From 2ad0cb942c6853bbfb6c319e78e299bcd5009b69 Mon Sep 17 00:00:00 2001 From: Quentin Roy Date: Fri, 15 Aug 2014 20:02:52 +0200 Subject: [PATCH 01/53] Fix FSM going to "*" state for events with both "from" and "to" WILDCARDed. --- state-machine.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state-machine.js b/state-machine.js index 859e5df..ac9ab0c 100644 --- a/state-machine.js +++ b/state-machine.js @@ -139,7 +139,7 @@ return function() { var from = this.current; - var to = map[from] || map[StateMachine.WILDCARD] || from; + var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from; var args = Array.prototype.slice.call(arguments); // turn arguments into pure array if (this.transition) From c761134b22dcf0dcf9117502b756d32b7be74b73 Mon Sep 17 00:00:00 2001 From: Quentin Roy Date: Mon, 26 Jan 2015 12:43:34 +0100 Subject: [PATCH 02/53] add tests --- test/test_advanced.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/test_advanced.js b/test/test_advanced.js index bf8ebd5..62cd9cb 100755 --- a/test/test_advanced.js +++ b/test/test_advanced.js @@ -278,3 +278,25 @@ test("callbacks are called when appropriate for prototype based state machine", +//----------------------------------------------------------------------------- + +test("double wildcard transition does not change current state", function() { + + var fsm = StateMachine.create({ + initial: 'green', + events: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: ['green', 'yellow'], to: 'red' }, + { name: 'noop', from: ['green', 'yellow'] }, // NOTE: 'to' not specified + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: ['yellow', 'red'], to: 'green' }, + { name: 'lightup', from: '*' }, // Note: "double wildcard" + { name: 'lightup', from: 'green', to: 'yellow' } + ]}); + + equal(fsm.current, 'green', "start with correct state"); + + fsm.lightup(); equal(fsm.current, 'yellow', "lightup event should switch green to yellow"); + fsm.lightup(); equal(fsm.current, 'yellow', "lightup event should have no effect effect in other state than green"); + +}); \ No newline at end of file From 63f202a84d2a5965a7ad1afdbd854be5f6449c4d Mon Sep 17 00:00:00 2001 From: mengzhx Date: Tue, 10 Feb 2015 16:00:32 +0800 Subject: [PATCH 03/53] Exclude files do not need to publish --- bower.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 116db62..5e2aa72 100644 --- a/bower.json +++ b/bower.json @@ -6,7 +6,7 @@ "Jake Gordon " ], "description": "a simple finite state machine library", - "main": "state-machine.js", + "main": ["state-machine.js", "state-machine.min.js"], "moduleType": [ "amd", "globals", @@ -23,6 +23,11 @@ "node_modules", "bower_components", "test", - "tests" + "tests", + "demo", + "minifier", + "index.html", + "Rakefile", + ".gitignore" ] } From a48dd9d7f0e42f30b8e2530979d265f59d5ba01c Mon Sep 17 00:00:00 2001 From: Benedikt Huss Date: Wed, 16 Nov 2016 17:17:39 +0100 Subject: [PATCH 04/53] transitions function now also returns wildcard transitions --- state-machine.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state-machine.js b/state-machine.js index aa05d14..3db1d8e 100755 --- a/state-machine.js +++ b/state-machine.js @@ -78,7 +78,7 @@ fsm.is = function(state) { return (state instanceof Array) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } fsm.cannot = function(event) { return !this.can(event); }; - fsm.transitions = function() { return transitions[this.current]; }; + fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD]); }; fsm.isFinished = function() { return this.is(terminal); }; fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17) From bcf39675f7fe424a444e9d0741f62e283e2810f7 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 17 Nov 2016 16:20:18 -0800 Subject: [PATCH 05/53] example should use $.slideUp (because its supposed to be hiding the element, not showing it) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8020ce1..7264a96 100644 --- a/README.md +++ b/README.md @@ -214,10 +214,10 @@ For example, using jQuery effects: }, onleavegame: function() { - $('#game').slideDown('slow', function() { + $('#game').slideUp('slow', function() { fsm.transition(); }; - return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in slideDown callback above) + return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in slideUp callback above) } } From c561d0fb42d7d093e7c62e924c59b9090749282b Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 17 Nov 2016 17:01:02 -0800 Subject: [PATCH 06/53] Prefer es5 Array.isArray(obj) rather than problematic (obj instanceof Array) Fixes Issue #88 "Multiple 'from' and 'to' states for a single event gives error in node cmd with jasmine" --- state-machine.js | 4 ++-- state-machine.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/state-machine.js b/state-machine.js index aa05d14..dd4b0ee 100755 --- a/state-machine.js +++ b/state-machine.js @@ -46,7 +46,7 @@ var transitions = {}; // track events allowed from a state { state: [ event ] } var add = function(e) { - var from = (e.from instanceof Array) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified + var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified map[e.name] = map[e.name] || {}; for (var n = 0 ; n < from.length ; n++) { transitions[from[n]] = transitions[from[n]] || []; @@ -75,7 +75,7 @@ } fsm.current = 'none'; - fsm.is = function(state) { return (state instanceof Array) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; + fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } fsm.cannot = function(event) { return !this.can(event); }; fsm.transitions = function() { return transitions[this.current]; }; diff --git a/state-machine.min.js b/state-machine.min.js index 717ca99..9b25a85 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.3.5",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=(o.from instanceof Array)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"2.3.5",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file From 90b98143dd83c27da58a1262389954c4dc60cca0 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 17 Nov 2016 18:11:15 -0800 Subject: [PATCH 07/53] start work on v3 --- LICENSE | 2 +- README.md | 2 +- RELEASE_NOTES.md | 17 +++++++++++++++++ bower.json | 1 - package.json | 2 +- state-machine.js | 2 +- state-machine.min.js | 2 +- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index 01f6314..701eca9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012, 2013, 2014, 2015, 2016, Jake Gordon and contributors +Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017, Jake Gordon and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 7264a96..dd15123 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Javascript Finite State Machine (v2.3.5) +Javascript Finite State Machine (v3.0.0) ======================================== This standalone javascript micro-framework provides a finite state machine for your pleasure. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7e9fd70..80f7f60 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,20 @@ +Version 3.0.0 (December 2016?) +------------------------------ + +I know, I know, I've neglected this library for far too long, so +lets get it back on track before the end of 2016 + + TODO: resolve outstanding github issues and pull requests + TODO: replace yui compressor with uglify + TODO: better npm integration + ADD: Promise based async transitions + ADD: conditional transitions + ADD: observable transitions + ADD: composable state machines + ADD: better introspection + ADD: undo/redo history + + Version 2.3.5 (January 20 2014) ------------------------------- diff --git a/bower.json b/bower.json index 116db62..a5d1b25 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,5 @@ { "name": "javascript-state-machine", - "version": "2.3.5", "homepage": "https://github.com/jakesgordon/javascript-state-machine", "authors": [ "Jake Gordon " diff --git a/package.json b/package.json index 2cdfbc7..c8ebbea 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,5 @@ "devDependencies": { "qunit": "~0.6.2" }, - "version": "2.3.5" + "version": "3.0.0" } diff --git a/state-machine.js b/state-machine.js index dd4b0ee..5e8b4ba 100755 --- a/state-machine.js +++ b/state-machine.js @@ -13,7 +13,7 @@ //--------------------------------------------------------------------------- - VERSION: "2.3.5", + VERSION: "3.0.0", //--------------------------------------------------------------------------- diff --git a/state-machine.min.js b/state-machine.min.js index 9b25a85..b34ee20 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.3.5",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"3.0.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file From 6904a2e466fdc83cc72a9c1a5309765fe8cd4a6b Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 17 Nov 2016 18:15:51 -0800 Subject: [PATCH 08/53] added npm install instructions --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dd15123..6578c14 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,14 @@ This standalone javascript micro-framework provides a finite state machine for y * You can find a [description here](http://codeincomplete.com/posts/2013/1/26/javascript_state_machine_v2_2_0/) * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) -This library has also been ported to: - - * [Go](https://github.com/looplab/fsm) by @maxpersson - * [Python](https://github.com/oxplot/fysom) by @oxplot - Download ======== -You can download [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), +Using npm: + + npm install --save javascript-state-machine + +Download [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), or the [minified version](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.min.js) Alternatively: @@ -33,7 +32,7 @@ Alternatively: Usage ===== -Include `state-machine.js` in your web application, or, for nodejs `require("javascript-state-machine.js")`. +Include `state-machine.js` in your web application, or, for npm `require("javascript-state-machine")`. In its simplest form, create a standalone state machine using: From d11801bcf5c105bd428ec785f8c57214a13712ad Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 09:02:15 -0800 Subject: [PATCH 09/53] lets do a small 2.4 point release before tackling the big things for 3.0 --- README.md | 2 +- RELEASE_NOTES.md | 30 ++++++++++++++++++------------ package.json | 2 +- state-machine.js | 2 +- state-machine.min.js | 2 +- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6578c14..cf65a54 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Javascript Finite State Machine (v3.0.0) +Javascript Finite State Machine (v2.4.0) ======================================== This standalone javascript micro-framework provides a finite state machine for your pleasure. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 80f7f60..c380576 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,19 +1,25 @@ -Version 3.0.0 (December 2016?) ------------------------------- -I know, I know, I've neglected this library for far too long, so -lets get it back on track before the end of 2016 + FUTURE Version 3.0.0 (ETA - Early 2017) + ------------------------------ + + I know, I know, I've neglected this library for far too long, so + lets get it back on track before the end of 2016 + + ADD: Promise based async transitions + ADD: conditional transitions + ADD: observable transitions + ADD: composable state machines + ADD: better introspection + ADD: undo/redo history + +Version 2.4.0 (ETA - December 2016) +-------------------- TODO: resolve outstanding github issues and pull requests TODO: replace yui compressor with uglify - TODO: better npm integration - ADD: Promise based async transitions - ADD: conditional transitions - ADD: observable transitions - ADD: composable state machines - ADD: better introspection - ADD: undo/redo history - + + * added npm install instructions to readme + * fix for javascript error when running in jasmine/node (issue #88) Version 2.3.5 (January 20 2014) ------------------------------- diff --git a/package.json b/package.json index c8ebbea..c9c50a1 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,5 @@ "devDependencies": { "qunit": "~0.6.2" }, - "version": "3.0.0" + "version": "2.4.0" } diff --git a/state-machine.js b/state-machine.js index 5e8b4ba..4f747fe 100755 --- a/state-machine.js +++ b/state-machine.js @@ -13,7 +13,7 @@ //--------------------------------------------------------------------------- - VERSION: "3.0.0", + VERSION: "2.4.0", //--------------------------------------------------------------------------- diff --git a/state-machine.min.js b/state-machine.min.js index b34ee20..8908902 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"3.0.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file From b9c3e232b5ecb0e4b18518382b8f3f4045ff7d35 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:01:48 -0800 Subject: [PATCH 10/53] provide npm scripts for running a dev server and running the tests --- package.json | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index c9c50a1..8144128 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,25 @@ { - "name": "javascript-state-machine", - "description": "A simple finite state machine library", - "homepage": "https://github.com/jakesgordon/javascript-state-machine", - "keywords": ["state machine", "server", "client"], - "author": "Jake Gordon ", - "repository": {"type": "git", "url": "git://github.com/jakesgordon/javascript-state-machine.git"}, - "main": "state-machine.js", + "name": "javascript-state-machine", + "description": "A simple finite state machine library", + "homepage": "https://github.com/jakesgordon/javascript-state-machine", + "keywords": [ + "state machine", + "server", + "client" + ], + "author": "Jake Gordon ", + "repository": { + "type": "git", + "url": "git://github.com/jakesgordon/javascript-state-machine.git" + }, + "main": "state-machine.js", "devDependencies": { - "qunit": "~0.6.2" + "local-web-server": "~1.2.6", + "qunit": "~0.9.1" }, - "version": "2.4.0" + "version": "2.4.0", + "scripts": { + "start": "ws --rewrite '/test -> /test/'", + "test": "node test/runner" + } } From aac26a55798f9b04272eeda49be4e7ca41cd8b96 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:38:50 -0800 Subject: [PATCH 11/53] updated release notes --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c380576..b24a8bb 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -20,6 +20,7 @@ Version 2.4.0 (ETA - December 2016) * added npm install instructions to readme * fix for javascript error when running in jasmine/node (issue #88) + * exclude build files from bower install (pull request #75) Version 2.3.5 (January 20 2014) ------------------------------- From a5ed2dced46dbb3cb8db0eb4215ea661f50b7b83 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:42:24 -0800 Subject: [PATCH 12/53] updated readme --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cf65a54..67e4619 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Using npm: npm install --save javascript-state-machine -Download [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), +Or download the source from [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), or the [minified version](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.min.js) Alternatively: @@ -27,7 +27,7 @@ Alternatively: * No 3rd party library is required * Demo can be found in /index.html * QUnit (browser) tests can be found in /test/index.html - * QUnit (headless) tests can be run with "node test/runner.js" (after installing node-qunit with "npm install") + * QUnit (headless) tests can be run with "npm run test" (after "npm install") Usage ===== @@ -360,7 +360,3 @@ If you have any ideas, feedback, requests or bug reports, you can reach me at [jake@codeincomplete.com](mailto:jake@codeincomplete.com), or via my website: [Code inComplete](http://codeincomplete.com/) - - - - From d77fff3fb324d254f8f9773f803194d95483de4b Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:50:39 -0800 Subject: [PATCH 13/53] fix tests broken by PR #97 --- state-machine.js | 2 +- state-machine.min.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/state-machine.js b/state-machine.js index 896cd78..85c6b35 100755 --- a/state-machine.js +++ b/state-machine.js @@ -78,7 +78,7 @@ fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } fsm.cannot = function(event) { return !this.can(event); }; - fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD]); }; + fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); }; fsm.isFinished = function() { return this.is(terminal); }; fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17) diff --git a/state-machine.min.js b/state-machine.min.js index 8908902..d3c56f3 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return k[this.current]};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file From 3a90274c7342c09df1e29d9d27908decc78192dc Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:55:44 -0800 Subject: [PATCH 14/53] add unit test for PR #97 --- test/test_basics.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_basics.js b/test/test_basics.js index 35ee7b3..08a008f 100644 --- a/test/test_basics.js +++ b/test/test_basics.js @@ -634,6 +634,11 @@ test("wildcard 'from' allows event from any state (github issue #11)", function( fsm.pause(); equal(fsm.current, 'paused', "pause event should transition from running to paused"); fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from paused to stopped"); + deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard event (stop) is included in available transitions") + fsm.prepare(); deepEqual(fsm.transitions(), ["start", "stop"], "ensure wildcard event (stop) is included in available transitions") + fsm.start(); deepEqual(fsm.transitions(), ["pause", "stop"], "ensure wildcard event (stop) is included in available transitions") + fsm.stop(); deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard event (stop) is included in available transitions") + }); //----------------------------------------------------------------------------- From c17eca7b9524de9ad94630906e11df680f506bfc Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 15:59:52 -0800 Subject: [PATCH 15/53] added issue #93 to RELEASE_NOTES --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b24a8bb..3beaef6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -21,6 +21,7 @@ Version 2.4.0 (ETA - December 2016) * added npm install instructions to readme * fix for javascript error when running in jasmine/node (issue #88) * exclude build files from bower install (pull request #75) + * ensure WILDCARD events are included in list of available transitions() (issue #93) Version 2.3.5 (January 20 2014) ------------------------------- From 3d71da4ebccb13f0887f30ce02f6ceb197887d5b Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 16:06:10 -0800 Subject: [PATCH 16/53] Fix issue #60 - can() with unexpected event (crashes) --- state-machine.js | 2 +- state-machine.min.js | 2 +- test/test_basics.js | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/state-machine.js b/state-machine.js index 85c6b35..59408c1 100755 --- a/state-machine.js +++ b/state-machine.js @@ -76,7 +76,7 @@ fsm.current = 'none'; fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; - fsm.can = function(event) { return !this.transition && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } + fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } fsm.cannot = function(event) { return !this.can(event); }; fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); }; fsm.isFinished = function() { return this.is(terminal); }; diff --git a/state-machine.min.js b/state-machine.min.js index d3c56f3..9aac8cb 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n]!==undefined)&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file diff --git a/test/test_basics.js b/test/test_basics.js index 08a008f..9f2e388 100644 --- a/test/test_basics.js +++ b/test/test_basics.js @@ -76,6 +76,9 @@ test("can & cannot", function() { ok(fsm.cannot('panic'), "should NOT be able to panic from red state") ok(fsm.can('calm'), "should be able to calm from red state") + equal(fsm.can('jibber'), false, "unknown event should not crash") + equal(fsm.cannot('jabber'), true, "unknown event should not crash") + }); //----------------------------------------------------------------------------- From 7ed79fcd24cf9c1527e23d63e58068047793719b Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 16:17:43 -0800 Subject: [PATCH 17/53] added issue #64 to release notes --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3beaef6..0edcf1f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -22,6 +22,7 @@ Version 2.4.0 (ETA - December 2016) * fix for javascript error when running in jasmine/node (issue #88) * exclude build files from bower install (pull request #75) * ensure WILDCARD events are included in list of available transitions() (issue #93) + * fix FSM getting stuck into "*" state when using double wildcard (issue #64) Version 2.3.5 (January 20 2014) ------------------------------- From 7d4c16c16ec26afc2c000b681796230246072c14 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Fri, 18 Nov 2016 17:29:40 -0800 Subject: [PATCH 18/53] added unit test to ensure issue #90 is fixed --- test/test_basics.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/test_basics.js b/test/test_basics.js index 9f2e388..a524d9e 100644 --- a/test/test_basics.js +++ b/test/test_basics.js @@ -119,14 +119,15 @@ test("transitions", function() { var fsm = StateMachine.create({ initial: 'green', events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' }, + { name: 'finish', from: 'green', to: 'done' }, ]}); equal(fsm.current, 'green', 'current state should be yellow'); - deepEqual(fsm.transitions(), ['warn'], 'current transition(s) should be yellow'); + deepEqual(fsm.transitions(), ['warn', 'finish'], 'current transition(s) should be yellow'); fsm.warn(); equal(fsm.current, 'yellow', 'current state should be yellow'); @@ -142,7 +143,12 @@ test("transitions", function() { fsm.clear(); equal(fsm.current, 'green', 'current state should be green'); - deepEqual(fsm.transitions(), ['warn'], 'current transion(s) should be warn'); + deepEqual(fsm.transitions(), ['warn', 'finish'], 'current transion(s) should be warn'); + + fsm.finish(); + equal(fsm.current, 'done', 'current state should be done'); + deepEqual(fsm.transitions(), [], 'current transition(s) should be empty'); + }); //----------------------------------------------------------------------------- From d4037581fa41f7f66ebc664ea1d2a13bf2da57ee Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 19 Nov 2016 13:36:09 -0800 Subject: [PATCH 19/53] added function (fsm.states) returning list of all available states to help automated testing (issue #54) --- RELEASE_NOTES.md | 1 + state-machine.js | 3 +++ state-machine.min.js | 2 +- test/test_basics.js | 18 ++++++++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0edcf1f..17a5281 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -23,6 +23,7 @@ Version 2.4.0 (ETA - December 2016) * exclude build files from bower install (pull request #75) * ensure WILDCARD events are included in list of available transitions() (issue #93) * fix FSM getting stuck into "*" state when using double wildcard (issue #64) + * function (fsm.states) returning list of all available states in the machine would help automated testing (issue #54) Version 2.3.5 (January 20 2014) ------------------------------- diff --git a/state-machine.js b/state-machine.js index e86b894..e917a2a 100755 --- a/state-machine.js +++ b/state-machine.js @@ -54,6 +54,8 @@ map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified } + if (e.to) + transitions[e.to] = transitions[e.to] || []; }; if (initial) { @@ -81,6 +83,7 @@ fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); }; fsm.isFinished = function() { return this.is(terminal); }; fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17) + fsm.states = function() { return Object.keys(transitions).sort() }; if (initial && !initial.defer) fsm[initial.event](); diff --git a/state-machine.min.js b/state-machine.min.js index 9aac8cb..1743263 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n]!==undefined)&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||c[a.WILDCARD]||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n]!==undefined)&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};e.states=function(){return Object.keys(k).sort()};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||(c[a.WILDCARD]!=a.WILDCARD?c[a.WILDCARD]:h)||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file diff --git a/test/test_basics.js b/test/test_basics.js index a524d9e..209479c 100644 --- a/test/test_basics.js +++ b/test/test_basics.js @@ -114,6 +114,24 @@ test("is", function() { //----------------------------------------------------------------------------- +test("states", function() { + + var fsm = StateMachine.create({ + initial: 'green', + events: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' }, + { name: 'finish', from: 'green', to: 'done' }, + ]}); + + deepEqual(fsm.states(), [ 'done', 'green', 'none', 'red', 'yellow' ]); + +}); + +//----------------------------------------------------------------------------- + test("transitions", function() { var fsm = StateMachine.create({ From 4d422c0880713ef662b256827f77eb9906eecfc4 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 11:13:15 -0800 Subject: [PATCH 20/53] updated readme to show that custom error handler can access the original exception (issue #62) --- README.md | 2 +- RELEASE_NOTES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 67e4619..50b045d 100644 --- a/README.md +++ b/README.md @@ -334,7 +334,7 @@ define a custom `error` handler: var fsm = StateMachine.create({ initial: 'green', - error: function(eventName, from, to, args, errorCode, errorMessage) { + error: function(eventName, from, to, args, errorCode, errorMessage, originalException) { return 'event ' + eventName + ' was naughty :- ' + errorMessage; }, events: [ diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 17a5281..1db9288 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -24,6 +24,7 @@ Version 2.4.0 (ETA - December 2016) * ensure WILDCARD events are included in list of available transitions() (issue #93) * fix FSM getting stuck into "*" state when using double wildcard (issue #64) * function (fsm.states) returning list of all available states in the machine would help automated testing (issue #54) + * state machine hides callback exceptions (issue #62) Version 2.3.5 (January 20 2014) ------------------------------- From 8e1c71b35cd3957919f22d6e72b25bdb8cf39fc5 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 12:05:32 -0800 Subject: [PATCH 21/53] replace YUI compressor with uglify-js for building minified version (dev only) --- RELEASE_NOTES.md | 3 +- Rakefile | 8 ----- bower.json | 2 -- minifier/LICENSE.TXT | 54 ------------------------------- minifier/minifier.rb | 34 ------------------- minifier/yuicompressor-2.4.6.jar | Bin 852834 -> 0 bytes package.json | 6 ++-- state-machine.min.js | 2 +- 8 files changed, 7 insertions(+), 102 deletions(-) delete mode 100644 Rakefile delete mode 100755 minifier/LICENSE.TXT delete mode 100644 minifier/minifier.rb delete mode 100755 minifier/yuicompressor-2.4.6.jar diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1db9288..0614fdf 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -11,12 +11,12 @@ ADD: composable state machines ADD: better introspection ADD: undo/redo history + ADD: use camel casing for callback methods (instead of all lower case) Version 2.4.0 (ETA - December 2016) -------------------- TODO: resolve outstanding github issues and pull requests - TODO: replace yui compressor with uglify * added npm install instructions to readme * fix for javascript error when running in jasmine/node (issue #88) @@ -25,6 +25,7 @@ Version 2.4.0 (ETA - December 2016) * fix FSM getting stuck into "*" state when using double wildcard (issue #64) * function (fsm.states) returning list of all available states in the machine would help automated testing (issue #54) * state machine hides callback exceptions (issue #62) + * replaced (dev dependency) YUI compressor with uglify-js for building minified version Version 2.3.5 (January 20 2014) ------------------------------- diff --git a/Rakefile b/Rakefile deleted file mode 100644 index beb8702..0000000 --- a/Rakefile +++ /dev/null @@ -1,8 +0,0 @@ - -desc "create minified version of state-machine.js" -task :minify do - require File.expand_path(File.join(File.dirname(__FILE__), 'minifier/minifier')) - Minifier.enabled = true - Minifier.minify('state-machine.js') -end - diff --git a/bower.json b/bower.json index 5b1e597..cb28032 100644 --- a/bower.json +++ b/bower.json @@ -24,9 +24,7 @@ "test", "tests", "demo", - "minifier", "index.html", - "Rakefile", ".gitignore" ] } diff --git a/minifier/LICENSE.TXT b/minifier/LICENSE.TXT deleted file mode 100755 index b12bbbf..0000000 --- a/minifier/LICENSE.TXT +++ /dev/null @@ -1,54 +0,0 @@ -YUI Compressor Copyright License Agreement (BSD License) - -Copyright (c) 2010, Yahoo! Inc. -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Yahoo! Inc. nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Yahoo! Inc. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software also requires access to software from the following sources: - -The Jarg Library v 1.0 ( http://jargs.sourceforge.net/ ) is available -under a BSD License – Copyright (c) 2001-2003 Steve Purcell, -Copyright (c) 2002 Vidar Holen, Copyright (c) 2002 Michal Ceresna and -Copyright (c) 2005 Ewan Mellor. - -The Rhino Library ( http://www.mozilla.org/rhino/ ) is dually available -under an MPL 1.1/GPL 2.0 license, with portions subject to a BSD license. - -Additionally, this software contains modified versions of the following -component files from the Rhino Library: - -[org/mozilla/javascript/Decompiler.java] -[org/mozilla/javascript/Parser.java] -[org/mozilla/javascript/Token.java] -[org/mozilla/javascript/TokenStream.java] - -The modified versions of these files are distributed under the MPL v 1.1 -( http://www.mozilla.org/MPL/MPL-1.1.html ) diff --git a/minifier/minifier.rb b/minifier/minifier.rb deleted file mode 100644 index 001cf35..0000000 --- a/minifier/minifier.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Minifier - - class << self - attr_accessor :enabled - attr_accessor :extensions - end - - self.extensions = ['.js', '.css'] - - def self.available? - @available ||= !`which java`.empty? # warning: linux only way of checking if java is available - end - - def self.enabled?(name = nil) - enabled && available? && (name.nil? || extensions.include?(File.extname(name))) - end - - def self.minified_name(name) - if enabled?(name) - ext = File.extname(name) - name.sub(ext, ".min#{ext}") - else - name - end - end - - def self.minify(name) - if name && enabled?(name) && File.exists?(name) - minified_name = minified_name(name) - `java -jar "#{File.dirname(__FILE__)}/yuicompressor-2.4.6.jar" "#{name}" -o "#{minified_name}"` - end - end - -end diff --git a/minifier/yuicompressor-2.4.6.jar b/minifier/yuicompressor-2.4.6.jar deleted file mode 100755 index 61f6318668e1bd1cda395c4f010a549c5062dc13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 852834 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%0A?q8SvY1EP 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 z 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 z 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
@%=9L2;!MlN4&Ih{P8eM9|*%DY~nL~$-g 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


F}L`yuDr&jBAO=J z_w>!c5D#orOv%#AO>?6X;WCX4xSm-$15{LE&89I{#-Oofe!lwMe5AeLTC264O->G* z^+Fj%JfWQmx~)n|K$W!MljGUHFGTx5PYZ3#BXYtMftla`@^)YIU2nDozd!$S0!_b= zMg5IRCk;cG$3vC3L~_Q%oQ`I31HVT=F+W2nqKqO^fS8Z%19}VH@|Ll~(F$JVBF$+L z&I9y_c=W+x4v)r)7Lh>R^$UO zPo0zR`u&?d+znKMhn6u^tmEI=NSAY?G}*%ahbri0q_eZQxxGstmJ${d(%8nCafYc< z7^WiGrrJ$vY@2CbnKM>r8)02DUHYR|Rl6=RYJKC%>pr)nOZI0*Ou{l#V{A>`GunT; zB1eJ!A9s7Qg0t+oFsVIPB>5F0qpyg&?elR_Rvgv5x^D!nfaWTp+-CZ2Z%OH>34Jzqn6K6v3<)h43 zDBz|ySTT!`%{#--lyEqx2JOeL|~CdWegEUK6+ zetA-!*gB<$91Ckjl%8GQHPW92H>OPAn0-!Ht$4ZA8%AmfJiJ8Y{9!n`JtP;G!E>1| zQfM9-e0RPJ5i$nBaX4(lo7~6JCo?R(k?pHvOs-E?vEYWQYkG+>Q&70I_2&-OW@E%- z+M6E=L^B+|;u!Ua{egEtT$;7OodJF%l&fQ0U{YHlS==Wr< zTux@r{Q&&VhFyDGD`Hi|>;j2?F)+k_H!JT(V;U}3h0pa0nL!^IcC zNGL^Pao-a4nT#w;;W>G)jN(JL9F|-wPuW+Z5H z>-PQXYG(5fhNJPk_V&)A3`sEF!T;v#l5?H7)%C;~@b&NN{&`52l0Fq-_KKo`eqWT1 zqfp{wr)2__jb(+qR06}#*d~%Ayze@L<&SbPBqr075KTY|B9n= zV*5a2=iiZ_641I9aV^UpSDJN?utz|BrEs{bqfYjXeaUQe+(T)sUaP9!E{W)u7@G6Fx6YQc?DAswq%&W1lOK0%i; zulL<^4NBt9%kN~k?Jn@EAfRVx)jON}1-ts-sc2vYjcyeUWVsFPyA|=P`DMTGZ+*qj zwb*le_j%m^oSOYd`wJ}Jqjvt&4aWcWwg0bOo0q+brL%**mA9GmfBgeumE{yrg|Phg zZv7-Hi3%j66-O*jrh6TWLSQE<7eGTo9JA_@S!SC=%5;LiAify?vC6p$0<#680CR#+ zksR)b_kVcjS?}lav!i8zn9ZZ0l&}Q@CZXyflm=8oE}_(fJE~Yx>yh_*>ur{!;-4#} zRgl|9Ef%F>c;=4r&qY~NTRZuJ`s)Owh8*?GoV$HiQq0$1p^DvdBU}}*%$`1r@(HUD z4(${Gj9Si?u4VG2mB=t%n-o2lA}}JXI?``jDsNqL&R$9DAA;8=Ck6J`PBcyGJC)`dDx?zk25KYY*@DFTbUE+Up z^#f3!cVD7yqwBf`%lVBHiXXbEQvfT4A+H!QLh5IHYuE}BHx}uy8bQ_XgaE(dhK3H+ z*ZD(8D#-PHb>X&C0A{fhFnV5H!POW3JyO4qVRZMlt{vB%*&NnOpbthdmWezrp9Oke zw7#RN<06;-(D~mG5&HfAp#bE3HEc%e_!*OhJXP4+N7BF9&S-X0&3LRAs*%T0dm;Eb zHeH3QI`v?|3mv+xbz@f;s^_hQ@!B@6FJ?7!QZB)+K&~$W^3@)^M})HV$PegY46fOWgLFJEyU*r}tMx@n ze@3}of+-#$?hWG-+byhIXEGOdh|9pJ3u7W=v_bKZL||EJl1okMNH3AiyvR5IHIb3l z<-&X1%F@ua9ETld?X5k|V&v-MSz&YOY=wP~ptGw&a}PncNf1k-KO1L>W{FmgXEftH z^HWK(@lv=i0>9LvVY*eeQ7WO%XHGz3Acj4qh32L#FUEhm;s--jUWD{(@^Q&3Ibqa0 zL&&hb>SY4DSe{luT|-gudfY|H>yn=qTP>4dMl2-;X6*1mR+V;cG*%+B!#9U>kE)8~ zJl>+n*m=;CqKf+c-=j8zshw*m^?|#q*_zjLtvQ#vS@yY`;;=qDd0aU~AtGz({Ua1Q z$8QHuO4W_JtmR_W*%Fvf>J_nTEOo9_x7vj@4QeCf2P&UF9&fy+fVKxw6YT}+}@ z9`06Moj|cACf{B8qSP11zkb?*81H^CzA{_P`Is&5^dh~vWd#6sYbxmFdC8;MbC9fs z@G8Lh3hPwd%@_P21G;kUTG|^RM>tP^Nu#^);40OZB`xkTHb2g%8|_5N{0kxl0HWv=DWTwcUI@;1$_1J=W3l;DZBEmDnt-l%Nn3f{)yUkU8GCnh8kO!HJCS8G(p( z8T*bF?gWOE+&QI&j*!+!g25?F;zI`_d_DyN0)~DZwj8$nLtL72n*I_|;KSjkNF*ryR9%T$)*3|EDs z&~b!+NNN%A4(lz?<$xz?n7?#e&7@E$^ z7_PxoAELorAGXd^ABvlqePDj(2Jk+E2Z*0xc%nX;d%`}cd*VL1dqO_RdtyG>dm=vR zdlEkRy#YN5y&*M2Q)bX}P0}5rxzO&6*$&^%;5Q8Cgz1?h&M|om@w)(p&uDRt?|^%- z{uv0*oDZEh;V0}1;6^l<&<*g({5&9?5qqO@5%7)a1S7QI2S#K<91@us21uPnA0VHp zIA(gG@z44)`$9jJ0dJx2EhGEnOFPO znFgT!Y42`;YsxqH8HbSlkuUQ%`Wc7N{jo2wFS4iYLl35YR6oq8?!)qo{ILDuFSsxL zvp<9P7Je9ifu0}_5t;q5{z5%T9L6*IzGF!0!wcAao|uFqsoTe?~@^sj?vw#4r0`L%JM9 zx*;mA_M{T#smyLQ?$9dD5smP*b_p?rY!&>s<{ZZ1Xc9J$gMyFw@Z@}+C$o?ELLoV~ zD)qTG6Y_g~7U*T>6ORqWAI?N2w0Y*Kn4 zkP!%300?NvGO#epfTNfa5((#2f~+A?CiEoO&@Hql5f-@A$Sjq$EL0>i3>(7}Dg$N&v! zH9Q=yrpbXaXgap0&4Dwh23E(?fEq*{hhuD@4SdhUKs0>M$bbxd&&}vCF zARFKS!4Y*B!PS!O)*}XYj})&1-!nU~4R6Z=K!E&LsGGftyiI|Qoxr4HNP29Dr z(?z{Sa?$}D4Y{btf`-ruu2?DN9OV%P=>=HYTUBLqY=9(BpdoxK-U`i2`n&a%6q8hw z(j8`!DmY#f#>e!iF!NP?EgZBOYR0s0lMZTuB1B+E4TUBOLP*fshhU~2WUZCZ4-2eO zLs`#`u;wY^x+*w*hqo4yZqq`R5q?idmG#Z+@HFjrAq(uPa^a@2rxlf=^G@^ zD@su)hEU(Tt7l(Q!|3IgV#UrqtakDlBjUD&>QVH)4oQ8?4c#BLe<0Te5{y3OpRX)% z*pt=-NL5yWw(@-0;MVB=G}ZnUeH{#_kEvQe=rqRm&uNjqhE``GDp|-}I)tjCrX2&J zKV@4(3U*#Q&a&D~NpH|#BWljt0sU1o8pg{?1SnmU>X5$=2b6WjQu~rd`@kE;)eI{Y znC??z6*mk}UemRsX(EdSBgIT!ggd)a&$5@WM1b(r^LDq1cg^(x$ZwR;ter#jp8 z%EU}FJ9){2E+Melv~Be|Rs^Y)kf>nas%?`afwk}I86MO=%AuL9)c#s~p(~G|KP+a( zrv`__JV!)4ualTkA{pKOVo+5(gpIGIf6#!rrOZlse{5Prr!2l}M+-wE8;ex#QngKQ zDG5W^XIZZCF7SjadZIxL#Xy~^ED3}a+xHELD`&FLwAiZBEBN>_EC{*D604rgB9)Kp zkPN(9JWYlD-NK4ps?}s7YbZoSC&g=XwIW?9K>aUD*%;xR@IsYK@?G4TB3n_cZEHwa zNdSeRjVV^!qziVK;WRe_mT#B@GzMN(HN1k48j^semwZN`V(Xg66}z;7UHRw;Rfv_P zq@<5kRgnObLdF9#9>YLjhsu=}f`jp=YQ;cVpKiB<;)62zZ%gd;d`Fd{*i3orLuwia zt~Eg&(JMe#*v?C9(nmRz2^OO!p1b5+%qI56svh!;&!HYl8n3NtkdIB2DCnv#DU8Y zXht}Yd_}mO{00IivFqo(Q@G~ZFmx=E)6lGAG^%}Qt$YXkRn7t#!Jolz`40RmSKs-_ z`(sG?w_iJ#A>9WQl%k^{zbrYwC|M|P&}M@H8L06`{Uc@xW$KM^xyD*lqs|~vW&`Nc zrqyk$YIg0VTjF}Hxv|#S#;Y9FRd(WP+p3jqcFK0FC0k{B(VN2bXZtM~=ZnVX($QKv z^yX`=8LP|2>Ppe?RP<-itr;3i#}w-Ezf}3`A79MZQQP~xn~N>oRm7VeII?nM7jHCU z&66`z3_p@lZasrq-N-)BB#Ka-C~zDo{UQjt3xVxjjq8vOF;Mu;O*AOKVnZVJZwimc z<-fpwZbt@7DBlRbQi{r=uE4niiLjdmt>Vli+`eWa^N*RA?721d?+gxT=aJ)5v7R-! zA7BGbkZ9z;Q2Li1Y$*MLAvT$rb8qVVtt_TxgNOuu1D?xKFZH&6bq4BqC^N1 z<_;YD8d<0`(97miQM-OEaLAJSeg3;G8nXuO1Ci6-y51#IR~F zAEwY(eI@aivCKy5HPB{Giv}(^Vw;JXVrATg;D#`F>THDgjK1_qP(_5Rf`3BYeLy2; z8M9-%QA5GN(B@r5W+l>rQCPfCQ(-qAr=g_5Q z`rD78$R0>}3!lw0+N+fdXnC{&0=fXX7HbJ|SI)`-%%O8MiiZkpGuoYYDeQ&w#lvYT zbZD>trmdM37=@j!y>KVn9Dgvz>Of{G!eze2=#NoKH3~IX%G7zRtO}*ddZVI5C0E`V zS&5D0q-Dm{)gm)`Rz;1nVzA}+Jeqde;4gK_Gt;UX2TP%Pf9P(hZS&BHK9%Gkm!JG| zq*oxT$~V$?<}AcDIG2eZPnVW1`>G0_XZUmq``zN${uwL?a`v)-x}qZ99cauF{$l7_q2SzLHHcXlQi`Ct^lex->Vo3R7<-H_)c6`=qDxCM&w7 z$p7*}&7gHXoDYk05!_IzYK#N2>dHxos%;P`+1H`A*9Sr=DQ()kaiTq%uTKlOL%dOQUad(2?yctjxss=3DJw zF(dI&Q}z=OiHikbl{Z5*8KT-k1RyLx*M;&3cEoAJ)s+kPA&n4f32tgQte?=E$swoJ zOsY&}2~$<+kwhik;=BLUq9CF&r`9;MUsH7V4Ufqo?pwbr zhl;(Tqd^>CI5Ok}G7kcwd8v800e|k;us_IS>$os-qjY`5w=p)4V!(2Dd?WnxsoL(s#7Coaek zQ+BR75$r;gzlJ_wiv>--(v3A2B25*djiU#DY{+PYXY2(1Y1p5#isOYtMeLL(D|{5v z88Wg-3&sb9s6`1bQi;*r5xt8`sgX=|HbuXsGyFi$#Y=}i8UPB2h&9EUMW$8muplhq z460)b94e*<%%;EPtjT(+M(q-Vn8QZ9P|p&87dWsFdzn-1*HAOj_C{^4R%fZ{&(;90 z&PeKwULPnjSM|fO0d36Fz49&%oSQdCa?CzHDsJ^w5WQAq1FEGmEtJ<8fubM^$`pxP*ClhdEN%MK6BFxi0$=wM zFG**cph_%GT&%MKBi5o3sOqJrO9Kz2Kr3CX*%IVH3nRi_1+7HC1LLwF;Hu9Vs2?aR zq1b7QSu&&prc7ysXwX%MRO?EbQlwSH`)Cx^#8$fLnk+%tg+Zoml<(Uihml`!e3-D5 z7)z522I*f9nj*SJ2%aTYSWxKU*S3PENv#|CB!8hTaxWd+obiQk1@}d4rIRTHgUeZS zMq?Z4IcBej1ekFM$lUae*WfJQ@HCokxy`GOiDH|srz>t=TqWobVJk=Y(^FvhgEiUG zRFh7%I?<%MnM=;>in~;iNXN+GG=y3+#85ra`yL96a&G165GeJy%30olWvL)5d2hN{ zlSrSx1=2FW8X#(nV^tnZH3S=UfR z#yB@{|Ag)SJGsg|W~8Hm2{H`ArmF|7D@^pcn<{2V2u#raEcU2}5~!--ZXd{m$o5>; zV|+ud!HJ9eD}^bO!62&I$M%H5i|j^SBVJRX_qqkkGxpjQ1QG_Itf2s61FpF}VqIf` zI^{jYAAOpZH|1VaBOQ>f9TVx?uSaNUc0)~5zXkYIW-qv2QMVTQUwf%jVw@3)XG0OYC?jgQoX54DmKFR-yr zsWEQ{OhA$NEG{nAR11M<*p1=^4w;X-ZfJvOo{9?&pJf7a7s5QuRm=ouV%YO(=?O>h zbn&@|jjNI3Zg!Ik1|1kfiL4>xL>WQq1UzXHwV5=Pfb+TYBfviT@sCTM8{ z;Zz6#xm<8}V^0SJx?q2fN*x9G;SdkD8({qdc5CQwj6e+;e?h)BPB!H8!67!00+4)= z3C#D0fcJn2PW29n7(>S2Ks2$lj#0!3}Ku-o&dzj<=-W)O8^DtuzMyYze&y`C$01>;>ev6a$*w;rtf;LJV3B z4mfiM@4bJ$i3s4!UkoF?C`~+5PrN9rz93zFK-d;L2$x4dY?7CNkGIwWxF*Yi!mW}I zp_2|Ik-?RBhq)62BUF|-hmC@;$S!dYp@i^~UT7!sA`3X=`g6#%B-+{Z`mz2M zVFttfX6KbjK*)VL1>gxmm|nA!-SRALEkBb3K!gx3YBdI;!CC|Tyn*ydCZIvx1gu2y ztzNOa5cP?vz{9RxCY{%WXihGh57>ibu}T$4Yb!}_35yj1IiZ{f!M=4plMC9IlmuY+ zNGkAU*TxggR~O-_*XBb!psW#DpFup+{}s_o%!m3TtstLW>M!;2bcvOI5H-!arDV~s zxEz26?I_my9OQ$U36tmED+Te0Xx@wetwZP1S42v&^4h+yzR<*nz35_fYs>Tm#o1*99 zxSM(ATlvi3ligePM3knR%_R{TRASPvMErRrOb7Z6E-7-?)O{UVu zi4r3&}(=$+pMO3__OX+R?~TJkszPy}5}+Lx8bDi?UBmZ8Qv&zg3Q z&EgdH5}o%z1a`)fm0pg}NYT;fCRLZw!ZVQtLrG$?t%}sU&gyPLfk}WD=`pz>qH&IF z*FCXP#pRw6Yho@u2Q!&)IzG8N1+d~4)Nap28nPeeiQRg`O^`C->yO$YL<}Hh?`?@o zI%l(9pvf&)Pslqt8bfo*2EPT6#d8N#$Z5zX@9=oI@D$@SX*C(rb3KG|5A=dQ?w$eg znNlclkT32y!gt|v$t#rr*Am-3?!MzxXunO&>44?R>LoFi)=$;-UWIM zzffGHWRo$^q+_wL<<;E;CmnW`7x&?gW${U+c2EB6C_Ko>&PegLxJ+Auf|Odu9YnI; zU)z!+qHR?btx(EkU!MvU(_exZ@qwkK$Tt}edb;geshhsxv0PVk$8WpF>DISiCo!jg z$Z!GsR7NDOhUU>>QQ)cEmqc5ll2K4t?9f+gpCA&%mX5cj6)^s;b*}+fOmckL4tAtU z^UW6e2J}k++^hVHvL2ycM<=iURvpl*t}SOZSF{u_N#2hA{QmwC8>GGUCQY6H`*TPC zXIJ)AjAnfiyU!#Kmz`2S_g$SL&+=6=Gu&M(372~_lm5vV9H8GrtmDt=JQBE z$h%9Cd3VTrbFuk$h`II(8)_D&_$#YE<<$ITul z1Yu9~(;**SAmSq8cmrJD2+&v5DF6~eX_&?~*hqF5$2Oj}fwgYLz5~YR*!m{g#*s@u z#;XHi{5X{hzkW!o13LYnwFB+i^7X|N*?w@^iS}hjaDk%-`uaiLcA(qw*IqdCPB`bW zi6<<<82%f`UflhG{1@k5Z2xgD+=E})At)XApC-1QdEPgo>u|)zLC*mAVF^us{;9D8 z6I&Mkxw&!54LaYX)I;JnEW~DM-zfUw@=dWfxNfj~i|Yq)clN%Cx?znC4&T&o_I{08rf&Y6n8A^Fw(O#R<6kgO>TD{9-uv@x0% zce)ZcLnHd=Rm9wn6&CxAdHz;-t-MX|U*DXNX z1*y%k+VI`tI>Q`R*PG_I((2`QraCRPw$1pIdLdzLj6A{J?!=>P;N3bvC*` zI9>z&SU=1CXg|~UM)()+P4ll18|I(+Zd|^V+-3c9epeD2kH27Uw13##{QBm5?fr}V zDfJWdUE@FOx7csef8F1J`f-m3KbBeOxGH&;B}=(i{``X11cI<3y=Fww(pX4Kgu6X) z;)8#pl%xR7?GAxRG2PedN~vO*Cw!@he5$f7X!dDUD|JiOrQxzjp5&DV5l(%+DP8Oz ze7F&JW@U@%TCRE~zOYFNfNsNldh@fiFw}oiJut-er5eN1 zc#Mz2)OnQAbeutBD@)3gY2zX2PRUx0y!0zm3T?)NB^M3VgJoOPxZ_u;P)TB2afoH* zWy}{es@8}oN2%*BY8!!(!!1(3bz?h$nZs^gTOaxoUCmjgCcQW>^v2fq22gjhP9ipq zvMcR=A3=I!_jV2@aQU+f8X{%)Y+URbrlvlT?$?a(VV~O+#r#}K;ctpg-*ie=j4j4( z(AIeKsEIwaT$YqMhoINYvwvBN6cA}}*4a)HXoiGiIm!?fx}uRmT_U}56_Aym*m1ZK zZ;+;Q(0DE6>&gVad7aHYXJq1tU5$ucKE%P8%oSBCjZIkE(e+DBg)R~f84YQ(pQ&<6@NN380*SI~ zy&^+1iuJ6)h;L=N;GJ%UWUwCF&_|lZTnwa#fMg6;)d#-h&1evzv}jV5t1a+CKDUXIE%V1g0VdWQ9mN1s0m4X}lMGJ|h;nWygP z0k+mjXsQGLqI8Q?35%;WQPh@fQxKl#-AsOl=HC{>+lo6(MNcHhIrKbg}gIM zI12eL^p!XbBQOm2mkzvozR~^5Yb~>Xrt3k2is^SM{6T%A&=);NQ2)62 z!=FvfzrerJ{U^#E<2T^`GIuBZWT!sEwTIJSlT z2ar1!Xv%(5xZ(KA`uXc8b$8Zgg8+O}1jYmseJ)Qu<&Dt-&-IL@04eMQ&1HC`Ueaz^ zoZib0LdHL35~ncORUp&eSxkE6QJIq8Myv+WE&cR99uaR%~HV;lN`Q_mf@nb zB{Wd_my|Y!U8!)GUC-z|k8#;=rdK=UAEpOdjqHi>z{&S!<1-|flBLP+O$lu(kgiJuRHWY0_49#>-iE)+to5ebfmMfe_R53IuH0N+y17`2Zf zEop&_l9K_rQva_vH5k#G<8ZB7JpZ|$fz2H(3zr`UZd~acc+$BrREy4$O{gQfc&=&6 zIhcs%#F0&`BU@f4jzBJ2lDWB$eC}()^P7fRP1cm24(n6xD)L%~dkhY}x1yS9r0fAN z>^w(KGRytM{NepY335@a}k5b;_p;!Cdo{23##VG`bx!$nPBKB#5tw2 zVYX7Txkn z*oB0XL9~LzR8>d@IlVi>(GRk%=r(lXo7z58Bfo%3fj1e+{u6C{1uUWZeCovK!_4mn z{V!>ykPPXv?mJ(FG61>QtWcSm00Tv$0SNU}>4H*cOh#W$hCU)_3j7EFJqZKxb{$z3 z4}?={7YC!AaM<=tt%=M+Qj6um0qr41wDpTusi82BZij&htRm$sBK>pio=S}Hy%W9} z%n5fVIcw4dnj_VwAh-#7XUbf;&IZ-5c!N=1R2D?`3o)pcivJU*rIjJjPEAaGKxZUo z3Ik_LI;cOer6aGUgSf7+g||;i2hZFk%h>8x%9wy4UW;-A=PKs@RQopQ?Ne5X<&Bq>=mR=@3spexgu^E5d?n2q+h}xQh z6*v#_FxSYEX=4%#hqT16$$JJV`^Kj7aXA$^NW1*YJxGnU;5FAH+n~BC%>C1v#t@O@ zP9(FWE@#Nf3;Bzx9XXFj0v5JENx;2?W3=6dFvxr=o1mDAVeATCNNH4%1?pa4Yqar0 z;-^Hm>IC8RQ>Y6SywLs{aRYo)Du9GXHayk5z~QMUK+hvcPe~7$0}bP_K#Ilz=;=!b zPE4V()dosM%>HX}?anK5hDG(@dmE1F1Ri@lT&hYQkkd!2YSgFp#fZ;>x>x?jCy@{( zi*4?LB%;n$NaXv&{D#WS?AG>>Ys%KpQizm8dte3nPil z%b~P((apL3t)UZ!l5`qSfuIMY_tL@(kgyKVh_+7G=xgx!5aJ9NwTn$ zmfZXb+HA@a?WJ)cMVOI)cPJ*>#zT$G5vVVG9}&WBo2{p`mTE|_3z%vW8q*B>V-V0% z<|X6f7S(=&5WZw46#K$#PjQ#Zk4t3shmfq#X#|qwzd_Ea`;&0L;Tec%4>h2(r;IYI zhGEnKQ>!3sR3UZicn+=EvFlV+46B_%+Nv46YEUn5diYU6$_n@OGOrgm|g*S z{!8n%VF3Y={qNp3H7k2pIU~pa>)6-uaa3K!|2ucr>*K)*8!|vnu_+cqVgw3Z#1PRC zMSLJF$u@{Yutql-N=MP{hiPCkFD zGR}X+y^M9?KF7y}6GS@9<=*Ri?$2l6{=LVYpXX6*JJ8C}DbZ9TdjyFstnn`hkefY< z?CsML{Ks4Q%^mXW?$ZrEh&%Wr{x8M2o%?@i+@EXbH{i`LNe)Da2PA^DS<)siRgQS@ z2QK%Ce+K@%gjohq1sqT50xkPG6Q>2RZjYS|2&{ z()ZjrKenut=TH8^g7pT@FH5I;$zPO)bQKO22HO3C?g~(roSNUg#N`c;~Jr_NSP8v*Om&1mx>nvHZT|jh}OMeSRsckuN8d-lWj(QnuMx z{nb?yhYMvKnobr(IU`r9^4<~9Zf#AASU>Hm4Pt_$Y*pP@Z_%2nm!-Qqo0t?P3yCkc zr1zRDM8BU(((!NqeY3TdH&dqS;nAdiG~;Hf()+$;qjLF`WXhOmtp;u77sDG9vP$lg zj9=+1AmPom!s;wqA}K|qvA;~~6Ve*A?NTY1c9nqUpuu9Ha}twY2Me~Q?UjuVoQ!Hg zMw@!q!m(shCnstBTqP>J1?#45lk|JHO%tS;+n}F0b-H}XW|hY)iMOpiJ{MXoayeFJ z{rTnfHHkHkKK_Wrp|3ohfCEKr?P{{7y@X^}JqZVg*S%3$zdDPib-mV=pY~m{dX<}m zOwVi5SA@bv#K1vjuZWpYj@I`t`=+Txo{=Oh-z1*cnoHY7AiFD{kx%{UN}VFj?7}Rk zHZF$D-yj?1P2D{$<&@S5$MuFWHCnPqpa%+SHE(+Crlrol8Zl>Ws;m|AIzV*q87vq>DRGqWE>`)BL^VzI4=XiX;dHjH5 z&3lY-ZAWuCBaegS_f7G5KxXY5Js!ajo72_lHDbQI%S))im7N_Sxun4(8_uci1lCusFl^ks10#?|os4>8 zS2tZ+Qm#y_72rMYNw_`{AL9}pi(2ReSH@$U$N9w;DzBDOLf=E$ibV^_og=HxE;d(k@`bp0cew!_cGK_5lskAU4>6&B7J} z9H(JK$Sr(W-3>VP4^)s-<glni zW86$cK)dXptSuWTvFT?K)0Gv3L4yU}9aTU<7(3#I9O5g|w7z#kybu5`@!kU6D~+3T zV#6wvVA%VkHMX^diJbVCihgCd z2G5AODzIzJDgxIOnQt=Cp7GL8%EJSOQP1$_iQXQX0O^8FET`MN zeM*M+L*y=17XJY^HpfdDaBSa~m3LuGZamPo0W$@^@$DBoAD29$pU9SgdC6DWMLg=| z{SH>u!41pNB6C{PjGM7#Td+FioZ&RmnwEMN9ml#>UR$m8|%*vKPLaYMTr@yJ8FAs^vux9C<*}Ho#>Y$NZxKGFM z2%;*O&k1Dt?=C6}gO6SEcO8~ntS#DqDWFl((PYyISNk}tWjqAh*8vM_k*FD&Tc9N# zlfH<{5GM5X?8*SzXF7j9I%@?TITaE#}K|-;A zQmcRBB%{}_-=mW6oKG*fkKcs)EI+5Cj{>JJGB&4i^$e9c;r>$Tl(`tD(%MnwtWKiZ)_U5{5tWF`!uKW+ zUJtGR67jH=Z&~v&YIx#Sx3Z+&vH&?st$lgw!%zk`Fz6vPe$kLX>Y;d8F`#BqsHag& zGErunQO%Y}lp2ggf zHmiQt9!M$8dctW;-Y#`YDHVHK#CL(ZUCXMugSn=(Q>h21yEUz}+$Pp*;q>eMosf5) zAHz^y321t0gv1u()v&su*UBvVHtWSEq}>^@<7?+5e)L5fcBx1Ve~uKBjs zk1V)WTrf8u{l1d9fC`O3#~Tnq?so?Sil*7DEjOlt>=LXTH z2%g#`c3TdhU59g)ZUdu6c%nvyq~oLSVmpv1(FbTcpwXg7Ib^8!p;`-9nfEz5&?FY3 zSq(B83uBS!#nKp(fD0qLMJ%?cIq&$^g1?Gj=ps^lAnS$o7h>5(F>j#&yoo(i7CMR9 zd+~^tDWJ484%Sk7#xCLHeMwKZmW9lH#j-vZl9 z7DU)fk#&!(L(4pqdswm)mcT0!iUzt=-SW3TOl$ot1}@}4+fn8#iNY9SA8E8o=`h$< zMzx5F0t%-MrRiTyuU~$$`h+p?)&-qyTFBYS-&* zl(Bau@-E$!>E#$Q3}N-j{%{0;k1?K*(p6<#H7j3t=`nEy;`k^=RNg23Fin(b$SwLV z#(M2T^n!z)r{czAA5SfdY3k5TsfbMxGj7Tb_+n1nfPl$>&(~>QGTi3-T zFk6r&`#1E1_n-gjkg`TadmHj~#$WeK{^{#j6p)>x8J&%tr-ik(0iC6RtAUe|qlLXQ zor0G5Ld(RTy6Ml)ERTnS{aq;k5DOHjXcxlR8)8!FNTV-t zGKRsKGZ;C?GD>be%I3Pp-kv5vo7C7n$R)VSCA09}>C52-&*#fTd}5m&OsMs9vY!3; z?qzMG78jc9ub~-*adGF-1Rgk820CKqQeW8>EX=_N8`{89q2MB;=Z9%Szc zn9|Xq>|^`NNI6}1ijBev3evx|^ksO~#L6U))I$T%j47o2;0o|SPyyf!r~p(#kbU^t z^`3jSrHy)YWg$8eU$_vS&u9HKSXyMGZzPtJBfG5r#1xcHLn z`HwHs!okHv*}&}YFH+g+OMep6SJt+j8m6Q`Udu}$pLs^oy0H=c2MH*19pY#R1&)|@ zA9C92`OqZo{+-_w3bxssa8+vT#0s6Sg_BpC62}$I)d9z}SK{*L+YOmN zHRX3v`x=D)C*jCf#R&<9njIxLgzJn@RNTsRc?X%nA*rYQ|+>*LJyj)r+=c~0tfB}h)mmnm10?^%bJsX&P89pRdxHJ&cHnX zY&0~nYE{=sY7JpmfJPs2U!-qhMUOsBgdG9}2TWj8aTr-xxfC=I7C8iTRlhj&|2bO? zeH?JbW@* zZTHp=UelFepkKCc9M?9@TUoQQj6}PcG3Ij=+ZBIU%7U146ZjkJFkV=!R#Vx*IO3d3u9}3 z(bBKMP+(kMYIemU*h`5)nFOr7GX&Iru1B78O)k$%AxcCDHl@*sA&mRZmAaR^ed*rQ zZL2z{=?6=3#r#Z|$WoA48*J{;s)gdOaJX-c2dRED<13kgJ0F4)InVo|hvNr-T0PeC z*#vFs4(+4(@{!_Y%H1K3JV0qjFyf-#wEGT>KB3>MbUrZOAKTs>ENxRCz*;xN`VLMGc87yrM5e*MFzh=C@-?s{IKt8`x))q$dD%&S*nR8)XiSd-U@MO}` zk9ViKPRF|hdfFbc4fsaPu_Gx+yLJpP4KY2#-UOM6UlSw5#;+wm)8%6e`gp(^qDqX3 zQM*qh=+)1%f!^AHirU4U_#@p;y5PSpv@UsK1h3*k?jx(VO+NwpEn*z;H{~ii{6B6X zL9)UyiOI}zjmUjc_rRx}iV3&$T<5l5DtuQL_dgN?MUGrF4YD~GNLDfnUxYUyua)GHWosdo#u%(Oqp#*>WcdW z`|md0U$QDDk@35_Us7y@&_F;W{~mHxWdt29jLl5`mZ&KzI$BsFsJ>y;qsWTu;O1b~ zP(Nu1Xe21`p((_le?bPU;b#^u888(~v9)`cvY~Zcc3<~N(REnh(Tx?w{bYOS^V`W& zn6_mlV20WeF(qZX;yB{Dn&5a{=IibPjt52{iVQ(SSD~(W5+3A18#nNdL~~PzBS7iP zjJ&7sYpL0*r^m&wG9-$I_udldH-*%rFK@Hp+E@VX->D>lsVKbfw8i9Z9M5yqO7a|) zura-q33KYJ%h3+* z+~fR0!xU_V8!o-9%7ljj-M8va4K_WkRZ8@b?bSyPH98|>jBs>w{eTOLn_6Ojor)^x}Tlzm4X>hP~2%Phw6@go>jY%nUd?J7xb_>b7U3e zY8tZ#qF6>V^YnvmViinpZ=VO%q1IqkA?f3PkZH=~@CeRiY$uu1itCl>+#3MI15^qC z&8`mcKxJe2H0Rm{H0-M6#UF`Uxn=qiDi!O>=T3F}m3oyJN|880+0G)@ocS?)pSYqs4Kw#; zm3Y;hhEm}Co5IJ|GC7RNi-68gLGzM*Vt6UK^zx#~$441N#WM z!x_+pQ~P00Bag=~wtrNWij_$mGiA~2T*9o^DUvi4VT)(9FTh~kANY@fj(mHcF+Pkc zz`I2Db>b%8{QeuD{@O>tqo9_n{{pDQFM#?FXXMo!4eUh?jGXNpJ^qGKovNFEiCKTr zSg#nj^Y@9th-l@P$jk-rU|3d=!--UQTbPrtXtIqXv%h7Qz;YloX3)PO%HzUGRhAC_5Usg$krPomNPs;p) z!c?Uq8$yXZrYrkh{u*{BDsu>B$IQh3jihE!=8kW%hXb!79KA|D-yR1o{lXhH{E> zwB;wNcr3m91V}H~(BbqAILi8@u`v5aZaS9FV#PW~)F^Wxy||gE^b-aCc?X-ybviP8 zQb}_lIDrk#Mc9btf{toU_fV{lL_75wS{Lm)BN!sw{+JW3#6Jv~SFGD#47rQHW<5am zN0G3GCJU68##>aKgszHGU^J>zrMNrHd+@P5g+WGUZZ#r@j;6s!lYy~{MjAbWN+0kX zGCBZRMi7A!S$7x(7 zjO!d3273ee{sB|pZffOtmMYD%niIXV;5f9V?Fh38^wnAgaa&|u<-_#&{TUJjsO8-O zH})0(-tk=bBPSYG5xHGvrEQAwW^biA!cnE#IEgaHc;Y#mvl&OO8PVL#tjKmP{EOsV zy6J^z6{n`s<7|DB>s5SqQ8VTi2*zPv;UUJ_;tWsXY?j5fd!((VL@a6bPNhvP#4kj23&&^9r~XU4Amq0gm8Euc)wfdI;0*jD;1 z`(E(jd5#z+jE%Z1%}=I=DMrah`&lDv;ZIls}eym*dee6iAzUUZCk~rn*Q_c(oIC;=GNPJ%v@zqb^LZ78 z*U?WOW^pge%kTcM%J3mY=go!#E7VFEzgezdIa??9S@gFrh%vvGhpOxU@UvY@1^@W= z-@x}*W%iDT!SwJ&gv-A;6wSY{%>DvCdlO?3cOw&fXA8T(YoEm^uPUM_Ao8$zg&H8i z>TCCajpB-cf`JnFgAXqE&hj*H>Gq59k`VvKhsK@xzD zXJ)qF@of6EU1dB!ynf|`L-7WrlzzB7BASyl;XY1nVF8X?r+I&Tuoq^kJsuIVjo9Ed zKP2LD2x5%BWe(7wNrFaZC-Mp>H5{{%K5^nW1oNa{1Pkb^Ln2e?$YToA89|Uf7o**g->vY+gM?Nvtu9oPdA}-Dk@|MBwRtort}EP$~W( z1}B$ABv3<_*%LJ8Wyi@Q+y9LA($AW23#>bQhI+0VTKTbxpVT;QBEN$MJk@C;-&Fm-0It2G;OdSDLa!R zH3-YcjS0eMGzwZ97fWdZ@!js!gLD{*qauKzHB@V5l|yI3UGz1=b|I5@ZuxU4I< zt1CFXD0tIc$8F&NuqZeZoJ`)2fjZ&$?12tvpU>hS3%`-AM8T_f-sTE_D>qMMD~p2X z+UL&&E)ep>3yOlbz7;yZZ@g7bWM>Qe#LGK4DwqmH@G7Gb1p&1MSVzM~!%D;A_l)$7 z^i1>s8#4R?mLLUZ{U<^6zp5V~{*PiXa3G*EcpxCQe-8piUmh_Qwk`&L0e}V zxcgf%G^x7ogrb7^X;atg>Lq1SkSqn-XtRb~3u#HAE(8({(=NlB9C#l&l*m2HGp`l}bnMtx% z0;)V`=_u(cU1)j2W+S2cKS>y*rDUZ?q+v&`TAva;Ra|An?(J=6BMN=e3{Wveo~bcM zOfVCfOX#peI$09HKai|F-4IO7B$`R?;xbh^a~afJ`e*jA3v(LovQfxTV{<2Av|YIs zZbe&6F4YCi)Mzd!Zgz6PX`QTjxhxJx&USIg<@H(TVN(l_>6Gjb`|5%ZnVlA(>s(!2 z)QDL6dR4}nTx~E8dQj`K=$Y4Xml=P|{Z2MIS!K?EMROwDHJ!}okgy&EtO!J_RpzfE zvE=@a3_ji_$cMF1&750T97KATIM5e=+S?BQod>Q3ruyY|4m$1HZkwj6UD!b6X;rAI zMD%Q(NM-F=aGQWmvQX@r1>T5IlPfXqEPW&zTcI56m^MZ=So9~bVVtW~oq+e0_9!%% zUdup&B?S?*<_i1tlL{p!%9B+^R8ZryMZv8~c;rX$&S>$jY~gisMsuRI@DWjID|47w zOIskubzyMPG`AC~u>ocH9)6?s2_Eu8&Mb`}&H)R~;)VH=bD=A58WT-e3GfI-3pf>! zRzOfkAP75Vj|&){zDO_J56N;Wtd_8*K4rL|5*DKo$)jgtfUZOx_9Ng+V7d94Anvd! zFz#2WKB^Hk?@(o+96!#QvIHfX!KC7fsvCW9x`eB0*=hS z*>MPn9G#>kSd;@Q#%*#uELIcs)Xs@ziQ@R#wM!c0FMTVI&P&Z)u0D84_U4;-Qh09H3V3mtU~!ac zH~YB&+fPXWAO=qe!DErUDsL#pCo$DOM(&5KJ2+=4MmT5jbT$A>MBp0y@O|?>C3ph)l$i))~i<*(59wJzkhI#0h}w_edGy2Bw&f5Fs~EHv!G zDuC5-1=d$DPD5cJbad})1yl*it35Tk%ZZ#0Ul!ajd_UyGEpPylk!yL3-FiPW-;y-T zg0#)u&?$+XIi{9KNv7Ow?8bEG1M7PYa7&Qf@Dlgp+bU$5qS_Rt{goHd1;m5G6Jmdr zpMZI3mA3AK70!KJFcbHx^$vWWi#(Gc7|ZcnwL7X6(wPnb=3Lor;%J4q0*lryaqlVP z&!c9q0h)yvEnztP=K!gl$Tk(3P_J&~#`}3hw+wPxu53TuUZ_>ZQ=9S-CwU0UT}o+F z2bAc3|5ksy#{A;!8C=H4x$6u*aI4qr`f`2DRM@xxo#Ixm^U6^3=gbFtj$2Gqf}@a{k+D{C_DjrtTJyhqJM#lMO|| z72qb#|Cd4|pD=Bqc<%0Qpg3DO9GEBmt4!Jazf~K)(BiGUZKR^$-<+dXFael=bWDE# zgph=Qi~z6!Lw&GBX;|xji3`!}O&iXym@xRF9{(TDr}ST2bAN9SD@@7)Ghk*D2EGOP z`^o*nZkVkiE9#9$r0;c~QF60jC27~0+dSAQ^0@xyO>VSKlaTJ7A7(dq;(YkJR&y06 z2ZV~DlC9z(E01yFRF``T_vLZYFqDH+x zE|Nc>`P$fMN=ck|P&=(6DgPj9$JyCF-w|bdE)U8^%B(;TljMdZ5}gUIcqW;)F)j3> zZ#nW7j$zPNq&dsO=DNJ~@pv}KZiJLk`w3kg4c2?0TkW~9U6%Dqg=>rk9Edz&nR@S* z4{OfttS+#)hh&L<29IT~Y2Es#Y2Iz7amA_4=#B=SegO)UtS#04<)5rl{t7j_q+pSW zuMqpo5r^vkE!6%Ydj2!6Hnxu*Hq_4vn}&y=_8L;$xs{t=jFPk%i}LFPl`5np3M#N5 z_Zr+I(4#!rcg*y7%xitAZok+1&ksM}Z;;-^m}Dc6^)U@UcT3J(*GBSlXmU&h+ts;h zgpa1yFe#dD$sc2u+woJUz6HB`@;D#@rU%q-TM)b z&$vW81;q#{4ZLZXsoSr{uP^PUsdsca8I-}wqjtQ`^UD0-hbWxJvxJM4o!XE-frRiBL~@0jf*hjgalbbqvZF)cVtmf43BJ4lMHi_ z`<+pl6gG^G9i>>8p{G)JQ&oRNjw5J?Zf(Ri)l{e~(=Vz_Qnao$jpES@AI3!P($WVf zR>**R3{u*MK4dHGS}oqPHnRy6qD^YFnc7-55iEU_o~Ocw5oFb$7iu7Jv)pc z&@!gHF_E~W0^y0Utlf!LR;vn6*l?Feph9PJg3Z&QW|Q%|Q=LG-M*Jy(k33Vg$x@Tm zVPqK|)zB1xyt2D4zYLGxtbX_GAG2!rmRN4x$K0a2Z*n{b6AD8oUUUT*h6>4b7-O8M zgq<3&`k5$(W*!xial03v55j_&9VIxOsV*)(8wru0*jk4;1SrkK!gE^A=0dO8OY~A7 zid+AwB5y&czY$1 z#OxNEga6eb3eM&byaUC6&kCL(jOM6OF9g4iiZBNXQl^z=R$~xeWejE5L+L27*2o9# z)jZ@{1Cw}wto`X`{>RWT+U~vU2}lA1Jft=pGu7NKBVDz8k0_2$rwZem%-a`X|Hyk4pt_(woQL{v~zFY4!UozEWrTtE2QEp#860Vfvq`!}JdawV%qfvVSEH$VF&%fh1KFyf+}eF?Ta5 z)BsYFw$ZItx5M0er|FGVJicxph@CwHa0}G0cEKp-a5|U~dJKixFHp9S15{PTmSOs? z=^*Y$53Q*10%Zk-O`8fgM#z@+->)6}B6UAEC*zl_Hc;eVDy(2nP7TVj1f}A78L4$+ z3h2Z2b&&c4wsvw=X9;?lzzaQ;F)|G*4HY;2!(1K@WR=`A8PC~;8mn?GVM3n;78c!i zxB~FwOR(ya^i0VSB<)_>sj4m?mgdD@Ty9w5;jR;4OMEA0sB&RA8VrRfoirl|PHAnJ zh?i327-f`=$#u^gU4`$)egGU&hJ$QyB~b8WNTX$8@iW-^<%Q3_T{(kJwj5RPb{i%q z?RKq^Oj+JUPkv@Z2-D80(Im=XDo5FnIT36E6rhWh}{|sgTcTEIn7#{Agj*@tKOY|(uFn#lT^+& zbnV$0DXX|>xKVkR3HK$SHNHs1sUd{GD|&ao=kOiR=AkAmg5w3Oq~eHCJTbqR{ux6* zmxAcNHk_FcJ>hAXkTZ9C7P51`Me>H_Hdo1dmi@>Z%n98S(*fNJ(`Af@I9t0gtT;*P zLEk4ffujzcAmA~bz-ssdyLz8=Vlthid-^r>7Wq(0Hf^O%c!{Kv_Q&8YMlo-W{wrcV zhtB{~){X5T3*d_NFwQl17$-W>kL{3r2RsHa_C1Q>>0frKfu#L)b|HX(=urMw(Er!S z{Tt}#s6DG;4dZ^BPkm`fCJP*k6)hwK$1aeJ-fr8bOM_3{aBA7R zlWXDG+`2|;k+_9nBc$bsY5uNR#&^)!^&#W)K5iHR$>GkUK<2?_k z?Yf!$^ac#ADN+!dfZZXO0YePtP-P=hXwVy0f;xP$Fp^Ap1AUyX@<|a}Z%A$6S_Mrn zst9^IYWIv%7m=|WX_)PX25lSte4Ap}Z9lu4Ot!0L4}wxRdLQ#}-yMps%3Wlz%7J-r z*nxS61+8XSA%ac$O?WVia!c{133&3CV{GdVtVU?AiaZ~4(e#;)1`pdJ3#(0*rzY+l zr8z^LXTc0{Y}SB7l8vmXOuxnViOHmaQT0|SPud(78!#1Kiub^nx7r26sSMVf=mLCC z+N5#zBedWontf=(chxmzdw23ACb2_PyYz>2U!w6G%L;GpW~RO7W`IK}6BrndP%6(N zi`C|oalL2Sj2iv9^wvqH#P&JwJPWUP?^JQw#L;iL)0!+soaG|l<$WnrR=Vg;y45|V z$FUdyr-*0cj(QWXNC?Yv;M9Kdk%Z#4xFeUuxGcD*cCvy&a;73qdHIggowodCfIuUkrDkx@NZ5j z59tkMOKuN$fd+>n$O;Qco#eeH1dwfV=1FnW<9*d#G}Nd{a(dt=={yx!hfGb4zghzR z*gGN+gF6S!>YaBs(IkL4mCQDC7?vDHpBT(%G|l;z2@VwpD!nd9g)w2JGA&m%ulEv; zc`8(FGmsJlk^KC%BMXWzngTYQivlg7nZjh35?Hd66GXNi3c{6urgB$u&z;u!x*VUF zbo{MX;284Sp`I<~gmu0bFFuL)rPq2Xd#>IV`9fT{<1RZX;r2~9?DpfgqRTQ%(}Yh^ zk2&WYKiENRiX1>S*W+V`H$T7YB&KP-g9=#JjZ{oyE5?pmN#E|GzAW8vIPu#=f2sLU zoqkchLStt&)8+l&r$9XDoe_BSh9HBCMkJSv;`T;){B zvCMinCwwALAsLJPE7ZI1zL9{Y?#>2s_RAV03Fp~t=LqZdI+izBzGe6BPeIs*GS=&+ zg_%fJxb6X?a}zBlmHwJ*E6cUcSmig-e!CkkxNb2%q_y^43-vxc<~JliLdb7ED*ar? zYPCOhr=MWx)@k(3&BY*;WUbvIFJ$Euj+$WS;(Mb*yA4BPOyY*r1b0<5#%6Kq#S8Xy z;I4LkN_VPxBEfw9VY(wMz`AU~ojB%G;WNRI>JgYXdMg8)K<=R7tkmfw@^)MmB#~FB z%b$Q`5j$|o*^brUlfEP%rZX>tjME=R*rZO1O4TVF1x!Yd1k{^y?FFI()E?X=NZVU! zx9C2~`c!{jR?oCOD^q&Nnr8%l{_GjX$C3eyxxNxjR10~KB

982W$MIrA!^$&Y*9VtUU{m4c$5W6=7Gx8q+lpCv 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

ypdWY1^p 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 diff --git a/package.json b/package.json index 8144128..630643f 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,13 @@ "main": "state-machine.js", "devDependencies": { "local-web-server": "~1.2.6", - "qunit": "~0.9.1" + "qunit": "~0.9.1", + "uglify-js": "^2.7.4" }, "version": "2.4.0", "scripts": { "start": "ws --rewrite '/test -> /test/'", - "test": "node test/runner" + "test": "node test/runner", + "minify": "uglifyjs state-machine.js --output state-machine.min.js --compress --mangle --stats" } } diff --git a/state-machine.min.js b/state-machine.min.js index 1743263..9093160 100644 --- a/state-machine.min.js +++ b/state-machine.min.js @@ -1 +1 @@ -(function(){var a={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(g,h){var j=(typeof g.initial=="string")?{state:g.initial}:g.initial;var f=g.terminal||g["final"];var e=h||g.target||{};var m=g.events||[];var i=g.callbacks||{};var c={};var k={};var l=function(o){var q=Array.isArray(o.from)?o.from:(o.from?[o.from]:[a.WILDCARD]);c[o.name]=c[o.name]||{};for(var p=0;p=0):(this.current===n)};e.can=function(n){return !this.transition&&(c[n]!==undefined)&&(c[n].hasOwnProperty(this.current)||c[n].hasOwnProperty(a.WILDCARD))};e.cannot=function(n){return !this.can(n)};e.transitions=function(){return(k[this.current]||[]).concat(k[a.WILDCARD]||[])};e.isFinished=function(){return this.is(f)};e.error=g.error||function(p,t,s,o,n,r,q){throw q||r};e.states=function(){return Object.keys(k).sort()};if(j&&!j.defer){e[j.event]()}return e},doCallback:function(g,d,c,i,h,b){if(d){try{return d.apply(g,[c,i,h].concat(b))}catch(f){return g.error(c,i,h,b,a.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",f)}}},beforeAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onbeforeevent,c,f,e,b)},afterAnyEvent:function(d,c,f,e,b){return a.doCallback(d,d.onafterevent||d.onevent,c,f,e,b)},leaveAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onleavestate,c,f,e,b)},enterAnyState:function(d,c,f,e,b){return a.doCallback(d,d.onenterstate||d.onstate,c,f,e,b)},changeState:function(d,c,f,e,b){return a.doCallback(d,d.onchangestate,c,f,e,b)},beforeThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onbefore"+c],c,f,e,b)},afterThisEvent:function(d,c,f,e,b){return a.doCallback(d,d["onafter"+c]||d["on"+c],c,f,e,b)},leaveThisState:function(d,c,f,e,b){return a.doCallback(d,d["onleave"+f],c,f,e,b)},enterThisState:function(d,c,f,e,b){return a.doCallback(d,d["onenter"+e]||d["on"+e],c,f,e,b)},beforeEvent:function(d,c,f,e,b){if((false===a.beforeThisEvent(d,c,f,e,b))||(false===a.beforeAnyEvent(d,c,f,e,b))){return false}},afterEvent:function(d,c,f,e,b){a.afterThisEvent(d,c,f,e,b);a.afterAnyEvent(d,c,f,e,b)},leaveState:function(f,e,h,g,d){var c=a.leaveThisState(f,e,h,g,d),b=a.leaveAnyState(f,e,h,g,d);if((false===c)||(false===b)){return false}else{if((a.ASYNC===c)||(a.ASYNC===b)){return a.ASYNC}}},enterState:function(d,c,f,e,b){a.enterThisState(d,c,f,e,b);a.enterAnyState(d,c,f,e,b)},buildEvent:function(b,c){return function(){var h=this.current;var g=c[h]||(c[a.WILDCARD]!=a.WILDCARD?c[a.WILDCARD]:h)||h;var e=Array.prototype.slice.call(arguments);if(this.transition){return this.error(b,h,g,e,a.Error.PENDING_TRANSITION,"event "+b+" inappropriate because previous transition did not complete")}if(this.cannot(b)){return this.error(b,h,g,e,a.Error.INVALID_TRANSITION,"event "+b+" inappropriate in current state "+this.current)}if(false===a.beforeEvent(this,b,h,g,e)){return a.Result.CANCELLED}if(h===g){a.afterEvent(this,b,h,g,e);return a.Result.NOTRANSITION}var f=this;this.transition=function(){f.transition=null;f.current=g;a.enterState(f,b,h,g,e);a.changeState(f,b,h,g,e);a.afterEvent(f,b,h,g,e);return a.Result.SUCCEEDED};this.transition.cancel=function(){f.transition=null;a.afterEvent(f,b,h,g,e)};var d=a.leaveState(this,b,h,g,e);if(false===d){this.transition=null;return a.Result.CANCELLED}else{if(a.ASYNC===d){return a.Result.PENDING}else{if(this.transition){return this.transition()}}}}}};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=a}exports.StateMachine=a}else{if(typeof define==="function"&&define.amd){define(function(b){return a})}else{if(typeof window!=="undefined"){window.StateMachine=a}else{if(typeof self!=="undefined"){self.StateMachine=a}}}}}()); \ No newline at end of file +!function(){var t={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(e,n){var r="string"==typeof e.initial?{state:e.initial}:e.initial,i=e.terminal||e.final,a=n||e.target||{},o=e.events||[],u=e.callbacks||{},s={},c={},f=function(e){var n=Array.isArray(e.from)?e.from:e.from?[e.from]:[t.WILDCARD];s[e.name]=s[e.name]||{};for(var r=0;r=0:this.current===t},a.can=function(e){return!this.transition&&void 0!==s[e]&&(s[e].hasOwnProperty(this.current)||s[e].hasOwnProperty(t.WILDCARD))},a.cannot=function(t){return!this.can(t)},a.transitions=function(){return(c[this.current]||[]).concat(c[t.WILDCARD]||[])},a.isFinished=function(){return this.is(i)},a.error=e.error||function(t,e,n,r,i,a,o){throw o||a},a.states=function(){return Object.keys(c).sort()},r&&!r.defer&&a[r.event](),a},doCallback:function(e,n,r,i,a,o){if(n)try{return n.apply(e,[r,i,a].concat(o))}catch(n){return e.error(r,i,a,o,t.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",n)}},beforeAnyEvent:function(e,n,r,i,a){return t.doCallback(e,e.onbeforeevent,n,r,i,a)},afterAnyEvent:function(e,n,r,i,a){return t.doCallback(e,e.onafterevent||e.onevent,n,r,i,a)},leaveAnyState:function(e,n,r,i,a){return t.doCallback(e,e.onleavestate,n,r,i,a)},enterAnyState:function(e,n,r,i,a){return t.doCallback(e,e.onenterstate||e.onstate,n,r,i,a)},changeState:function(e,n,r,i,a){return t.doCallback(e,e.onchangestate,n,r,i,a)},beforeThisEvent:function(e,n,r,i,a){return t.doCallback(e,e["onbefore"+n],n,r,i,a)},afterThisEvent:function(e,n,r,i,a){return t.doCallback(e,e["onafter"+n]||e["on"+n],n,r,i,a)},leaveThisState:function(e,n,r,i,a){return t.doCallback(e,e["onleave"+r],n,r,i,a)},enterThisState:function(e,n,r,i,a){return t.doCallback(e,e["onenter"+i]||e["on"+i],n,r,i,a)},beforeEvent:function(e,n,r,i,a){if(!1===t.beforeThisEvent(e,n,r,i,a)||!1===t.beforeAnyEvent(e,n,r,i,a))return!1},afterEvent:function(e,n,r,i,a){t.afterThisEvent(e,n,r,i,a),t.afterAnyEvent(e,n,r,i,a)},leaveState:function(e,n,r,i,a){var o=t.leaveThisState(e,n,r,i,a),u=t.leaveAnyState(e,n,r,i,a);return!1!==o&&!1!==u&&(t.ASYNC===o||t.ASYNC===u?t.ASYNC:void 0)},enterState:function(e,n,r,i,a){t.enterThisState(e,n,r,i,a),t.enterAnyState(e,n,r,i,a)},buildEvent:function(e,n){return function(){var r=this.current,i=n[r]||(n[t.WILDCARD]!=t.WILDCARD?n[t.WILDCARD]:r)||r,a=Array.prototype.slice.call(arguments);if(this.transition)return this.error(e,r,i,a,t.Error.PENDING_TRANSITION,"event "+e+" inappropriate because previous transition did not complete");if(this.cannot(e))return this.error(e,r,i,a,t.Error.INVALID_TRANSITION,"event "+e+" inappropriate in current state "+this.current);if(!1===t.beforeEvent(this,e,r,i,a))return t.Result.CANCELLED;if(r===i)return t.afterEvent(this,e,r,i,a),t.Result.NOTRANSITION;var o=this;this.transition=function(){return o.transition=null,o.current=i,t.enterState(o,e,r,i,a),t.changeState(o,e,r,i,a),t.afterEvent(o,e,r,i,a),t.Result.SUCCEEDED},this.transition.cancel=function(){o.transition=null,t.afterEvent(o,e,r,i,a)};var u=t.leaveState(this,e,r,i,a);return!1===u?(this.transition=null,t.Result.CANCELLED):t.ASYNC===u?t.Result.PENDING:this.transition?this.transition():void 0}}};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=t),exports.StateMachine=t):"function"==typeof define&&define.amd?define(function(e){return t}):"undefined"!=typeof window?window.StateMachine=t:"undefined"!=typeof self&&(self.StateMachine=t)}(); \ No newline at end of file From cccd978850e24c93ae976c45ed8dc05a36eab270 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 12:22:19 -0800 Subject: [PATCH 22/53] updated README and RELEASE_NOTES --- README.md | 68 +++++++++++++++++++++--------------------------- RELEASE_NOTES.md | 31 ++++++++++------------ bower.json | 1 - 3 files changed, 43 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 50b045d..100e4bb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Javascript Finite State Machine (v2.4.0) -======================================== +# Javascript Finite State Machine (v2.4.0) This standalone javascript micro-framework provides a finite state machine for your pleasure. @@ -7,32 +6,18 @@ This standalone javascript micro-framework provides a finite state machine for y * You can find a [description here](http://codeincomplete.com/posts/2013/1/26/javascript_state_machine_v2_2_0/) * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) -Download -======== +# Download Using npm: - npm install --save javascript-state-machine + npm install javascript-state-machine Or download the source from [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), or the [minified version](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.min.js) -Alternatively: +# Usage - git clone git@github.com:jakesgordon/javascript-state-machine - - - * All code is in state-machine.js - * Minified version provided in state-machine.min.js - * No 3rd party library is required - * Demo can be found in /index.html - * QUnit (browser) tests can be found in /test/index.html - * QUnit (headless) tests can be run with "npm run test" (after "npm install") - -Usage -===== - -Include `state-machine.js` in your web application, or, for npm `require("javascript-state-machine")`. +Include `state-machine.js` in your web application, or, for npm `require('javascript-state-machine')`. In its simplest form, create a standalone state machine using: @@ -60,8 +45,7 @@ along with the following members: * fsm.cannot(e) - return true if event `e` cannot be fired in the current state * fsm.transitions() - return list of events that are allowed from the current state -Multiple 'from' and 'to' states for a single event -================================================== +# Multiple 'from' and 'to' states for a single event If an event is allowed **from** multiple states, and always transitions to the same state, then simply provide an array of states in the `from` attribute of an event. However, @@ -92,8 +76,7 @@ allowed from any current state. >> NOTE: The `rest` event in the above example can also be specified as multiple events with the same name if you prefer the verbose approach. -Callbacks -========= +# Callbacks 4 types of callback are available by attaching methods to your StateMachine using the following naming conventions: @@ -175,8 +158,7 @@ You can affect the event in 3 ways: * return `false` from an `onleaveSTATE` handler to cancel the event. * return `ASYNC` from an `onleaveSTATE` handler to perform an asynchronous state transition (see next section) -Asynchronous State Transitions -============================== +# Asynchronous State Transitions Sometimes, you need to execute some asynchronous code during a state transition and ensure the new state is not entered until your code has completed. @@ -224,8 +206,7 @@ For example, using jQuery effects: >> _NOTE: If you decide to cancel the ASYNC event, you can call `fsm.transition.cancel();` -State Machine Classes -===================== +# State Machine Classes You can also turn all instances of a _class_ into an FSM by applying the state machine functionality to the prototype, including your callbacks @@ -261,8 +242,7 @@ This should be easy to adjust to fit your appropriate mechanism for object const >> _NOTE: the `startup` event can be given any name, but it must be present in some form to ensure that each instance constructed is initialized with its own unique `current` state._ -Initialization Options -====================== +# Initialization Options How the state machine should initialize can depend on your application requirements, so the library provides a number of simple options. @@ -325,8 +305,7 @@ So you have a number of choices available to you when initializing your state ma that each instance gets its own unique `current` state, rather than an (unwanted) shared `current` state on the prototype object itself._ -Handling Failures -====================== +# Handling Failures By default, if you try to call an event method that is not allowed in the current state, the state machine will throw an exception. If you prefer to handle the problem yourself, you can @@ -343,20 +322,31 @@ define a custom `error` handler: ]}); alert(fsm.calm()); // "event calm was naughty :- event not allowed in current state green" -Release Notes -============= +# Contributing + + > git clone git@github.com:jakesgordon/javascript-state-machine + > cd javascript-state-machine + + > npm install # install dev dependencies + > npm start # run a local dev server + + * Source code - `state-machine.js` + * Minified code - `state-machine.min.js` (build with `npm run minify`) + * Browse demo at `/` + * Run tests in browser at `/test/` + * Run tests in console with `npm test` + * Please include tests with pull requests. + +# Release Notes See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file. -License -======= +# License See [LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE) file. -Contact -======= +# Contact If you have any ideas, feedback, requests or bug reports, you can reach me at [jake@codeincomplete.com](mailto:jake@codeincomplete.com), or via my website: [Code inComplete](http://codeincomplete.com/) - diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0614fdf..b6f5bb8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,22 +1,19 @@ - FUTURE Version 3.0.0 (ETA - Early 2017) - ------------------------------ - - I know, I know, I've neglected this library for far too long, so - lets get it back on track before the end of 2016 - - ADD: Promise based async transitions - ADD: conditional transitions - ADD: observable transitions - ADD: composable state machines - ADD: better introspection - ADD: undo/redo history - ADD: use camel casing for callback methods (instead of all lower case) + FUTURE Version 3.0.0 (ETA - Early 2017) + ------------------------------ + + I know, I know, I've neglected this library for far too long, so lets get it back on track before the end of 2016... + + ADD: Promise based async transitions + ADD: conditional transitions + ADD: observable transitions + ADD: composable state machines + ADD: better introspection + ADD: undo/redo history + ADD: use camel casing for callback/observer methods (instead of all lower case) -Version 2.4.0 (ETA - December 2016) --------------------- - - TODO: resolve outstanding github issues and pull requests +Version 2.4.0 (ETA - November 2016) +----------------------------------- * added npm install instructions to readme * fix for javascript error when running in jasmine/node (issue #88) diff --git a/bower.json b/bower.json index cb28032..7f1f489 100644 --- a/bower.json +++ b/bower.json @@ -22,7 +22,6 @@ "node_modules", "bower_components", "test", - "tests", "demo", "index.html", ".gitignore" From 56ac6759440cfacd38cd4a66b499f57117b0513f Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 14:01:03 -0800 Subject: [PATCH 23/53] more readme --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 100e4bb..ef7a7e3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # Javascript Finite State Machine (v2.4.0) -This standalone javascript micro-framework provides a finite state machine for your pleasure. - - * You can find the [code here](https://github.com/jakesgordon/javascript-state-machine) - * You can find a [description here](http://codeincomplete.com/posts/2013/1/26/javascript_state_machine_v2_2_0/) - * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) +A standalone library for finite state machines. # Download @@ -341,6 +337,18 @@ define a custom `error` handler: See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file. +# Related Links + + * You can find the [code on github](https://github.com/jakesgordon/javascript-state-machine) + * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) + + * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) + * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) + * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) + * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) + * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) + * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) + # License See [LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE) file. From f2cc8a09b6d7575debc504dfada4dbd95f2f56e9 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 14:03:36 -0800 Subject: [PATCH 24/53] more readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ef7a7e3..7148dad 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,13 @@ or the [minified version](https://github.com/jakesgordon/javascript-state-machin # Usage -Include `state-machine.js` in your web application, or, for npm `require('javascript-state-machine')`. +Include `state-machine.js` in your web application: + + + +Or for npm: + + var StateMachine = require('javascript-state-machine'); In its simplest form, create a standalone state machine using: From 489f4bd8f9237d0e9415aec5421e1c620a74e800 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 14:06:35 -0800 Subject: [PATCH 25/53] document fsm.states() method in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7148dad..1c1fed0 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ along with the following members: * fsm.can(e) - return true if event `e` can be fired in the current state * fsm.cannot(e) - return true if event `e` cannot be fired in the current state * fsm.transitions() - return list of events that are allowed from the current state + * fsm.states() - return list of all possible states. # Multiple 'from' and 'to' states for a single event From d5a00dd3e4ed94b5077e2a41760a14e6a119c7ec Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 14:14:41 -0800 Subject: [PATCH 26/53] more readme --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1c1fed0..4386ed5 100644 --- a/README.md +++ b/README.md @@ -340,21 +340,20 @@ define a custom `error` handler: * Run tests in console with `npm test` * Please include tests with pull requests. -# Release Notes - -See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file. - # Related Links * You can find the [code on github](https://github.com/jakesgordon/javascript-state-machine) * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) + * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) - 3/15/2014 + * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) - 1/26/2013 + * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) - 1/7/2012 + * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) - 8/19/2011 + * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) - 6/21/2011 + * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) - 6/1/2011 - * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) - * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) - * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) - * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) - * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) - * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) +# Release Notes + +See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file. # License From c7538b4fce486a84de7a456b72ce7dc15201c818 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 14:18:43 -0800 Subject: [PATCH 27/53] more readme --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 4386ed5..d794b7d 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,10 @@ This example will create an object with 2 event methods: The `rest` event will always transition to the `hungry` state, while the `eat` event will transition to a state that is dependent on the current state. ->> NOTE: The `rest` event could use a wildcard '*' for the 'from' state if it should be +> NOTE: The `rest` event could use a wildcard '*' for the 'from' state if it should be allowed from any current state. ->> NOTE: The `rest` event in the above example can also be specified as multiple events with +> NOTE: The `rest` event in the above example can also be specified as multiple events with the same name if you prefer the verbose approach. # Callbacks @@ -88,7 +88,7 @@ the same name if you prefer the verbose approach. * `onenterSTATE` - fired when entering the new state * `onafterEVENT` - fired after the event ->> (using your **specific** EVENT and STATE names) +> (using your **specific** EVENT and STATE names) For convenience, the 2 most useful callbacks can be shortened: @@ -142,7 +142,7 @@ Additionally, they can be added and removed from the state machine at any time: The order in which callbacks occur is as follows: ->> assume event **go** transitions from **red** state to **green** +> assume event **go** transitions from **red** state to **green** * `onbeforego` - specific handler for the **go** event only * `onbeforeevent` - generic handler for all events @@ -153,7 +153,7 @@ The order in which callbacks occur is as follows: * `onaftergo` - specific handler for the **go** event only * `onafterevent` - generic handler for all events ->> NOTE: the legacy `onchangestate` handler has been deprecated and will be removed in a future version +> NOTE: the legacy `onchangestate` handler has been deprecated and will be removed in a future version You can affect the event in 3 ways: @@ -207,7 +207,7 @@ For example, using jQuery effects: } }); ->> _NOTE: If you decide to cancel the ASYNC event, you can call `fsm.transition.cancel();` +> NOTE: If you decide to cancel the ASYNC event, you can call `fsm.transition.cancel();` # State Machine Classes @@ -242,8 +242,8 @@ instances: This should be easy to adjust to fit your appropriate mechanism for object construction. ->> _NOTE: the `startup` event can be given any name, but it must be present in some form to - ensure that each instance constructed is initialized with its own unique `current` state._ +> NOTE: the `startup` event can be given any name, but it must be present in some form to + ensure that each instance constructed is initialized with its own unique `current` state. # Initialization Options @@ -302,11 +302,11 @@ same as the first example in this section where you simply define your own start So you have a number of choices available to you when initializing your state machine. ->> _IMPORTANT NOTE: if you are using the pattern described in the previous section "State Machine - Classes", and wish to declare an `initial` state in this manner, you MUST use the `defer: true` - attribute and manually call the starting event in your constructor function. This will ensure - that each instance gets its own unique `current` state, rather than an (unwanted) shared - `current` state on the prototype object itself._ +> IMPORTANT NOTE: if you are using the pattern described in the previous section "State Machine + Classes", and wish to declare an `initial` state in this manner, you MUST use the `defer: true` + attribute and manually call the starting event in your constructor function. This will ensure + that each instance gets its own unique `current` state, rather than an (unwanted) shared + `current` state on the prototype object itself. # Handling Failures @@ -344,12 +344,12 @@ define a custom `error` handler: * You can find the [code on github](https://github.com/jakesgordon/javascript-state-machine) * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) - * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) - 3/15/2014 - * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) - 1/26/2013 - * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) - 1/7/2012 - * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) - 8/19/2011 - * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) - 6/21/2011 - * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) - 6/1/2011 + * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) + * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) + * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) + * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) + * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) + * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) # Release Notes From 1d6526f0c73419269c21a35d4093c5ad6847c795 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Mon, 21 Nov 2016 03:03:34 +0400 Subject: [PATCH 28/53] Restrict list of published files in npm --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 630643f..a888691 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "url": "git://github.com/jakesgordon/javascript-state-machine.git" }, "main": "state-machine.js", + "files": [ + "state-machine.js" + ], "devDependencies": { "local-web-server": "~1.2.6", "qunit": "~0.9.1", From 7ebe918aa92fdb30ece709795849622fe34a50cf Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Mon, 21 Nov 2016 03:07:31 +0400 Subject: [PATCH 29/53] Add Travis-CI config --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c86adcc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - '4' + - '6' +sudo: false From c944086d7a200a1f72c327eea13824f4726fa955 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 15:48:07 -0800 Subject: [PATCH 30/53] include minified state-machine.min.js in npm files --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a888691..a350191 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ }, "main": "state-machine.js", "files": [ - "state-machine.js" + "state-machine.js", + "state-machine.min.js", + "LICENSE" ], "devDependencies": { "local-web-server": "~1.2.6", From e22f7e522b44e6c5fcc7fbd0b6b2074ce365bf15 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 16:02:04 -0800 Subject: [PATCH 31/53] added travis-ci build status badge to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d794b7d..3ad375c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Javascript Finite State Machine (v2.4.0) +[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) + A standalone library for finite state machines. # Download From adcd3a4e6b66c498f78ec76874f8b15cb2a8b4ec Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Mon, 21 Nov 2016 04:08:48 +0400 Subject: [PATCH 32/53] readme: move version number from header to badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ad375c..f5af586 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# Javascript Finite State Machine (v2.4.0) +# Javascript Finite State Machine [![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) +[![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) A standalone library for finite state machines. From e53c8e7230b3c7c21838e21b641f233f8ca0a55d Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 16:27:52 -0800 Subject: [PATCH 33/53] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b6f5bb8..c0aba13 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,7 +2,7 @@ FUTURE Version 3.0.0 (ETA - Early 2017) ------------------------------ - I know, I know, I've neglected this library for far too long, so lets get it back on track before the end of 2016... + I know, I know, I've neglected this library for far too long, so lets get it back on track... ADD: Promise based async transitions ADD: conditional transitions @@ -12,8 +12,8 @@ ADD: undo/redo history ADD: use camel casing for callback/observer methods (instead of all lower case) -Version 2.4.0 (ETA - November 2016) ------------------------------------ +Version 2.4.0 (November 20 2016) +-------------------------------- * added npm install instructions to readme * fix for javascript error when running in jasmine/node (issue #88) From 90f11cccb47633dfc591858e2aef9d2aabd613fe Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 20 Nov 2016 17:29:57 -0800 Subject: [PATCH 34/53] put version badge before build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5af586..2b71e5e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Javascript Finite State Machine -[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) [![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) +[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) A standalone library for finite state machines. From ca1a2f380384d83f85ddc669c9798a9a96d6aca6 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 7 Jan 2017 12:11:09 -0800 Subject: [PATCH 35/53] v3 big rewrite (development occurred in a private repository so this is a BIG commit) --- .gitignore | 2 + LICENSE | 24 +- README.md | 413 +-- RELEASE_NOTES.md | 29 +- bin/examples | 60 + bin/minify | 40 + bower.json | 29 - demo/demo.js | 78 - dist/state-machine-history.js | 187 ++ dist/state-machine-history.min.js | 1 + dist/state-machine-visualize.js | 269 ++ dist/state-machine-visualize.min.js | 1 + dist/state-machine.js | 644 +++++ dist/state-machine.min.js | 1 + docs/async-transitions.md | 59 + docs/commercial-license.md | 180 ++ docs/contributing.md | 59 + docs/data-and-methods.md | 64 + docs/error-handling.md | 56 + docs/initialization.md | 57 + docs/lifecycle-events.md | 148 ++ docs/state-history.md | 127 + docs/state-machine-factory.md | 104 + docs/states-and-transitions.md | 156 ++ docs/upgrading-from-v2.md | 378 +++ docs/visualization.md | 211 ++ examples/atm.dot | 31 + examples/atm.js | 33 + examples/atm.png | Bin 0 -> 98712 bytes examples/atm.svg | 174 ++ {demo => examples/demo}/demo.css | 0 examples/demo/demo.js | 84 + .../demo}/images/alerts.green.png | Bin {demo => examples/demo}/images/alerts.red.png | Bin .../demo}/images/alerts.yellow.png | Bin examples/horizontal_door.dot | 7 + examples/horizontal_door.js | 16 + examples/horizontal_door.png | Bin 0 -> 11279 bytes examples/horizontal_door.svg | 35 + examples/matter.dot | 10 + examples/matter.js | 18 + examples/matter.png | Bin 0 -> 14731 bytes examples/matter.svg | 52 + examples/vertical_door.dot | 6 + examples/vertical_door.js | 16 + examples/vertical_door.png | Bin 0 -> 8246 bytes examples/vertical_door.svg | 35 + examples/wizard.dot | 13 + examples/wizard.js | 18 + examples/wizard.png | Bin 0 -> 28377 bytes examples/wizard.svg | 69 + index.html | 6 +- lib/history.js | 187 ++ lib/state-machine.js | 644 +++++ lib/visualize.js | 269 ++ package.json | 58 +- src/app.js | 102 + src/config.js | 161 ++ src/jsm.js | 181 ++ src/plugin.js | 40 + src/plugin/history.js | 83 + src/plugin/visualize.js | 161 ++ src/util/camelize.js | 9 + src/util/exception.js | 9 + src/util/mixin.js | 13 + state-machine.js | 230 -- state-machine.min.js | 1 - test/basics.js | 130 + test/construction.js | 229 ++ test/defaults.js | 62 + test/empty.js | 79 + test/errors.js | 160 ++ test/goto.js | 195 ++ test/helpers/lifecycle_logger.js | 25 + test/index.html | 22 - test/introspection.js | 204 ++ test/issues.js | 103 + test/lifecycle.js | 880 +++++++ test/observers.js | 151 ++ test/plugin/history.js | 493 ++++ test/plugin/visualize.js | 443 ++++ test/plugins.js | 151 ++ test/qunit/qunit.css | 237 -- test/qunit/qunit.js | 2288 ----------------- test/requirejs/index.html | 42 - test/requirejs/require.js | 33 - test/runner.js | 22 - test/test_advanced.js | 302 --- test/test_async.js | 408 --- test/test_basics.js | 733 ------ test/test_classes.js | 92 - test/test_initialize.js | 122 - test/transitions.js | 223 ++ test/util/camelize.js | 14 + test/util/mixin.js | 65 + test/wildcards.js | 212 ++ webpack.config.js | 43 + 97 files changed, 9308 insertions(+), 5003 deletions(-) create mode 100755 bin/examples create mode 100755 bin/minify delete mode 100644 bower.json delete mode 100644 demo/demo.js create mode 100644 dist/state-machine-history.js create mode 100644 dist/state-machine-history.min.js create mode 100644 dist/state-machine-visualize.js create mode 100644 dist/state-machine-visualize.min.js create mode 100644 dist/state-machine.js create mode 100644 dist/state-machine.min.js create mode 100644 docs/async-transitions.md create mode 100644 docs/commercial-license.md create mode 100644 docs/contributing.md create mode 100644 docs/data-and-methods.md create mode 100644 docs/error-handling.md create mode 100644 docs/initialization.md create mode 100644 docs/lifecycle-events.md create mode 100644 docs/state-history.md create mode 100644 docs/state-machine-factory.md create mode 100644 docs/states-and-transitions.md create mode 100644 docs/upgrading-from-v2.md create mode 100644 docs/visualization.md create mode 100644 examples/atm.dot create mode 100644 examples/atm.js create mode 100644 examples/atm.png create mode 100644 examples/atm.svg rename {demo => examples/demo}/demo.css (100%) create mode 100644 examples/demo/demo.js rename {demo => examples/demo}/images/alerts.green.png (100%) rename {demo => examples/demo}/images/alerts.red.png (100%) rename {demo => examples/demo}/images/alerts.yellow.png (100%) create mode 100644 examples/horizontal_door.dot create mode 100644 examples/horizontal_door.js create mode 100644 examples/horizontal_door.png create mode 100644 examples/horizontal_door.svg create mode 100644 examples/matter.dot create mode 100644 examples/matter.js create mode 100644 examples/matter.png create mode 100644 examples/matter.svg create mode 100644 examples/vertical_door.dot create mode 100644 examples/vertical_door.js create mode 100644 examples/vertical_door.png create mode 100644 examples/vertical_door.svg create mode 100644 examples/wizard.dot create mode 100644 examples/wizard.js create mode 100644 examples/wizard.png create mode 100644 examples/wizard.svg create mode 100644 lib/history.js create mode 100644 lib/state-machine.js create mode 100644 lib/visualize.js create mode 100644 src/app.js create mode 100644 src/config.js create mode 100644 src/jsm.js create mode 100644 src/plugin.js create mode 100644 src/plugin/history.js create mode 100644 src/plugin/visualize.js create mode 100644 src/util/camelize.js create mode 100644 src/util/exception.js create mode 100644 src/util/mixin.js delete mode 100755 state-machine.js delete mode 100644 state-machine.min.js create mode 100644 test/basics.js create mode 100644 test/construction.js create mode 100644 test/defaults.js create mode 100644 test/empty.js create mode 100644 test/errors.js create mode 100644 test/goto.js create mode 100644 test/helpers/lifecycle_logger.js delete mode 100755 test/index.html create mode 100644 test/introspection.js create mode 100644 test/issues.js create mode 100644 test/lifecycle.js create mode 100644 test/observers.js create mode 100644 test/plugin/history.js create mode 100644 test/plugin/visualize.js create mode 100644 test/plugins.js delete mode 100644 test/qunit/qunit.css delete mode 100644 test/qunit/qunit.js delete mode 100755 test/requirejs/index.html delete mode 100755 test/requirejs/require.js delete mode 100644 test/runner.js delete mode 100755 test/test_advanced.js delete mode 100644 test/test_async.js delete mode 100644 test/test_basics.js delete mode 100644 test/test_classes.js delete mode 100644 test/test_initialize.js create mode 100644 test/transitions.js create mode 100644 test/util/camelize.js create mode 100644 test/util/mixin.js create mode 100644 test/wildcards.js create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index 3c3629e..1fd04da 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +coverage +.nyc_output diff --git a/LICENSE b/LICENSE index 701eca9..f4b0142 100644 --- a/LICENSE +++ b/LICENSE @@ -1,20 +1,10 @@ -Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017, Jake Gordon and contributors +Copyright (c) Jake Gordon -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +"javascript-state-machine" is dual-licensed: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + * "javascript-state-machine" is available as an Open Source project licensed under the terms + of the LGPLv3 license. Please see + for license text. + * "javascript-state-machine" is also available under a commercial license (with support). Please + read docs/commercial-license.md and contact jake@codeincomplete.com for more details. diff --git a/README.md b/README.md index 2b71e5e..acdf35a 100644 --- a/README.md +++ b/README.md @@ -1,366 +1,145 @@ -# Javascript Finite State Machine +# Javascript State Machine -[![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) -[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) +A library for finite state machines. -A standalone library for finite state machines. +![matter state machine](examples/matter.png) -# Download +
-Using npm: - - npm install javascript-state-machine - -Or download the source from [state-machine.js](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.js), -or the [minified version](https://github.com/jakesgordon/javascript-state-machine/raw/master/state-machine.min.js) - -# Usage - -Include `state-machine.js` in your web application: - - - -Or for npm: - - var StateMachine = require('javascript-state-machine'); - -In its simplest form, create a standalone state machine using: - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); - -... will create an object with a method for each event: - - * fsm.warn() - transition from 'green' to 'yellow' - * fsm.panic() - transition from 'yellow' to 'red' - * fsm.calm() - transition from 'red' to 'yellow' - * fsm.clear() - transition from 'yellow' to 'green' - -along with the following members: - - * fsm.current - contains the current state - * fsm.is(s) - return true if state `s` is the current state - * fsm.can(e) - return true if event `e` can be fired in the current state - * fsm.cannot(e) - return true if event `e` cannot be fired in the current state - * fsm.transitions() - return list of events that are allowed from the current state - * fsm.states() - return list of all possible states. - -# Multiple 'from' and 'to' states for a single event - -If an event is allowed **from** multiple states, and always transitions to the same -state, then simply provide an array of states in the `from` attribute of an event. However, -if an event is allowed from multiple states, but should transition **to** a different -state depending on the current state, then provide multiple event entries with -the same name: - - var fsm = StateMachine.create({ - initial: 'hungry', - events: [ - { name: 'eat', from: 'hungry', to: 'satisfied' }, - { name: 'eat', from: 'satisfied', to: 'full' }, - { name: 'eat', from: 'full', to: 'sick' }, - { name: 'rest', from: ['hungry', 'satisfied', 'full', 'sick'], to: 'hungry' }, - ]}); - -This example will create an object with 2 event methods: - - * fsm.eat() - * fsm.rest() - -The `rest` event will always transition to the `hungry` state, while the `eat` event -will transition to a state that is dependent on the current state. - -> NOTE: The `rest` event could use a wildcard '*' for the 'from' state if it should be -allowed from any current state. - -> NOTE: The `rest` event in the above example can also be specified as multiple events with -the same name if you prefer the verbose approach. - -# Callbacks - -4 types of callback are available by attaching methods to your StateMachine using the following naming conventions: - - * `onbeforeEVENT` - fired before the event - * `onleaveSTATE` - fired when leaving the old state - * `onenterSTATE` - fired when entering the new state - * `onafterEVENT` - fired after the event +### NOTE for existing users -> (using your **specific** EVENT and STATE names) +> **VERSION 3.0** Is a significant rewrite from earlier versions. + Existing 2.x users should be sure to read the [Upgrade Guide](docs/upgrading-from-v2.md). -For convenience, the 2 most useful callbacks can be shortened: +
- * `onEVENT` - convenience shorthand for `onafterEVENT` - * `onSTATE` - convenience shorthand for `onenterSTATE` +# Installation -In addition, 4 general-purpose callbacks can be used to capture **all** event and state changes: +In a browser: - * `onbeforeevent` - fired before *any* event - * `onleavestate` - fired when leaving *any* state - * `onenterstate` - fired when entering *any* state - * `onafterevent` - fired after *any* event +```html + +``` -All callbacks will be passed the same arguments: +> after downloading the [source](dist/state-machine.js) or the [minified version](dist/state-machine.min.js) - * **event** name - * **from** state - * **to** state - * _(followed by any arguments you passed into the original event method)_ - -Callbacks can be specified when the state machine is first created: - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onpanic: function(event, from, to, msg) { alert('panic! ' + msg); }, - onclear: function(event, from, to, msg) { alert('thanks to ' + msg); }, - ongreen: function(event, from, to) { document.body.className = 'green'; }, - onyellow: function(event, from, to) { document.body.className = 'yellow'; }, - onred: function(event, from, to) { document.body.className = 'red'; }, - } - }); - - fsm.panic('killer bees'); - fsm.clear('sedatives in the honey pots'); - ... - -Additionally, they can be added and removed from the state machine at any time: - - fsm.ongreen = null; - fsm.onyellow = null; - fsm.onred = null; - fsm.onenterstate = function(event, from, to) { document.body.className = to; }; - - -The order in which callbacks occur is as follows: - -> assume event **go** transitions from **red** state to **green** - - * `onbeforego` - specific handler for the **go** event only - * `onbeforeevent` - generic handler for all events - * `onleavered` - specific handler for the **red** state only - * `onleavestate` - generic handler for all states - * `onentergreen` - specific handler for the **green** state only - * `onenterstate` - generic handler for all states - * `onaftergo` - specific handler for the **go** event only - * `onafterevent` - generic handler for all events - -> NOTE: the legacy `onchangestate` handler has been deprecated and will be removed in a future version - -You can affect the event in 3 ways: - - * return `false` from an `onbeforeEVENT` handler to cancel the event. - * return `false` from an `onleaveSTATE` handler to cancel the event. - * return `ASYNC` from an `onleaveSTATE` handler to perform an asynchronous state transition (see next section) - -# Asynchronous State Transitions - -Sometimes, you need to execute some asynchronous code during a state transition and ensure the -new state is not entered until your code has completed. - -A good example of this is when you transition out of a `menu` state, perhaps you want to gradually -fade the menu away, or slide it off the screen and don't want to transition to your `game` state -until after that animation has been performed. - -You can now return `StateMachine.ASYNC` from your `onleavestate` handler and the state machine -will be _'put on hold'_ until you are ready to trigger the transition using the new `transition()` -method. - -For example, using jQuery effects: - - var fsm = StateMachine.create({ - - initial: 'menu', - - events: [ - { name: 'play', from: 'menu', to: 'game' }, - { name: 'quit', from: 'game', to: 'menu' } - ], +Using npm: - callbacks: { +```shell + npm install --save-dev javascript-state-machine +``` - onentermenu: function() { $('#menu').show(); }, - onentergame: function() { $('#game').show(); }, +In Node.js: - onleavemenu: function() { - $('#menu').fadeOut('fast', function() { - fsm.transition(); - }); - return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in fadeOut callback above) - }, +```javascript + var StateMachine = require('javascript-state-machine'); +``` - onleavegame: function() { - $('#game').slideUp('slow', function() { - fsm.transition(); - }; - return StateMachine.ASYNC; // tell StateMachine to defer next state until we call transition (in slideUp callback above) - } +# Usage - } - }); +A state machine can be constructed using: -> NOTE: If you decide to cancel the ASYNC event, you can call `fsm.transition.cancel();` +```javascript + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + methods: { + onMelt: function() { console.log('I melted') }, + onFreeze: function() { console.log('I froze') }, + onVaporize: function() { console.log('I vaporized') }, + onCondense: function() { console.log('I condensed') } + } + }); +``` -# State Machine Classes +... which creates an object with a current state property: -You can also turn all instances of a _class_ into an FSM by applying -the state machine functionality to the prototype, including your callbacks -in your prototype, and providing a `startup` event for use when constructing -instances: + * `fsm.state` - MyFSM = function() { // my constructor function - this.startup(); - }; +... methods to transition to a different state: - MyFSM.prototype = { + * `fsm.melt()` + * `fsm.freeze()` + * `fsm.vaporize()` + * `fsm.condense()` - onpanic: function(event, from, to) { alert('panic'); }, - onclear: function(event, from, to) { alert('all is clear'); }, +... observer methods called automatically during the lifecycle of a transition: - // my other prototype methods + * `onMelt()` + * `onFreeze()` + * `onVaporize()` + * `onCondense()` - }; +... along with the following helper methods: - StateMachine.create({ - target: MyFSM.prototype, - events: [ - { name: 'startup', from: 'none', to: 'green' }, - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); + * `fsm.is(s)` - return true if state `s` is the current state + * `fsm.can(t)` - return true if transition `t` can occur from the current state + * `fsm.cannot(t)` - return true if transition `t` cannot occur from the current state + * `fsm.transitions()` - return list of transitions that are allowed from the current state + * `fsm.allTransitions()` - return list of all possible transitions + * `fsm.allStates()` - return list of all possible states +# Terminology -This should be easy to adjust to fit your appropriate mechanism for object construction. +A state machine consists of a set of [**States**](docs/states-and-transitions.md) -> NOTE: the `startup` event can be given any name, but it must be present in some form to - ensure that each instance constructed is initialized with its own unique `current` state. + * solid + * liquid + * gas -# Initialization Options +A state machine changes state by using [**Transitions**](docs/states-and-transitions.md) -How the state machine should initialize can depend on your application requirements, so -the library provides a number of simple options. + * melt + * freeze + * vaporize + * condense -By default, if you don't specify any initial state, the state machine will be in the `'none'` -state and you would need to provide an event to take it out of this state: +A state machine can perform actions during a transition by observing [**Lifecycle Events**](docs/lifecycle-events.md) - var fsm = StateMachine.create({ - events: [ - { name: 'startup', from: 'none', to: 'green' }, - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' }, - ]}); - alert(fsm.current); // "none" - fsm.startup(); - alert(fsm.current); // "green" + * onBeforeMelt + * onAfterMelt + * onLeaveSolid + * onEnterLiquid + * ... -If you specify the name of your initial state (as in all the earlier examples), then an -implicit `startup` event will be created for you and fired when the state machine is constructed. +A state machine can also have arbitrary [**Data and Methods**](docs/data-and-methods.md). - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' }, - ]}); - alert(fsm.current); // "green" +Multiple instances of a state machine can be created using a [**State Machine Factory**](docs/state-machine-factory.md). -If your object already has a `startup` method you can use a different name for the initial event +# Documentation - var fsm = StateMachine.create({ - initial: { state: 'green', event: 'init' }, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' }, - ]}); - alert(fsm.current); // "green" - -Finally, if you want to wait to call the initial state transition event until a later date you -can `defer` it: - - var fsm = StateMachine.create({ - initial: { state: 'green', event: 'init', defer: true }, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' }, - ]}); - alert(fsm.current); // "none" - fsm.init(); - alert(fsm.current); // "green" - -Of course, we have now come full circle, this last example is pretty much functionally the -same as the first example in this section where you simply define your own startup event. - -So you have a number of choices available to you when initializing your state machine. - -> IMPORTANT NOTE: if you are using the pattern described in the previous section "State Machine - Classes", and wish to declare an `initial` state in this manner, you MUST use the `defer: true` - attribute and manually call the starting event in your constructor function. This will ensure - that each instance gets its own unique `current` state, rather than an (unwanted) shared - `current` state on the prototype object itself. - -# Handling Failures - -By default, if you try to call an event method that is not allowed in the current state, the -state machine will throw an exception. If you prefer to handle the problem yourself, you can -define a custom `error` handler: - - var fsm = StateMachine.create({ - initial: 'green', - error: function(eventName, from, to, args, errorCode, errorMessage, originalException) { - return 'event ' + eventName + ' was naughty :- ' + errorMessage; - }, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' }, - ]}); - alert(fsm.calm()); // "event calm was naughty :- event not allowed in current state green" +Read more about + * [States and Transitions](docs/states-and-transitions.md) + * [Data and Methods](docs/data-and-methods.md) + * [Lifecycle Events](docs/lifecycle-events.md) + * [Asynchronous Transitions](docs/async-transitions.md) + * [Initialization](docs/initialization.md) + * [Error Handling](docs/error-handling.md) + * [State History](docs/state-history.md) + * [Visualization](docs/visualization.md) + * [State Machine Factory](docs/state-machine-factory.md) + * [Upgrading from 2.x](docs/upgrading-from-v2.md) + # Contributing - > git clone git@github.com:jakesgordon/javascript-state-machine - > cd javascript-state-machine - - > npm install # install dev dependencies - > npm start # run a local dev server - - * Source code - `state-machine.js` - * Minified code - `state-machine.min.js` (build with `npm run minify`) - * Browse demo at `/` - * Run tests in browser at `/test/` - * Run tests in console with `npm test` - * Please include tests with pull requests. - -# Related Links +You can [Contribute](docs/contributing.md) to this project with issues or pull requests. - * You can find the [code on github](https://github.com/jakesgordon/javascript-state-machine) - * You can find a [working demo here](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/) - * [v2.3 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-3-0/) - * [v2.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-2-0/) - * [v2.1 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2-1-0/) - * [v2.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v2) - * [v1.2 release announcement](http://codeincomplete.com/posts/javascript-state-machine-v1-2-0) - * [v1.0 release announcement](http://codeincomplete.com/posts/javascript-state-machine) +You might also want to support this project by purchasing a [commercial license](docs/commercial-license.md). # Release Notes -See [RELEASE NOTES](https://github.com/jakesgordon/javascript-state-machine/blob/master/RELEASE_NOTES.md) file. +See [RELEASE NOTES](RELEASE_NOTES.md) file. # License -See [LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE) file. +Dual-licensed under the [LGPL](http://www.gnu.org/licenses/lgpl-3.0.html) for the open source community and also available with support +under a [commercial license](docs/commercial-license.md). # Contact diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c0aba13..ca0b628 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,17 +1,24 @@ +Version 3.0.0 (ETA - January 2017) +---------------------------------- - FUTURE Version 3.0.0 (ETA - Early 2017) - ------------------------------ +**IMPORTANT NOTE**: this version includes **breaking changes** that will require code updates. - I know, I know, I've neglected this library for far too long, so lets get it back on track... +Please read [UPGRADING FROM 2.x](docs/upgrading-from-v2.md) for details. Highlights include: + + * Improved Construction. + * Arbitrary Data and Methods. + * Observable Transitions + * Conditional Transitions + * Promise-based Asynchronous Transitions + * Improved Transition Lifecycle Events + * State History + * Visualization + * Webpack build system + * ... + +
+
- ADD: Promise based async transitions - ADD: conditional transitions - ADD: observable transitions - ADD: composable state machines - ADD: better introspection - ADD: undo/redo history - ADD: use camel casing for callback/observer methods (instead of all lower case) - Version 2.4.0 (November 20 2016) -------------------------------- diff --git a/bin/examples b/bin/examples new file mode 100755 index 0000000..e726661 --- /dev/null +++ b/bin/examples @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +//================================================================================================= +// +// This script is used to regenerate the example visualizations +// +//================================================================================================= + +var fs = require('fs'), + path = require('path'), + child = require('child_process'); + +//------------------------------------------------------------------------------------------------- + +fs.readdirSync('examples') + .filter(function(file) { return path.extname(file) === ".js" }) + .map(visualize); + +//------------------------------------------------------------------------------------------------- + +function visualize(example) { + var name = path.basename(example, '.js'), + fsm = require('../examples/' + example), + dot = fsm.visualize(), + svg = dot2svg(dot), + png = dot2png(dot); + console.log('visualizing examples/' + example); + fs.writeFileSync('examples/' + name + '.dot', dot); + fs.writeFileSync('examples/' + name + '.svg', svg); + fs.writeFileSync('examples/' + name + '.png', png, 'binary'); +} + +//------------------------------------------------------------------------------------------------- + +function dot2svg(dot) { + var result = child.spawnSync("dot", ["-Tsvg"], { input: dot }); + if (result.error) + dotError(result.error.errno); + return result.stdout.toString(); +} + +//------------------------------------------------------------------------------------------------- + +function dot2png(dot) { + var result = child.spawnSync("dot", ["-Tpng"], { input: dot }); + if (result.error) + dotError(result.error.errno); + return result.stdout; +} + +//------------------------------------------------------------------------------------------------- + +function dotError(errno) { + if (errno === 'ENOENT') + throw new Error("dot program not found. Install graphviz (http://graphviz.org)") + else + throw new Error("unexpected error: " + errno) +} + +//------------------------------------------------------------------------------------------------- diff --git a/bin/minify b/bin/minify new file mode 100755 index 0000000..88fe76c --- /dev/null +++ b/bin/minify @@ -0,0 +1,40 @@ +#!/usr/bin/env node + +//================================================================================================= +// +// This script is used (by npm run build) to minify the distributed source code +// +//================================================================================================= + +var fs = require('fs-sync'), + path = require('path'), + uglify = require('uglify-js'), + target = 'dist'; + +//------------------------------------------------------------------------------------------------- + +fs.expand("lib/**/*.js") + .map(minify); + +//------------------------------------------------------------------------------------------------- + +function minify(file) { + var name = output_name(file), + expanded = path.join(target, name + '.js'), + minified = path.join(target, name + '.min.js') + + console.log('copied ' + file + ' to ' + expanded + ' and minified as ' + minified); + + fs.copy(file, expanded, { force: true }); + fs.write(minified, uglify.minify(expanded).code); +} + +function output_name(file) { + var name = path.basename(file, '.js'); + if (name === 'state-machine') + return 'state-machine' + else + return 'state-machine-' + name +} + +//------------------------------------------------------------------------------------------------- diff --git a/bower.json b/bower.json deleted file mode 100644 index 7f1f489..0000000 --- a/bower.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "javascript-state-machine", - "homepage": "https://github.com/jakesgordon/javascript-state-machine", - "authors": [ - "Jake Gordon " - ], - "description": "a simple finite state machine library", - "main": ["state-machine.js", "state-machine.min.js"], - "moduleType": [ - "amd", - "globals", - "node" - ], - "keywords": [ - "state machine", - "server", - "client" - ], - "license": "MIT", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "demo", - "index.html", - ".gitignore" - ] -} diff --git a/demo/demo.js b/demo/demo.js deleted file mode 100644 index 4789c85..0000000 --- a/demo/demo.js +++ /dev/null @@ -1,78 +0,0 @@ -Demo = function() { - - var output = document.getElementById('output'), - demo = document.getElementById('demo'), - panic = document.getElementById('panic'), - warn = document.getElementById('warn'), - calm = document.getElementById('calm'), - clear = document.getElementById('clear'), - count = 0; - - var log = function(msg, separate) { - count = count + (separate ? 1 : 0); - output.value = count + ": " + msg + "\n" + (separate ? "\n" : "") + output.value; - demo.className = fsm.current; - panic.disabled = fsm.cannot('panic'); - warn.disabled = fsm.cannot('warn'); - calm.disabled = fsm.cannot('calm'); - clear.disabled = fsm.cannot('clear'); - }; - - var fsm = StateMachine.create({ - - events: [ - { name: 'start', from: 'none', to: 'green' }, - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'green', to: 'red' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'red', to: 'green' }, - { name: 'clear', from: 'yellow', to: 'green' }, - ], - - callbacks: { - onbeforestart: function(event, from, to) { log("STARTING UP"); }, - onstart: function(event, from, to) { log("READY"); }, - - onbeforewarn: function(event, from, to) { log("START EVENT: warn!", true); }, - onbeforepanic: function(event, from, to) { log("START EVENT: panic!", true); }, - onbeforecalm: function(event, from, to) { log("START EVENT: calm!", true); }, - onbeforeclear: function(event, from, to) { log("START EVENT: clear!", true); }, - - onwarn: function(event, from, to) { log("FINISH EVENT: warn!"); }, - onpanic: function(event, from, to) { log("FINISH EVENT: panic!"); }, - oncalm: function(event, from, to) { log("FINISH EVENT: calm!"); }, - onclear: function(event, from, to) { log("FINISH EVENT: clear!"); }, - - onleavegreen: function(event, from, to) { log("LEAVE STATE: green"); }, - onleaveyellow: function(event, from, to) { log("LEAVE STATE: yellow"); }, - onleavered: function(event, from, to) { log("LEAVE STATE: red"); async(to); return StateMachine.ASYNC; }, - - ongreen: function(event, from, to) { log("ENTER STATE: green"); }, - onyellow: function(event, from, to) { log("ENTER STATE: yellow"); }, - onred: function(event, from, to) { log("ENTER STATE: red"); }, - - onchangestate: function(event, from, to) { log("CHANGED STATE: " + from + " to " + to); } - } - }); - - var async = function(to) { - pending(to, 3); - setTimeout(function() { - pending(to, 2); - setTimeout(function() { - pending(to, 1); - setTimeout(function() { - fsm.transition(); // trigger deferred state transition - }, 1000); - }, 1000); - }, 1000); - }; - - var pending = function(to, n) { log("PENDING STATE: " + to + " in ..." + n); }; - - fsm.start(); - return fsm; - -}(); - diff --git a/dist/state-machine-history.js b/dist/state-machine-history.js new file mode 100644 index 0000000..d604994 --- /dev/null +++ b/dist/state-machine-history.js @@ -0,0 +1,187 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachineHistory", [], factory); + else if(typeof exports === 'object') + exports["StateMachineHistory"] = factory(); + else + root["StateMachineHistory"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(label) { + var n, word, words = label.split(/[_-]/), result = words[0]; + for(n = 1 ; n < words.length ; n++) { + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + } + return result; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var camelize = __webpack_require__(0); + +//------------------------------------------------------------------------------------------------- + +module.exports = function(options) { options = options || {}; + + var past = camelize(options.name || options.past || 'history'), + future = camelize( options.future || 'future'), + clear = camelize('clear-' + past), + back = camelize(past + '-back'), + forward = camelize(past + '-forward'), + canBack = camelize('can-' + back), + canForward = camelize('can-' + forward), + max = options.max; + + var plugin = { + + configure: function(config) { + config.addTransitionLifecycleNames(back); + config.addTransitionLifecycleNames(forward); + }, + + init: function(instance) { + instance[past] = []; + instance[future] = []; + }, + + lifecycle: function(instance, lifecycle) { + if (lifecycle.event === 'onEnterState') { + instance[past].push(lifecycle.to); + if (max && instance[past].length > max) + instance[past].shift(); + if (lifecycle.transition !== back && lifecycle.transition !== forward) + instance[future].length = 0; + } + }, + + methods: {}, + properties: {} + + } + + plugin.methods[clear] = function() { + this[past].length = 0 + this[future].length = 0 + } + + plugin.properties[canBack] = { + get: function() { + return this[past].length > 1 + } + } + + plugin.properties[canForward] = { + get: function() { + return this[future].length > 0 + } + } + + plugin.methods[back] = function() { + if (!this[canBack]) + throw Error('no history'); + var from = this[past].pop(), + to = this[past].pop(); + this[future].push(from); + this._fsm.transit(back, from, to, []); + } + + plugin.methods[forward] = function() { + if (!this[canForward]) + throw Error('no history'); + var from = this.state, + to = this[future].pop(); + this._fsm.transit(forward, from, to, []); + } + + return plugin; + +} + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/dist/state-machine-history.min.js b/dist/state-machine-history.min.js new file mode 100644 index 0000000..c186024 --- /dev/null +++ b/dist/state-machine-history.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("StateMachineHistory",[],e):"object"==typeof exports?exports.StateMachineHistory=e():t.StateMachineHistory=e()}(this,function(){return 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.i=function(t){return t},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=1)}([function(t,e,n){"use strict";t.exports=function(t){var e,n=t.split(/[_-]/),r=n[0];for(e=1;ef&&t[e].shift(),r.transition!==i&&r.transition!==s&&(t[n].length=0))},methods:{},properties:{}};return a.methods[o]=function(){this[e].length=0,this[n].length=0},a.properties[u]={get:function(){return this[e].length>1}},a.properties[c]={get:function(){return this[n].length>0}},a.methods[i]=function(){if(!this[u])throw Error("no history");var t=this[e].pop(),r=this[e].pop();this[n].push(t),this._fsm.transit(i,t,r,[])},a.methods[s]=function(){if(!this[c])throw Error("no history");var t=this.state,e=this[n].pop();this._fsm.transit(s,t,e,[])},a}}])}); \ No newline at end of file diff --git a/dist/state-machine-visualize.js b/dist/state-machine-visualize.js new file mode 100644 index 0000000..531bf03 --- /dev/null +++ b/dist/state-machine-visualize.js @@ -0,0 +1,269 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachineVisualize", [], factory); + else if(typeof exports === 'object') + exports["StateMachineVisualize"] = factory(); + else + root["StateMachineVisualize"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(target, sources) { + var n, source, key; + for(n = 1 ; n < arguments.length ; n++) { + source = arguments[n]; + for(key in source) { + if (source.hasOwnProperty(key)) + target[key] = source[key]; + } + } + return target; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0) + +//------------------------------------------------------------------------------------------------- + +function visualize(fsm, options) { + return dotify(dotcfg(fsm, options)); +} + +//------------------------------------------------------------------------------------------------- + +function dotcfg(fsm, options) { + + options = options || {} + + var config = dotcfg.fetch(fsm), + name = options.name, + rankdir = dotcfg.rankdir(options.orientation), + states = dotcfg.states(config, options), + transitions = dotcfg.transitions(config, options), + result = { } + + if (name) + result.name = name + + if (rankdir) + result.rankdir = rankdir + + if (states && states.length > 0) + result.states = states + + if (transitions && transitions.length > 0) + result.transitions = transitions + + return result +} + +//------------------------------------------------------------------------------------------------- + +dotcfg.fetch = function(fsm) { + return (typeof fsm === 'function') ? fsm.prototype._fsm.config + : fsm._fsm.config +} + +dotcfg.rankdir = function(orientation) { + if (orientation === 'horizontal') + return 'LR'; + else if (orientation === 'vertical') + return 'TB'; +} + +dotcfg.states = function(config, options) { + var index, states = config.states; + if (!options.init) { // if not showing init transition, then slice out the implied init :from state + index = states.indexOf(config.init.from); + states = states.slice(0, index).concat(states.slice(index+1)); + } + return states; +} + +dotcfg.transitions = function(config, options) { + var n, max, transition, + init = config.init, + transitions = config.source.transitions || [], // easier to visualize using the ORIGINAL transition declarations rather than our run-time mapping + output = []; + if (options.init && init.active) + dotcfg.transition(init.name, init.from, init.to, init.dot, config, options, output) + for (n = 0, max = transitions.length ; n < max ; n++) { + transition = config.source.transitions[n] + dotcfg.transition(transition.name, transition.from, transition.to, transition.dot, config, options, output) + } + return output +} + +dotcfg.transition = function(name, from, to, dot, config, options, output) { + var n, max, wildcard = config.defaults.wildcard + + if (Array.isArray(from)) { + for(n = 0, max = from.length ; n < max ; n++) + dotcfg.transition(name, from[n], to, dot, config, options, output) + } + else if (from === wildcard || from === undefined) { + for(n = 0, max = config.states.length ; n < max ; n++) + dotcfg.transition(name, config.states[n], to, dot, config, options, output) + } + else if (to === wildcard || to === undefined) { + dotcfg.transition(name, from, from, dot, config, options, output) + } + else if (typeof to === 'function') { + // do nothing, can't display conditional transition + } + else { + output.push(mixin({}, { from: from, to: to, label: pad(name) }, dot || {})) + } + +} + +//------------------------------------------------------------------------------------------------- + +function pad(name) { + return " " + name + " " +} + +function quote(name) { + return "\"" + name + "\"" +} + +function dotify(dotcfg) { + + dotcfg = dotcfg || {}; + + var name = dotcfg.name || 'fsm', + states = dotcfg.states || [], + transitions = dotcfg.transitions || [], + rankdir = dotcfg.rankdir, + output = [], + n, max; + + output.push("digraph " + quote(name) + " {") + if (rankdir) + output.push(" rankdir=" + rankdir + ";") + for(n = 0, max = states.length ; n < max ; n++) + output.push(dotify.state(states[n])) + for(n = 0, max = transitions.length ; n < max ; n++) + output.push(dotify.edge(transitions[n])) + output.push("}") + return output.join("\n") + +} + +dotify.state = function(state) { + return " " + quote(state) + ";" +} + +dotify.edge = function(edge) { + return " " + quote(edge.from) + " -> " + quote(edge.to) + dotify.edge.attr(edge) + ";" +} + +dotify.edge.attr = function(edge) { + var n, max, key, keys = Object.keys(edge).sort(), output = []; + for(n = 0, max = keys.length ; n < max ; n++) { + key = keys[n]; + if (key !== 'from' && key !== 'to') + output.push(key + "=" + quote(edge[key])) + } + return output.length > 0 ? " [ " + output.join(" ; ") + " ]" : "" +} + +//------------------------------------------------------------------------------------------------- + +visualize.dotcfg = dotcfg; +visualize.dotify = dotify; + +//------------------------------------------------------------------------------------------------- + +module.exports = visualize; + +//------------------------------------------------------------------------------------------------- + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/dist/state-machine-visualize.min.js b/dist/state-machine-visualize.min.js new file mode 100644 index 0000000..28a9d5a --- /dev/null +++ b/dist/state-machine-visualize.min.js @@ -0,0 +1 @@ +!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachineVisualize",[],n):"object"==typeof exports?exports.StateMachineVisualize=n():t.StateMachineVisualize=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=1)}([function(t,n,e){"use strict";t.exports=function(t,n){var e,r,o;for(e=1;e0&&(u.states=s),a&&a.length>0&&(u.transitions=a),u}function i(t){return" "+t+" "}function s(t){return'"'+t+'"'}function a(t){t=t||{};var n,e,r=t.name||"fsm",o=t.states||[],i=t.transitions||[],u=t.rankdir,f=[];for(f.push("digraph "+s(r)+" {"),u&&f.push(" rankdir="+u+";"),n=0,e=o.length;n "+s(t.to)+a.edge.attr(t)+";"},a.edge.attr=function(t){var n,e,r,o=Object.keys(t).sort(),i=[];for(n=0,e=o.length;n0?" [ "+i.join(" ; ")+" ]":""},r.dotcfg=o,r.dotify=a,t.exports=r}])}); \ No newline at end of file diff --git a/dist/state-machine.js b/dist/state-machine.js new file mode 100644 index 0000000..6ac51b3 --- /dev/null +++ b/dist/state-machine.js @@ -0,0 +1,644 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachine", [], factory); + else if(typeof exports === 'object') + exports["StateMachine"] = factory(); + else + root["StateMachine"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 6); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(target, sources) { + var n, source, key; + for(n = 1 ; n < arguments.length ; n++) { + source = arguments[n]; + for(key in source) { + if (source.hasOwnProperty(key)) + target[key] = source[key]; + } + } + return target; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0); + +//------------------------------------------------------------------------------------------------- + +module.exports = { + + build: function(target, config) { + var n, max, plugin, plugins = config.plugins; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (plugin.methods) + mixin(target, plugin.methods); + if (plugin.properties) + Object.defineProperties(target, plugin.properties); + } + }, + + hook: function(fsm, name, additional) { + var n, max, method, plugin, + plugins = fsm.config.plugins, + args = [fsm.context]; + + if (additional) + args = args.concat(additional) + + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n] + method = plugins[n][name] + if (method) + method.apply(plugin, args); + } + } + +} + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(label) { + var n, word, words = label.split(/[_-]/), result = words[0]; + for(n = 1 ; n < words.length ; n++) { + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + } + return result; +} + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0), + camelize = __webpack_require__(2); + +//------------------------------------------------------------------------------------------------- + +function Config(options, StateMachine) { + + options = options || {}; + + this.source = options; // preserving original options helps with visualize plugin + this.defaults = StateMachine.defaults; + this.states = []; + this.transitions = []; + this.map = {}; + this.lifecycle = this.configureLifecycle(); + this.init = this.configureInitTransition(options.init); + this.data = this.configureData(options.data); + this.methods = this.configureMethods(options.methods); + + this.map[this.defaults.wildcard] = {}; + + this.configureTransitions(options.transitions || []); + + this.plugins = this.configurePlugins(options.plugins, StateMachine.plugin); + +} + +//------------------------------------------------------------------------------------------------- + +mixin(Config.prototype, { + + addState: function(name) { + if (!this.map[name]) { + this.states.push(name); + this.addStateLifecycleNames(name); + this.map[name] = {}; + } + }, + + addStateLifecycleNames: function(name) { + this.lifecycle.onEnter[name] = camelize('on-enter-' + name); + this.lifecycle.onLeave[name] = camelize('on-leave-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + addTransition: function(name) { + if (this.transitions.indexOf(name) < 0) { + this.transitions.push(name); + this.addTransitionLifecycleNames(name); + } + }, + + addTransitionLifecycleNames: function(name) { + this.lifecycle.onBefore[name] = camelize('on-before-' + name); + this.lifecycle.onAfter[name] = camelize('on-after-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + mapTransition: function(transition) { + var name = transition.name, + from = transition.from, + to = transition.to; + this.addState(from); + if (typeof to !== 'function') + this.addState(to); + this.addTransition(name); + this.map[from][name] = transition; + return transition; + }, + + configureLifecycle: function() { + return { + onBefore: { transition: camelize('on-before-transition') }, + onAfter: { transition: camelize('on-after-transition') }, + onEnter: { state: camelize('on-enter-state') }, + onLeave: { state: camelize('on-leave-state') }, + on: { transition: camelize('on-transition') } + }; + }, + + configureInitTransition: function(init) { + if (typeof init === 'string') { + return this.mapTransition(mixin({}, this.defaults.init, { to: init, active: true })); + } + else if (typeof init === 'object') { + return this.mapTransition(mixin({}, this.defaults.init, init, { active: true })); + } + else { + this.addState(this.defaults.init.from); + return this.defaults.init; + } + }, + + configureData: function(data) { + if (typeof data === 'function') + return data; + else if (typeof data === 'object') + return function() { return data; } + else + return function() { return {}; } + }, + + configureMethods: function(methods) { + return methods || {}; + }, + + configurePlugins: function(plugins, builtin) { + plugins = plugins || []; + var n, max, plugin; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (typeof plugin === 'function') + plugins[n] = plugin = plugin() + if (plugin.configure) + plugin.configure(this); + } + return plugins + }, + + configureTransitions: function(transitions) { + var i, n, transition, from, to, wildcard = this.defaults.wildcard; + for(n = 0 ; n < transitions.length ; n++) { + transition = transitions[n]; + from = Array.isArray(transition.from) ? transition.from : [transition.from || wildcard] + to = transition.to || wildcard; + for(i = 0 ; i < from.length ; i++) { + this.mapTransition({ name: transition.name, from: from[i], to: to }); + } + } + }, + + transitionFor: function(state, transition) { + var wildcard = this.defaults.wildcard; + return this.map[state][transition] || + this.map[wildcard][transition]; + }, + + transitionsFor: function(state) { + var wildcard = this.defaults.wildcard; + return Object.keys(this.map[state]).concat(Object.keys(this.map[wildcard])); + }, + + allStates: function() { + return this.states; + }, + + allTransitions: function() { + return this.transitions; + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = Config; + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + +var mixin = __webpack_require__(0), + Exception = __webpack_require__(5), + plugin = __webpack_require__(1), + UNOBSERVED = [ null, [] ]; + +//------------------------------------------------------------------------------------------------- + +function JSM(context, config) { + this.context = context; + this.config = config; + this.state = config.init.from; + this.observers = [context]; +} + +//------------------------------------------------------------------------------------------------- + +mixin(JSM.prototype, { + + init: function(args) { + mixin(this.context, this.config.data.apply(this.context, args)); + plugin.hook(this, 'init'); + if (this.config.init.active) + return this.fire(this.config.init.name, []); + }, + + is: function(state) { + return Array.isArray(state) ? (state.indexOf(this.state) >= 0) : (this.state === state); + }, + + isPending: function() { + return this.pending; + }, + + can: function(transition) { + return !this.isPending() && !!this.seek(transition); + }, + + cannot: function(transition) { + return !this.can(transition); + }, + + allStates: function() { + return this.config.allStates(); + }, + + allTransitions: function() { + return this.config.allTransitions(); + }, + + transitions: function() { + return this.config.transitionsFor(this.state); + }, + + seek: function(transition, args) { + var wildcard = this.config.defaults.wildcard, + entry = this.config.transitionFor(this.state, transition), + to = entry && entry.to; + if (typeof to === 'function') + return to.apply(this.context, args); + else if (to === wildcard) + return this.state + else + return to + }, + + fire: function(transition, args) { + return this.transit(transition, this.state, this.seek(transition, args), args); + }, + + transit: function(transition, from, to, args) { + + var lifecycle = this.config.lifecycle, + changed = from !== to; + + if (!to) + return this.context.onInvalidTransition(transition, from, to); + + if (this.isPending()) + return this.context.onPendingTransition(transition, from, to); + + this.config.addState(to); // might need to add this state if it's unknown (e.g. conditional transition or goto) + + this.beginTransit(); + + args.unshift({ // this context will be passed to each lifecycle event observer + transition: transition, + from: from, + to: to, + fsm: this.context + }); + + return this.observeEvents([ + this.observersForEvent(lifecycle.onBefore.transition), + this.observersForEvent(lifecycle.onBefore[transition]), + changed ? this.observersForEvent(lifecycle.onLeave.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onLeave[from]) : UNOBSERVED, + this.observersForEvent(lifecycle.on.transition), + changed ? [ 'doTransit', [ this ] ] : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter[to]) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.on[to]) : UNOBSERVED, + this.observersForEvent(lifecycle.onAfter.transition), + this.observersForEvent(lifecycle.onAfter[transition]), + this.observersForEvent(lifecycle.on[transition]) + ], args); + }, + + beginTransit: function() { this.pending = true; }, + endTransit: function(result) { this.pending = false; return result; }, + doTransit: function(lifecycle) { this.state = lifecycle.to; }, + + observe: function(args) { + if (args.length === 2) { + var observer = {}; + observer[args[0]] = args[1]; + this.observers.push(observer); + } + else { + this.observers.push(args[0]); + } + }, + + observersForEvent: function(event) { // TODO: this could be cached + var n = 0, max = this.observers.length, observer, result = []; + for( ; n < max ; n++) { + observer = this.observers[n]; + if (observer[event]) + result.push(observer); + } + return [ event, result, true ] + }, + + observeEvents: function(events, args, previousEvent) { + if (events.length === 0) { + return this.endTransit(true); + } + + var event = events[0][0], + observers = events[0][1], + pluggable = events[0][2]; + + args[0].event = event; + if (event && pluggable && event !== previousEvent) + plugin.hook(this, 'lifecycle', args); + + if (observers.length === 0) { + events.shift(); + return this.observeEvents(events, args, event); + } + else { + var observer = observers.shift(), + result = observer[event].apply(observer, args); + if (result && typeof result.then === 'function') { + return result.then(this.observeEvents.bind(this, events, args, event)) + .catch(this.endTransit.bind(this)) + } + else if (result === false) { + return this.endTransit(false); + } + else { + return this.observeEvents(events, args, event); + } + } + }, + + onInvalidTransition: function(transition, from, to) { + throw new Exception("transition is invalid in current state", transition, from, to, this.state); + }, + + onPendingTransition: function(transition, from, to) { + throw new Exception("transition is invalid while previous transition is still in progress", transition, from, to, this.state); + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = JSM; + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(message, transition, from, to, current) { + this.message = message; + this.transition = transition; + this.from = from; + this.to = to; + this.current = current; +} + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//----------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0), + camelize = __webpack_require__(2), + plugin = __webpack_require__(1), + Config = __webpack_require__(3), + JSM = __webpack_require__(4); + +//----------------------------------------------------------------------------------------------- + +var PublicMethods = { + is: function(state) { return this._fsm.is(state) }, + can: function(transition) { return this._fsm.can(transition) }, + cannot: function(transition) { return this._fsm.cannot(transition) }, + observe: function() { return this._fsm.observe(arguments) }, + transitions: function() { return this._fsm.transitions() }, + allTransitions: function() { return this._fsm.allTransitions() }, + allStates: function() { return this._fsm.allStates() }, + onInvalidTransition: function(t, from, to) { return this._fsm.onInvalidTransition(t, from, to) }, + onPendingTransition: function(t, from, to) { return this._fsm.onPendingTransition(t, from, to) }, +} + +var PublicProperties = { + state: { + configurable: false, + enumerable: true, + get: function() { + return this._fsm.state; + }, + set: function(state) { + throw Error('use transitions to change state') + } + } +} + +//----------------------------------------------------------------------------------------------- + +function StateMachine(options) { + return apply(this || {}, options); +} + +function factory() { + var cstor, options; + if (typeof arguments[0] === 'function') { + cstor = arguments[0]; + options = arguments[1] || {}; + } + else { + cstor = function() { this._fsm.apply(this, arguments) }; + options = arguments[0] || {}; + } + var config = new Config(options, StateMachine); + build(cstor.prototype, config); + cstor.prototype._fsm.config = config; // convenience access to shared config without needing an instance + return cstor; +} + +//------------------------------------------------------------------------------------------------- + +function apply(instance, options) { + var config = new Config(options, StateMachine); + build(instance, config); + instance._fsm(); + return instance; +} + +function build(target, config) { + if ((typeof target !== 'object') || Array.isArray(target)) + throw Error('StateMachine can only be applied to objects'); + plugin.build(target, config); + Object.defineProperties(target, PublicProperties); + mixin(target, PublicMethods); + mixin(target, config.methods); + config.allTransitions().forEach(function(transition) { + target[camelize(transition)] = function() { + return this._fsm.fire(transition, [].slice.call(arguments)) + } + }); + target._fsm = function() { + this._fsm = new JSM(this, config); + this._fsm.init(arguments); + } +} + +//----------------------------------------------------------------------------------------------- + +StateMachine.version = '3.0.0'; +StateMachine.factory = factory; +StateMachine.apply = apply; +StateMachine.defaults = { + wildcard: '*', + init: { + name: 'init', + from: 'none' + } +} + +//=============================================================================================== + +module.exports = StateMachine; + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/dist/state-machine.min.js b/dist/state-machine.min.js new file mode 100644 index 0000000..ddf671a --- /dev/null +++ b/dist/state-machine.min.js @@ -0,0 +1 @@ +!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachine",[],n):"object"==typeof exports?exports.StateMachine=n():t.StateMachine=n()}(this,function(){return function(t){function n(e){if(i[e])return i[e].exports;var s=i[e]={i:e,l:!1,exports:{}};return t[e].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var i={};return n.m=t,n.c=i,n.i=function(t){return t},n.d=function(t,i,e){n.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(i,"a",i),i},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=6)}([function(t,n,i){"use strict";t.exports=function(t,n){var i,e,s;for(i=1;i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i You should be familiar with the state machine [Lifecycle Events](lifecycle-events.md) before reading this article. + +Sometimes, you need to execute some asynchronous code during a state transition and ensure the new +state is not entered until your code has completed. A good example of this is when you transition +out of a state and want to gradually fade a UI component away, or slide it off the screen, and +don't want to transition to the next state until after that animation has completed. + +You can achieve this by returning a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) +object from any of the [Lifecycle Events](lifecycle-events.md). + +Returning a Promise from a lifecycle event will cause the lifecycle for that transition to +pause. It can be continued by resolving the promise, or cancelled by rejecting the promise. + +For example (using jQuery effects): + +```javascript + var fsm = new StateMachine({ + + init: 'menu', + + transitions: [ + { name: 'play', from: 'menu', to: 'game' }, + { name: 'quit', from: 'game', to: 'menu' } + ], + + methods: { + + onEnterMenu: function() { + return new Promise(function(resolve, reject) { + $('#menu').fadeIn('fast', resolve) + }) + }, + + onEnterGame: function() { + return new Promise(function(resolve, reject) { + $('#game').fadeIn('fast', resolve) + }) + }, + + onLeaveMenu: function() { + return new Promise(function(resolve, reject) { + $('#menu').fadeOut('fast', resolve) + }) + }, + + onLeaveGame: function() { + return new Promise(function(resolve, reject) { + $('#game').fadeOut('fast', resolve) + }) + } + } + + }) +``` + +> Be sure that you always resolve (or reject) your Promise eventually, otherwise the state + machine will be stuck forever within that pending transition. diff --git a/docs/commercial-license.md b/docs/commercial-license.md new file mode 100644 index 0000000..af8b6cd --- /dev/null +++ b/docs/commercial-license.md @@ -0,0 +1,180 @@ +# Javascript State Machine Commercial License + +All `javascript-state-machine` features are available in both the open source and the commercially +licensed versions. The commercial license allows for commercial use and provides priority support. + +| | Open Source | | Commercial License | +|--------------------------|---------------|---|-----------------------------| +| All Existing v2 Features | ✔ | | ✔ | +| Promise-based Async | ✔ | | ✔ | +| Observable Transitions | ✔ | | ✔ | +| Conditional Transitions | ✔ | | ✔ | +| State History | ✔ | | ✔ | +| Support | Github Issues | | **Priority Email (1 year)** | +| License | LGPL | | **Commercial** | +| Price | Free | | **$149** | + +## PURCHASE NOW + +A commercial license purchasing page will be available soon. + +Please email [jake@codeincomplete.com](mailto:jake@codeincomplete.com) for more details. + +## Commercial License Summary + + * License does not expire + * Commercial use allowed + * Can be used for unlimited projects + * Can modify source-code but cannot distribute modifications (derivative works) + * Email support provided for 1 year (from time of purchase) + +## Commercial License Example + + + Javascript State Machine - Terms and Conditions. + + 1. Preamble. + + This Agreement, signed on [DATE] (hereinafter: Effective Date) governs the relationship + between [COMPANY], a Business Entity, (hereinafter: Licensee) and + Jake Gordon, a private person (hereinafter: Licensor). This Agreement sets the terms, + rights, restrictions and obligations on using Javascript State Machine + (hereinafter: The Software) created and owned by Licensor, as detailed herein + + 2. License Grant. + + Licensor hereby grants Licensee a Personal, Non-assignable & non-transferable, Perpetual, + Commercial, Royalty free, Including the rights to create but not distribute derivative + works, Non-exclusive license, all with accordance with the terms set forth and other legal + restrictions set forth in 3rd party software used while running Software. + + 2.1. Limited: Licensee may use Software for the purpose of: + + 2.1.1. Running Software on Licensee’s Website[s] and Server[s]; + 2.1.2. Allowing 3rd Parties to run Software on Licensee’s Website[s] and Server[s]; + 2.1.3. Publishing Software’s output to Licensee and 3rd Parties; + 2.1.4. Distribute verbatim copies of Software’s output (including compiled binaries); + 2.1.5. Modify Software to suit Licensee’s needs and specifications. + + 2.2. This license is granted perpetually, as long as you do not materially breach it. + 2.3. Binary Restricted: Licensee may sublicense Software as a part of a larger work + containing more than Software, distributed solely in Object or Binary form under a + personal, non-sublicensable, limited license. Such redistribution shall be limited + to unlimited codebases. + 2.4. Non Assignable & Non-Transferable: Licensee may not assign or transfer his rights + and duties under this license. + 2.5. Commercial, Royalty Free: Licensee may use Software for any purpose, including + paid-services, without any royalties + 2.6. Including the Right to Create Derivative Works: Licensee may create derivative works + based on Software, including amending Software’s source code, modifying it, integrating + it into a larger work or removing portions of Software, as long as no distribution of + the derivative works is made + 2.7. With support & maintenance: Licensor shall provide Licensee support and maintenance as follows - + + 1 year (from time of purchase) email support with 48hr response time + + 3. Term & Termination: The Term of this license shall be until terminated. Licensor may + terminate this Agreement, including Licensee’s license in the case where Licensee: + + 3.1. became insolvent or otherwise entered into any liquidation process; or + 3.2. exported The Software to any jurisdiction where licensor may not enforce his + rights under this agreements in; or + 3.3. Licensee was in breach of any of this license's terms and conditions and such + breach was not cured, immediately upon notification; or + 3.4. Licensee in breach of any of the terms of clause 2 to this license; or + 3.5. Licensee otherwise entered into any arrangement which caused Licensor to be + unable to enforce his rights under this License. + + 4. Payment: In consideration of the License granted under clause 2, Licensee shall pay + Licensor a fee, via Credit-Card, PayPal or any other mean which Licensor may deem + adequate. Failure to perform payment shall construe as material breach of this Agreement. + + 5. Upgrades, Updates and Fixes: Licensor may provide Licensee, from time to time, with + Upgrades, Updates or Fixes, as detailed herein and according to his sole discretion. + Licensee hereby warrants to keep The Software up-to-date and install all relevant + updates and fixes, and may, at his sole discretion, purchase upgrades, according to + the rates set by Licensor. Licensor shall provide any update or Fix free of charge; + however, nothing in this Agreement shall require Licensor to provide Updates or Fixes. + + 5.1. Upgrades: for the purpose of this license, an Upgrade shall be a material amendment + in The Software, which contains new features and or major performance improvements + and shall be marked as a new version number. For example, should Licensee purchase + The Software under version 1.X.X, an upgrade shall commence under number 2.0.0. + 5.2. Updates: for the purpose of this license, an update shall be a minor amendment in The + Software, which may contain new features or minor improvements and shall be marked as + a new sub-version number. For example, should Licensee purchase The Software under + version 1.1.X, an upgrade shall commence under number 1.2.0. + 5.3. Fix: for the purpose of this license, a fix shall be a minor amendment in The + Software, intended to remove bugs or alter minor features which impair the The + Software's functionality. A fix shall be marked as a new sub-sub-version number. + For example, should Licensee purchase Software under version 1.1.1, an upgrade + shall commence under number 1.1.2. + + 6. Support: Software is provided with limited support, as detailed in the Software’s SLA + detailed under the License Grant. Licensor shall provide support via electronic mail + and on regular business days and hours. + + 6.1. Bug Notification: Licensee may provide Licensor of details regarding any bug, + defect or failure in The Software promptly and with no delay from such event; + Licensee shall comply with Licensor's request for information regarding bugs, + defects or failures and furnish him with information, screenshots and try to + reproduce such bugs, defects or failures. + 6.2. Feature Request: Licensee may request additional features in Software, provided, + however, that (i) Licensee shall waive any claim or right in such feature should + feature be developed by Licensor; (ii) Licensee shall be prohibited from developing + the feature, or disclose such feature request, or feature, to any 3rd party directly + competing with Licensor or any 3rd party which may be, following the development + of such feature, in direct competition with Licensor; (iii) Licensee warrants that + feature does not infringe any 3rd party patent, trademark, trade-secret or any + other intellectual property right; and (iv) Licensee developed, envisioned or + created the feature solely by himself. + + 7. Liability: To the extent permitted under Law, The Software is provided under an + AS-IS basis. Licensor shall never, and without any limit, be liable for any damage, + cost, expense or any other payment incurred by Licensee as a result of Software’s + actions, failure, bugs and/or any other interaction between The Software and + Licensee’s end-equipment, computers, other software or any 3rd party, end-equipment, + computer or services. Moreover, Licensor shall never be liable for any defect in + source code written by Licensee when relying on The Software or using The Software’s + source code. + + 8. Warranty: + 8.1. Intellectual Property: Licensor hereby warrants that The Software does not violate + or infringe any 3rd party claims in regards to intellectual property, patents and/or + trademarks and that to the best of its knowledge no legal action has been taken + against it for any infringement or violation of any 3rd party intellectual + property rights. + 8.2. No-Warranty: The Software is provided without any warranty; Licensor hereby + disclaims any warranty that The Software shall be error free, without defects + or code which may cause damage to Licensee’s computers or to Licensee, and + that Software shall be functional. Licensee shall be solely liable to any + damage, defect or loss incurred as a result of operating software and undertake + the risks contained in running The Software on License’s Server[s] and Website[s]. + 8.3. Prior Inspection: Licensee hereby states that he inspected The Software thoroughly + and found it satisfactory and adequate to his needs, that it does not interfere + with his regular operation and that it does meet the standards and scope of his + computer systems and architecture. Licensee found that The Software interacts with + his development, website and server environment and that it does not infringe any of + End User License Agreement of any software Licensee may use in performing his + services. Licensee hereby waives any claims regarding The Software's + incompatibility, performance, results and features, and warrants that he + inspected the The Software. + + 9. No Refunds: Licensee warrants that he inspected The Software according to + clause 7(c) and that it is adequate to his needs. Accordingly, as The Software + is intangible goods, Licensee shall not be, ever, entitled to any refund, rebate, + compensation or restitution for any reason whatsoever, even if The Software + contains material flaws. + + 10. Indemnification: Licensee hereby warrants to hold Licensor harmless and indemnify + Licensor for any lawsuit brought against it in regards to Licensee’s use of The + Software in means that violate, breach or otherwise circumvent this license, + Licensor's intellectual property rights or Licensor's title in The Software. + Licensor shall promptly notify Licensee in case of such legal action and request + Licensee’s consent prior to any settlement in relation to such lawsuit or claim. + + 11. Governing Law, Jurisdiction: Licensee hereby agrees not to initiate class-action + lawsuits against Licensor in relation to this license and to compensate Licensor + for any legal fees, cost or attorney fees should any claim brought by Licensee + against Licensor be denied, in part or in full. + diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..01e5e74 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,59 @@ +# Contributing + +The `javascript-state-machine` library is built using: + + * [Webpack 2](https://webpack.js.org/concepts/) - for bundling javascript modules together + * [UglifyJS2](https://github.com/mishoo/UglifyJS2) - for minifying bundled javascript files + * [Ava](https://github.com/avajs/ava) - for testing + +The directory structure includes: + +```shell + /bin # - build scripts + /dist # - minified bundles for distribution + /docs # - documentation + /examples # - example visualizations + /lib # - bundled source code for npm + /src # - source code + /test # - unit tests + + package.json # - npm configuration + webpack.config.js # - webpack configuration + + LICENSE # - the project licensing terms + README.md # - the project readme + RELEASE_NOTES.md # - the project release notes + +``` + +Build time dependencies can be installed using npm: + +```shell + > npm install +``` + +A number of npm scripts are available: + +```shell + > npm run test # run unit tests + > npm run build # bundle and minify files for distribution + > npm run watch # run tests if source files change +``` + +## Source Code + +The source code is written in es5 syntax and should be supported by all [es5 compatible browsers](http://caniuse.com/#feat=es5). +[Babel](https://babeljs.io/) is **NOT** used for this project. Webpack is used to +bundle modules together for distribution. + +## Submitting Pull Requests + +Generally speaking, please raise an issue first and lets discuss the problem and the +proposed solution. The next step would be a pull-request - fantastic and thank you for helping out - but +please try to... + + * ensure the tests pass (`npm test`). + * rebuild distribution files (`npm run build`). + * include tests for your changes. + * include documentation for your changes. + * include a great commit message. diff --git a/docs/data-and-methods.md b/docs/data-and-methods.md new file mode 100644 index 0000000..28aa7a6 --- /dev/null +++ b/docs/data-and-methods.md @@ -0,0 +1,64 @@ +# Data and Methods + +In addition to [States](states-and-transitions.md) and [Transitions](states-and-transitions.md), a state machine can +also contain arbitrary data and methods: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' } + ], + data: { + color: 'red' + }, + methods: { + describe: function() { + console.log('I am ' + this.color); + } + } + }); + + fsm.state; // 'A' + fsm.color; // 'red' + fsm.describe(); // 'I am red' +``` + +## Data and State Machine Factories + +If you are constructing multiple instances from a [State Machine Factory](state-machine-factory.md) then the +`data` object will be shared amongst them. This is almost certainly **NOT** what you want! To +ensure that each instance gets unique data you should use a `data` method instead: + +```javascript + var FSM = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' } + ], + data: function(color) { // <-- use a method that can be called for each instance + return { + color: color + } + }, + methods: { + describe: function() { + console.log('I am ' + this.color); + } + } + }); + + var a = new FSM('red'), + b = new FSM('blue'); + + a.state; // 'A' + b.state; // 'A' + + a.color; // 'red' + b.color; // 'blue' + + a.describe(); // 'I am red' + b.describe(); // 'I am blue' +``` + +> NOTE: that arguments used when constructing each instance are passed thru to the `data` method directly. diff --git a/docs/error-handling.md b/docs/error-handling.md new file mode 100644 index 0000000..c79f14c --- /dev/null +++ b/docs/error-handling.md @@ -0,0 +1,56 @@ +# Error Handling + +## Invalid Transitions + +By default, if you try to fire a transition that is not allowed in the current state, the +state machine will throw an exception. If you prefer to handle the problem yourself, you can +define a custom `onInvalidTransition` handler: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'reset', from: 'B', to: 'A' } + ], + methods: { + onInvalidTransition: function(transition, from, to) { + throw new Exception("transition not allowed from that state"); + } + } + }); + + fsm.state; // 'A' + fsm.can('step'); // true + fsm.can('reset'); // false + + fsm.reset(); // <-- throws "transition not allowed from that state" +``` + +## Pending Transitions + +By default, if you try to fire a transition during a [Lifecycle Event](lifecycle-events.md) for a +pending transition, the state machine will throw an exception. If you prefer to handle the problem +yourself, you can define a custom `onPendingTransition` handler: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' } + ], + methods: { + onLeaveA: function() { + this.step(); // <-- uh oh, trying to transition from within a lifecycle event is not allowed + }, + onPendingTransition: function(transition, from, to) { + throw new Exception("transition already in progress"); + } + } + }); + + fsm.state; // 'A' + fsm.can('step'), // true + fsm.step(); // <-- throws "transition already in progress" +``` diff --git a/docs/initialization.md b/docs/initialization.md new file mode 100644 index 0000000..39151ff --- /dev/null +++ b/docs/initialization.md @@ -0,0 +1,57 @@ +# Initialization Options + +## Explicit Init Transition + +By default, if you don't specify an initial state, the state machine will be in the `none` +state, no lifecycle events will fire during construction, and you will need to provide an +explicit transition to advance out of this state: + +```javascript + var fsm = new StateMachine({ + transitions: [ + { name: 'init', from: 'none', to: 'A' }, + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' } + ] + }); + fsm.state; // 'none' + fsm.init(); // 'init()' transition is fired explicitly + fsm.state; // 'A' +``` + +## Implicit Init Transition + +If you specify the name of your initial state (as in most of the examples in this documentation), +then an implicit `init` transition will be created for you and fired (along with appropriate +lifecycle events) when the state machine is constructed. + +> This is the most common initialization strategy, and the one you should use 90% of the time + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' } + ] + }); // 'init()' transition fires from 'none' to 'A' during construction + fsm.state; // 'A' +``` + +## Initialization and State Machine Factories + +For [State Machine Factories](state-machine-factory.md), the `init` transition +is triggered for each constructed instance. + +```javascript + var FSM = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' } + ] + }); + + var fsm1 = new FSM(), // 'init()' transition fires from 'none' to 'A' for fsm1 + fsm2 = new FSM(); // 'init()' transition fires from 'none' to 'A' for fsm2 +``` diff --git a/docs/lifecycle-events.md b/docs/lifecycle-events.md new file mode 100644 index 0000000..bb3381b --- /dev/null +++ b/docs/lifecycle-events.md @@ -0,0 +1,148 @@ +# Lifecycle Events + +In order to track or perform an action when a transition occurs, five +general-purpose lifecycle events can be observed: + + * `onBeforeTransition` - fired before any transition + * `onLeaveState` - fired when leaving any state + * `onTransition` - fired during any transition + * `onEnterState` - fired when entering any state + * `onAfterTransition` - fired after any transition + +In addition to the general-purpose events, transitions can be observed +using your specific transition and state names: + + * `onBefore` - fired before a specific TRANSITION begins + * `onLeave` - fired when leaving a specific STATE + * `onEnter` - fired when entering a specific STATE + * `onAfter` - fired after a specific TRANSITION completes + +For convenience, the 2 most useful events can be shortened: + + * `on` - convenience shorthand for `onAfter` + * `on` - convenience shorthand for `onEnter` + +## Observing Lifecycle Events + +Individual lifecycle events can be observed using an observer method: + +```javascript + fsm.observe('onStep', function() { + console.log('stepped'); + }); +``` + +Multiple events can be observed using an observer object: + +```javascript + fsm.observe({ + onStep: function() { console.log('stepped'); } + onA: function() { console.log('entered state A'); } + onB: function() { console.log('entered state B'); } + }); +``` + +A state machine always observes its own lifecycle events: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' } + ], + methods: { + onStep: function() { console.log('stepped'); } + onA: function() { console.log('entered state A'); } + onB: function() { console.log('entered state B'); } + } + }); +``` + +## Lifecycle Event Arguments + +Observers will be passed a single argument containing a `lifecycle` object with the following attributes: + + * **transition** - the transition name + * **from** - the previous state + * **to** - the next state + +In addition to the `lifecycle` argument, the observer will receive any arbitrary arguments passed +into the transition method + +```javascript + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'A', to: 'B' } + ], + methods: { + onTransition: function(lifecycle, arg1, arg2) { + console.log(lifecycle.transition); // 'step' + console.log(lifecycle.from); // 'A' + console.log(lifecycle.to); // 'B' + console.log(arg1); // 42 + console.log(arg2); // 'hello' + } + } + }); + + fsm.step(42, 'hello'); +``` + +## Lifecycle Event Names + +Lifecycle event names always use standard javascipt camelCase, even if your transition and +state names do not: + +```javascript + var fsm = new StateMachine({ + transitions: [ + { name: 'do-with-dash', from: 'has-dash', to: 'has_underscore' }, + { name: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized' }, + { name: 'doAlreadyCamelized', from: 'alreadyCamelize', to: 'has-dash' } + ], + methods: { + onBeforeDoWithDash: function() { /* ... */ }, + onBeforeDoWithUnderscore: function() { /* ... */ }, + onBeforeDoAlreadyCamelized: function() { /* ... */ }, + onLeaveHasDash: function() { /* ... */ }, + onLeaveHasUnderscore: function() { /* ... */ }, + onLeaveAlreadyCamelized: function() { /* ... */ }, + onEnterHasDash: function() { /* ... */ }, + onEnterHasUnderscore: function() { /* ... */ }, + onEnterAlreadyCamelized: function() { /* ... */ }, + onAfterDoWithDash: function() { /* ... */ }, + onAfterDoWithUnderscore: function() { /* ... */ }, + onAfterDoAlreadyCamelized: function() { /* ... */ } + } + }); +``` + +# Lifecycle Events Listed in Order + +To recap, the lifecycle of a transition occurs in the following order: + + * `onBeforeTransition` - fired before any transition + * `onBefore` - fired before a specific TRANSITION + * `onLeaveState` - fired when leaving any state + * `onLeave` - fired when leaving a specific STATE + * `onTransition` - fired during any transition + * `onEnterState` - fired when entering any state + * `onEnter` - fired when entering a specific STATE + * `on` - convenience shorthand for `onEnter` + * `onAfterTransition` - fired after any transition + * `onAfter` - fired after a specific TRANSITION + * `on` - convenience shorthand for `onAfter` + +# Cancelling a Transition + +Any observer can cancel a transition by explicitly returning `false` during any of the following +lifecycle events: + + * `onBeforeTransition` + * `onBefore` + * `onLeaveState` + * `onLeave` + * `onTransition` + +All subsequent lifecycle events will be cancelled and the state will remain unchanged. + diff --git a/docs/state-history.md b/docs/state-history.md new file mode 100644 index 0000000..7e2ac85 --- /dev/null +++ b/docs/state-history.md @@ -0,0 +1,127 @@ +# Remembering State History + +By default, a state machine only tracks its current state. If you wish to track the state history +you can extend the state machine with the `state-machine-history` plugin. + +```javascript + var StateMachineHistory = require('javascript-state-machine/lib/history') +``` + +```javascript + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ], + plugins: [ + new StateMachineHistory() // <-- plugin enabled here + ] + }) + + fsm.history; // [ 'A' ] + fsm.step(); + fsm.history; // [ 'A', 'B' ] + fsm.step(); + fsm.history; // [ 'A', 'B', 'C' ] + + fsm.clearHistory(); + + fsm.history; // [ ] + +``` +## Traversing History + +You can traverse back through history using the `historyBack` and `historyForward` methods: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ] + }) + + fsm.step(); + fsm.step(); + fsm.step(); + + fsm.state; // 'D' + fsm.history; // [ 'A', 'B', 'C', 'D' ] + + fsm.historyBack(); + + fsm.state; // 'C' + fsm.history; // [ 'A', 'B', 'C' ] + + fsm.historyBack(); + + fsm.state; // 'B' + fsm.history; // [ 'A', 'B' ] + + fsm.historyForward(); + + fsm.state; // 'C' + fsm.history; // [ 'A', 'B', 'C' ] +``` + +You can test if history traversal is allowed using the following properties: + +```javascript + fsm.canHistoryBack; // true/false + fsm.canHistoryForward; // true/false +``` + +A full set of [Lifecycle Events](lifecycle-events.md) will still apply when traversing history with +`historyBack` and `historyForward`. + +## Limiting History + +By default, the state machine history is unbounded and will continue to grow until cleared. You +can limit storage to only the last N states by configuring the plugin: + +``` javascript + var fsm = new StateMachine({ + plugins: [ + new StateMachineHistory({ max: 100 }) // <-- plugin configuration + ] + }) +``` + +## Customizing History + +If the `history` terminology clashes with your existing state machine attributes or methods, you +can enable the plugin with a different name: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ], + plugins: [ + new StateMachineHistory({ name: 'memory' }) + ] + }) + + fsm.step(); + fsm.step(); + + fsm.memory; // [ 'A', 'B', 'C' ] + + fsm.memoryBack(); + fsm.memory; // [ 'A', 'B' ] + + fsm.memoryForward(); + fsm.memory; // [ 'A', 'B', 'C' ] + + fsm.clearMemory(); + fsm.memory; // [ ] +``` + diff --git a/docs/state-machine-factory.md b/docs/state-machine-factory.md new file mode 100644 index 0000000..9f5e906 --- /dev/null +++ b/docs/state-machine-factory.md @@ -0,0 +1,104 @@ +# State Machine Factory + +Most examples in this documentation construct a single state machine instance, for example: + +```javascript + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }); +``` + +If you wish to construct multiple instances using the same configuration you should use a State +Machine Factory. A State Machine Factory provides a javascript constructor function (e.g. a 'class') +that can be instantiated multiple times: + +```javascript + var Matter = StateMachine.factory({ // <-- the factory is constructed here + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }); + + var a = new Matter(), // <-- instances are constructed here + b = new Matter(), + c = new Matter(); + + b.melt(); + c.melt(); + c.vaporize(); + + a.state; // solid + b.state; // liquid + c.state; // gas +``` + +Using the factory, each state machine instance is a unique javascript object. Each instance manages +its own `state` property, but methods are shared via the normal javascript prototype mechanism. + +> NOTE: be aware of special case handling required for [Data and State Machine Factories](data-and-methods.md#data-and-state-machine-factories) + +## Applying State Machine Behavior to Existing Objects + +Occasionally, you may wish to apply state machine behavior to an already existing +object (e.g. a react component). You can achieve this using the `StateMachine.apply` method: + +```javascript + var component = { /* ... */ }; + + StateMachine.apply(component, { + init: 'A', + transitions: { + { name: 'step', from: 'A', to: 'B' } + } + }); +``` + +> Be careful not to use state or transition names that will clash with existing object properties. + +## Applying State Machine Factory Behavior to Existing Classes + +You can also apply state machine factory behavior to an existing class, however you must now +take responsibility for initialization by calling `this._fsm()` from within your class +constructor method: + +```javascript + function Person(name) { + this.name = name; + this._fsm(); // <-- IMPORTANT + } + + Person.prototype = { + speak: function() { + console.log('my name is ' + this.name + ' and I am ' + this.state); + } + } + + StateMachine.factory(Person, { + init: 'idle', + transitions: { + { name: 'sleep', from: 'idle', to: 'sleeping' }, + { name: 'wake', from: 'sleeping', to: 'idle' } + } + }); + + var amy = new Person('amy'), + bob = new Person('bob'); + + bob.sleep(); + + amy.state; // 'idle' + bob.state; // 'sleeping' + + amy.speak(); // 'my name is amy and I am idle' + bob.speak(); // 'my name is bob and I am sleeping' +``` diff --git a/docs/states-and-transitions.md b/docs/states-and-transitions.md new file mode 100644 index 0000000..3e28413 --- /dev/null +++ b/docs/states-and-transitions.md @@ -0,0 +1,156 @@ +# States and Transitions + +![matter state machine](../examples/matter.png) + +A state machine consists of a set of **states**, e.g: + + * solid + * liquid + * gas + +.. and a set of **transitions**, e.g: + + * melt + * freeze + * vaporize + * condense + +```javascript + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }); + + fsm.state; // 'solid' + fsm.melt(); + fsm.state; // 'liquid' + fsm.vaporise(); + fsm.state; // 'gas' +``` + +## Multiple states for a transition + +![wizard state machine](../examples/wizard.png) + +If a transition is allowed `from` multiple states then declare the transitions with the same name: + +```javascript + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } +``` + +If a transition with multiple `from` states always transitions `to` the same state, e.g: + +```javascript + { name: 'reset', from: 'B', to: 'A' }, + { name: 'reset', from: 'C', to: 'A' }, + { name: 'reset', from: 'D', to: 'A' } +``` + +... then it can be abbreviated using an array of `from` states: + +```javascript + { name: 'reset', from: [ 'B', 'C', 'D' ], to: 'A' } +``` + +Combining these into a single example: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'reset', from: [ 'B', 'C', 'D' ], to: 'A' } + ] + }) +``` + +This example will create an object with 2 transition methods: + + * `fsm.step()` + * `fsm.reset()` + +The `reset` transition will always end up in the `A` state, while the `step` transition +will end up in a state that is dependent on the current state. + +## Wildcard Transitions + +If a transition is appropriate from **any** state, then a wildcard '*' `from` state can be used: + +```javascript + var fsm = new StateMachine({ + transitions: [ + // ... + { name: 'reset', from: '*', to: 'A' } + ] + }); +``` + +## Conditional Transitions + +A transition can choose the target state at run-time by providing a function as the `to` attribute: + +```javascript + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: '*', to: function(n) { return increaseCharacter(this.state, n || 1) } } + ] + }); + + fsm.state; // A + fsm.step(); + fsm.state; // B + fsm.step(5); + fsm.state; // G + + // helper method to perform (c = c + n) on the 1st character in str + function increaseCharacter(str, n) { + return String.fromCharCode(str.charCodeAt(0) + n); + } +``` + +The `allStates` method will only include conditional states once they have been seen at run-time: + +```javascript + fsm.state; // A + fsm.allStates(); // [ 'A' ] + fsm.step(); + fsm.state; // B + fsm.allStates(); // [ 'A', 'B' ] + fsm.step(5); + fsm.state; // G + fsm.allStates(); // [ 'A', 'B', 'G' ] +``` + +## GOTO - Changing State Without a Transition + +You can use a conditional transition, combined with a wildcard `from`, to implement +arbitrary `goto` behavior: + +```javascript + var fsm = new StateMachine({ + init: 'A' + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'goto', from: '*', to: function(s) { return s } } + ] + }) + + fsm.state; // 'A' + fsm.goto('D'); + fsm.state; // 'D' +``` + +A full set of [Lifecycle Events](lifecycle-events.md) still apply when using `goto`. + diff --git a/docs/upgrading-from-v2.md b/docs/upgrading-from-v2.md new file mode 100644 index 0000000..42f8150 --- /dev/null +++ b/docs/upgrading-from-v2.md @@ -0,0 +1,378 @@ +# Upgrading from Version 2.x + +Version 3.0 is a significant rewrite from earlier versions in order to support more +advanced use cases and to improve the existing use cases. Unfortunately, many of these +updates are incompatible with earlier versions, so changes are required in your code when you upgrade +to version 3.x. We want to tackle those all in one swoop and avoid any more big-bang changes +in the future. + +Please read this article carefully if you are upgrading from version 2.x to 3.x. + +> A [summary](#upgrade-summary) of the changes required can be found at the end of the article. + +### Table of Contents + + * [**Construction**](#construction) - constructing single instances follows a more idomatic javascript pattern. + * [**State Machine Factory**](#state-machine-factory) - constructing multiple instances from a class has been simplified. + * [**Data and Methods**](#data-and-methods) - A state machine can now have additional data and methods. + * [**Renamed Terminology**](#renamed-terminology) - A more consistent terminology has been applied. + * [**Lifecycle Events**](#lifecycle-events) - (previously called 'callbacks') are camelCased and observable. + * [**Async Transitions**](#promise-based-asynchronous-transitions) - Asynchronous transitions now use standard Promises. + * [**Conditional Transitions**](#conditional-transitions) - A transition can now dynamically choose its target state at run-time. + * [**Goto**](#goto) - The state can be changed without a defined transition using `goto`. + * [**State History**](#state-history) - The state history can now be retained and traversed with back/forward semantics. + * [**Visualization**](#visualization) - A state machine can now be visualized using GraphViz. + * [**Build System**](#build-system) - A new webpack-based build system has been implemented. + +## Construction + +Constructing a single state machine now follows a more idiomatic javascript pattern: + +Version 2.x: + +```javascript + var fsm = StateMachine.create({ /* ... */ }) +``` + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ /* ... */ }) // <-- more idomatic +``` + +## State Machine Factory + +Constructing multiple instances from a state machine 'class' has been simplified: + +Version 2.x: + +```javascript + function FSM() { } + + StateMachine.create({ + target: FSM.prototype, + // ... + }) + + var a = new FSM(), + b = new FSM(); +``` + +**Version 3.x**: + +```javascript + var FSM = StateMachine.factory({ /* ... */ }), // <-- generate a factory (a constructor function) + a = new FSM(), // <-- then create instances + b = new FSM(); +``` + +## Data and Methods + +A state machine can now have additional (arbitrary) data and methods defined: + +Version 2.x: _not supported_. + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ + data: { + color: 'red' + }, + methods: { + speak: function() { console.log('hello') } + } + }); + + fsm.color; // 'red' + fsm.speak(); // 'hello' +``` + +## Renamed Terminology + +A more consistent terminology has been applied: + + * A state machine consists of a set of [**States**](states-and-transitions.md). + * A state machine changes state by using [**Transitions**](states-and-transitions.md). + * A state machine can perform actions during a transition by observing [**Lifecycle Events**](lifecycle-events.md). + * A state machine can also have arbitrary [**Data and Methods**](data-and-methods.md). + +Version 2.x: + +```javascript + var fsm = StateMachine.create({ + initial: 'ready', + events: [ /* ... */ ], + callbacks: { /* ... */ } + }); + + fsm.current; // 'ready' +``` + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ + init: 'ready', // <-- renamed s/initial/init/ + transitions: [ /* ... */ ], // <-- renamed s/events/transitions/ + data: { /* ... */ }, // <-- new + methods: { /* ... */ } // <-- renamed s/callbacks/methods/ + // ... which can contain arbitrary methods AND lifecycle event callbacks + }); + + fsm.state; // 'ready' // <-- renamed s/current/state/ +``` + +## Lifecycle Events + +**Callbacks** have been renamed **Lifecycle Events** and are now declared as `methods` on the +state machine using a more traditional javascript camelCase for the method names: + +Version 2.x: + +```javascript + var fsm = StateMachine.create({ + initial: 'initial-state', + events: [ + { name: 'do-something', from: 'initial-state', to: 'final-state' } + ], + callbacks: { + onbeforedosomething: function() { /* ... */ }, + onleaveinitialstate: function() { /* ... */ }, + onenterfinalstate: function() { /* ... */ }, + onafterdosomething: function() { /* ... */ } + } + }) +``` + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ + init: 'initial-state', + transitions: [ + { name: 'do-something', from: 'initial-state', to: 'final-state' } + ], + methods: { // <-- renamed s/callbacks/methods/ + onBeforeDoSomething: function() { /* ... */ }, // <-- camelCase naming convention + onLeaveInitialState: function() { /* ... */ }, // <-- + onEnterFinalState: function() { /* ... */ }, // <-- + onAfterDoSomething: function() { /* ... */ } // <-- + } + }) +``` + +


+Lifecycle events are now passed information in a single `lifecycle` argument: + +Version 2.x: + +```javascript + var fsm = StateMachine.create({ + events: [ + { name: 'step', from: 'none', to: 'complete' } + ], + callbacks: { + onbeforestep: function(event, from, to) { + console.log('event: ' + event); // 'step' + console.log('from: ' + from); // 'none' + console.log('to: ' + to); // 'complete' + }, + } + }); +``` + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onBeforeStep: function(lifecycle) { // <-- combined into a single argument + console.log('transition: ' + lifecycle.transition); // 'step' + console.log('from: ' + lifecycle.from); // 'none' + console.log('to: ' + lifecycle.to); // 'complete' + } + } + }); +``` + +> This change allows us to include additional information in the future without having to have a ridiculous +number of arguments to lifecycle event observer methods + +
+Lifecycle events are also now observable by others: + +Version 2.x: _not supported_. + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ /* ... */ }); + + // observe individual lifecycle events with observer methods + fsm.observe('onBeforeTransition', function() { /* ... */ }); + fsm.observe('onLeaveState', function() { /* ... */ }); + + // or observe multiple lifecycle events with an observer object + fsm.observe({ + onBeforeTransition: function() { /* ... */ }, + onLeaveState: function() { /* ... */ } + }); +``` + +
+The general purpose lifecycle events now use the word `transition` instead of `event` and +occur **before** their specialized versions: + +Version 2.x, the lifecycle order was: + + * `onbefore` + * `onbeforeevent` + * `onleave` + * `onleavestate` + * `onenter` + * `onenterstate` + * `on` + * `onafter` + * `onafterevent` + * `on` + +**Version 3.x**, the lifecycle order is: + + * `onBeforeTransition` - fired before any transition + * `onBefore` - fired before a specific TRANSITION + * `onLeaveState` - fired when leaving any state + * `onLeave` - fired when leaving a specific STATE + * `onTransition` - fired during any transition + * `onEnterState` - fired when entering any state + * `onEnter` - fired when entering a specific STATE + * `on` - convenience shorthand for `onEnter` + * `onAfterTransition` - fired after any transition + * `onAfter` - fired after a specific TRANSITION + * `on` - convenience shorthand for `onAfter` + +> For more details, read [Lifecycle Events](lifecycle-events.md) + +## Promise-Based Asynchronous Transitions + +Asynchronous transitions are now implemented using standard javascript [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). + +If you return a Promise from **any** lifecycle event then the entire lifecycle for that transition +is put on hold until that Promise gets resolved. If the promise is rejected then the transition +is cancelled. + +Version 2.x: + +```javascript + var fsm = StateMachine.create({ + events: [ + { name: 'step', from: 'none', to: 'complete' } + ], + callbacks: { + onbeforestep: function() { + $('#ui').fadeOut('fast', function() { + fsm.transition(); + }); + return StateMachine.ASYNC; + } + } + }); +``` + +**Version 3.x**: + +```javascript + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onBeforeStep: function() { + return new Promise(function(resolve, reject) { // <-- return a Promise instead of StateMachine.ASYNC + $('#ui').fadeOut('fast', resolve); // <-- resolve the promise instead of calling .transition() + }); + } + } + }); +``` + +> For more details, read [Asynchronous Transitions](async-transitions.md) + +## Conditional Transitions + +A transition can now be conditional and choose the target state at run-time by providing a function +as the `to` attribute. + +Version 2.x: _not supported_. + +**Version 3.x**: See [Conditional Transitions](states-and-transitions.md#conditional-transitions) + +## Goto + +The state can now be changed without the need for a predefined transition using a conditional `goto` +transition: + +Version 2.x: _not_supported_. + +**Version 3.x**: See [Goto](states-and-transitions.md#goto---changing-state-without-a-transition) + +## State History + +A state machine can now track and traverse (back/forward) its state history. + +Version 2.x: _not supported_. + +**Version 3.x**: See [State History](state-history.md) + +## Visualization + +A state machine can now be visualized as a directed graph using GraphViz `.dot` syntax. + +Version 2.x: _not_supported_. + +**Version 3.x**: See [Visualization](visualization.md) + +## Build System + +A new [Webpack](https://webpack.js.org/concepts/) based build system has been provided along +with an [Ava](https://github.com/avajs/ava) based unit test suite. + +Version 2.x: _not_supported_. + +**Version 3.x**: See [Contributing](contributing.md) + +## Other Breaking Changes in Version 3.0 + +`isFinished` is no longer built-in, you can easily add it to your state machine with a custom method: + +```javascript + var fsm = new StateMachine({ + methods: { + isFinished: function() { return this.state === 'done' } + } + }) +``` + +# UPGRADE SUMMARY + +The following list summarizes the above changes you might need when upgrading to version 3.0 + + * replace `StateMachine.create()` with `new StateMachine()` + * rename: + * `initial` to `init` + * `events` to `transitions` + * `callbacks` to `methods` + * `fsm.current` to `fsm.state` + * update your callback methods: + * rename them to use traditional javascript `camelCasing` + * refactor them to use the single `lifecycle` argument instead of individual `event,from,to` arguments + * update any asynchronous callback methods: + * return a `Promise` instead of `StateMachine.ASYNC` + * `resolve()` the promise when ready instead of calling `fsm.transition()` + * replace `StateMachine.create({ target: FOO })` with: + * if FOO is a class - `StateMachine.factory(FOO, {})` + * if FOO is an object - `StateMachine.apply(FOO, {})` + diff --git a/docs/visualization.md b/docs/visualization.md new file mode 100644 index 0000000..e944dcf --- /dev/null +++ b/docs/visualization.md @@ -0,0 +1,211 @@ +# Visualization + +It can be very helpful to visualize your state machine as a directed graph. This is possible +with the open source [GraphViz](http://www.graphviz.org/) library if we convert from our +state machine configuration to the `.dot` language expected by GraphViz using the +`visualize` method: + +```javascript + var visualize = require('javascript-state-machine/lib/visualize'); + + var fsm = new StateMachine({ + init: 'open', + transitions: [ + { name: 'close', from: 'open', to: 'closed' }, + { name: 'open', from: 'closed', to: 'open' } + ] + }); + + visualize(fsm) +``` + +Generates the following .dot syntax: + +```dot + digraph "fsm" { + "closed"; + "open"; + "closed" -> "open" [ label=" open " ]; + "open" -> "closed" [ label=" close " ]; + } +``` + +Which GraphViz displays as: + +![door](../examples/vertical_door.png) + +## Enhanced Visualization + +You can customize the generated `.dot` output - and hence the graphviz visualization - by attaching +`dot` attributes to your transitions and (optionally) declaring an `orientation`: + +```javascript + var fsm = new StateMachine({ + init: 'closed', + transitions: [ + { name: 'open', from: 'closed', to: 'open', dot: { color: 'blue', headport: 'n', tailport: 'n' } }, + { name: 'close', from: 'open', to: 'closed', dot: { color: 'red', headport: 's', tailport: 's' } } + ] + }); + visualize(fsm, { name: 'door', orientation: 'horizontal' }); +``` + +Generates the following (enhanced) `.dot` syntax: + +```dot + digraph "door" { + rankdir=LR; + "closed"; + "open"; + "closed" -> "open" [ color="blue" ; headport="n" ; label=" open " ; tailport="n" ]; + "open" -> "closed" [ color="red" ; headport="s" ; label=" close " ; tailport="s" ]; + } +``` + +Which GraphViz displays as: + +![door](../examples/horizontal_door.png) + +## Visualizing State Machine Factories + +You can use the same `visualize` method to generate `.dot` output for a state machine factory: + +```javascript + var Matter = StateMachine.factory({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid', dot: { headport: 'nw' } }, + { name: 'freeze', from: 'liquid', to: 'solid', dot: { headport: 'se' } }, + { name: 'vaporize', from: 'liquid', to: 'gas', dot: { headport: 'nw' } }, + { name: 'condense', from: 'gas', to: 'liquid', dot: { headport: 'se' } } + ] + }); + + visualize(Matter, { name: 'matter', orientation: 'horizontal' }) +``` + +Generates the following .dot syntax: + +```dot + digraph "matter" { + rankdir=LR; + "solid"; + "liquid"; + "gas"; + "solid" -> "liquid" [ headport="nw" ; label=" melt " ]; + "liquid" -> "solid" [ headport="se" ; label=" freeze " ]; + "liquid" -> "gas" [ headport="nw" ; label=" vaporize " ]; + "gas" -> "liquid" [ headport="se" ; label=" condense " ]; + } +``` + +Which GraphViz displays as: + +![matter](../examples/matter.png) + +## Other Examples + +```javascript + var Wizard = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B', dot: { headport: 'w', tailport: 'ne' } }, + { name: 'step', from: 'B', to: 'C', dot: { headport: 'w', tailport: 'e' } }, + { name: 'step', from: 'C', to: 'D', dot: { headport: 'w', tailport: 'e' } }, + { name: 'reset', from: [ 'B', 'C', 'D' ], to: 'A', dot: { headport: 'se', tailport: 's' } } + ] + }); + + visualize(Wizard, { orientation: 'horizontal' }) +``` + +Generates: + +```dot + digraph "wizard" { + rankdir=LR; + "A"; + "B"; + "C"; + "D"; + "A" -> "B" [ headport="w" ; label=" step " ; tailport="ne" ]; + "B" -> "C" [ headport="w" ; label=" step " ; tailport="e" ]; + "C" -> "D" [ headport="w" ; label=" step " ; tailport="e" ]; + "B" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; + "C" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; + "D" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; + } +``` + +Displays: + +![wizard](../examples/wizard.png) + +```javascript + var ATM = StateMachine.factory({ + init: 'ready', + transitions: [ + { name: 'insert-card', from: 'ready', to: 'pin' }, + { name: 'confirm', from: 'pin', to: 'action' }, + { name: 'reject', from: 'pin', to: 'return-card' }, + { name: 'withdraw', from: 'return-card', to: 'ready' }, + + { name: 'deposit', from: 'action', to: 'deposit-account' }, + { name: 'provide', from: 'deposit-account', to: 'deposit-amount' }, + { name: 'provide', from: 'deposit-amount', to: 'confirm-deposit' }, + { name: 'confirm', from: 'confirm-deposit', to: 'collect-envelope' }, + { name: 'provide', from: 'collect-envelope', to: 'continue' }, + + { name: 'withdraw', from: 'action', to: 'withdrawal-account' }, + { name: 'provide', from: 'withdrawal-account', to: 'withdrawal-amount' }, + { name: 'provide', from: 'withdrawal-amount', to: 'confirm-withdrawal' }, + { name: 'confirm', from: 'confirm-withdrawal', to: 'dispense-cash' }, + { name: 'withdraw', from: 'dispense-cash', to: 'continue' }, + + { name: 'continue', from: 'continue', to: 'action' }, + { name: 'finish', from: 'continue', to: 'return-card' } + ] + }) + + visualize(ATM) +``` + +Generates: + +```dot + digraph "ATM" { + "ready"; + "pin"; + "action"; + "return-card"; + "deposit-account"; + "deposit-amount"; + "confirm-deposit"; + "collect-envelope"; + "continue"; + "withdrawal-account"; + "withdrawal-amount"; + "confirm-withdrawal"; + "dispense-cash"; + "ready" -> "pin" [ label=" insert-card " ]; + "pin" -> "action" [ label=" confirm " ]; + "pin" -> "return-card" [ label=" reject " ]; + "return-card" -> "ready" [ label=" withdraw " ]; + "action" -> "deposit-account" [ label=" deposit " ]; + "deposit-account" -> "deposit-amount" [ label=" provide " ]; + "deposit-amount" -> "confirm-deposit" [ label=" provide " ]; + "confirm-deposit" -> "collect-envelope" [ label=" confirm " ]; + "collect-envelope" -> "continue" [ label=" provide " ]; + "action" -> "withdrawal-account" [ label=" withdraw " ]; + "withdrawal-account" -> "withdrawal-amount" [ label=" provide " ]; + "withdrawal-amount" -> "confirm-withdrawal" [ label=" provide " ]; + "confirm-withdrawal" -> "dispense-cash" [ label=" confirm " ]; + "dispense-cash" -> "continue" [ label=" withdraw " ]; + "continue" -> "action" [ label=" continue " ]; + "continue" -> "return-card" [ label=" finish " ]; + } +``` + +Displays: + +![atm](../examples/atm.png) diff --git a/examples/atm.dot b/examples/atm.dot new file mode 100644 index 0000000..9f76543 --- /dev/null +++ b/examples/atm.dot @@ -0,0 +1,31 @@ +digraph "ATM" { + "ready"; + "pin"; + "action"; + "return-card"; + "deposit-account"; + "deposit-amount"; + "confirm-deposit"; + "collect-envelope"; + "continue"; + "withdrawal-account"; + "withdrawal-amount"; + "confirm-withdrawal"; + "dispense-cash"; + "ready" -> "pin" [ label=" insert-card " ]; + "pin" -> "action" [ label=" confirm " ]; + "pin" -> "return-card" [ label=" reject " ]; + "return-card" -> "ready" [ label=" withdraw " ]; + "action" -> "deposit-account" [ label=" deposit " ]; + "deposit-account" -> "deposit-amount" [ label=" provide " ]; + "deposit-amount" -> "confirm-deposit" [ label=" provide " ]; + "confirm-deposit" -> "collect-envelope" [ label=" confirm " ]; + "collect-envelope" -> "continue" [ label=" provide " ]; + "action" -> "withdrawal-account" [ label=" withdraw " ]; + "withdrawal-account" -> "withdrawal-amount" [ label=" provide " ]; + "withdrawal-amount" -> "confirm-withdrawal" [ label=" provide " ]; + "confirm-withdrawal" -> "dispense-cash" [ label=" confirm " ]; + "dispense-cash" -> "continue" [ label=" withdraw " ]; + "continue" -> "action" [ label=" continue " ]; + "continue" -> "return-card" [ label=" finish " ]; +} \ No newline at end of file diff --git a/examples/atm.js b/examples/atm.js new file mode 100644 index 0000000..0113e55 --- /dev/null +++ b/examples/atm.js @@ -0,0 +1,33 @@ +var StateMachine = require('../src/app'), + visualize = require('../src/plugin/visualize'); + +var ATM = StateMachine.factory({ + init: 'ready', + transitions: [ + { name: 'insert-card', from: 'ready', to: 'pin' }, + { name: 'confirm', from: 'pin', to: 'action' }, + { name: 'reject', from: 'pin', to: 'return-card' }, + { name: 'withdraw', from: 'return-card', to: 'ready' }, + + { name: 'deposit', from: 'action', to: 'deposit-account' }, + { name: 'provide', from: 'deposit-account', to: 'deposit-amount' }, + { name: 'provide', from: 'deposit-amount', to: 'confirm-deposit' }, + { name: 'confirm', from: 'confirm-deposit', to: 'collect-envelope' }, + { name: 'provide', from: 'collect-envelope', to: 'continue' }, + + { name: 'withdraw', from: 'action', to: 'withdrawal-account' }, + { name: 'provide', from: 'withdrawal-account', to: 'withdrawal-amount' }, + { name: 'provide', from: 'withdrawal-amount', to: 'confirm-withdrawal' }, + { name: 'confirm', from: 'confirm-withdrawal', to: 'dispense-cash' }, + { name: 'withdraw', from: 'dispense-cash', to: 'continue' }, + + { name: 'continue', from: 'continue', to: 'action' }, + { name: 'finish', from: 'continue', to: 'return-card' } + ] +}) + +ATM.visualize = function() { + return visualize(ATM, { name: 'ATM' }) +} + +module.exports = ATM diff --git a/examples/atm.png b/examples/atm.png new file mode 100644 index 0000000000000000000000000000000000000000..a699d3968486c09484bdc1259cbecc291bb9755b GIT binary patch literal 98712 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
@{YeNVqAH_b8~H|_?OdJPSYp)I2OD7YcA)03{W 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

f&XbJ+<^_yz+dVxRMT3 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 + + + + + +ATM + + +ready + +ready + + +pin + +pin + + +ready->pin + + + insert-card + + +action + +action + + +pin->action + + + confirm + + +return-card + +return-card + + +pin->return-card + + + reject + + +deposit-account + +deposit-account + + +action->deposit-account + + + deposit + + +withdrawal-account + +withdrawal-account + + +action->withdrawal-account + + + withdraw + + +return-card->ready + + + withdraw + + +deposit-amount + +deposit-amount + + +deposit-account->deposit-amount + + + provide + + +confirm-deposit + +confirm-deposit + + +deposit-amount->confirm-deposit + + + provide + + +collect-envelope + +collect-envelope + + +confirm-deposit->collect-envelope + + + confirm + + +continue + +continue + + +collect-envelope->continue + + + provide + + +continue->action + + + continue + + +continue->return-card + + + finish + + +withdrawal-amount + +withdrawal-amount + + +withdrawal-account->withdrawal-amount + + + provide + + +confirm-withdrawal + +confirm-withdrawal + + +withdrawal-amount->confirm-withdrawal + + + provide + + +dispense-cash + +dispense-cash + + +confirm-withdrawal->dispense-cash + + + confirm + + +dispense-cash->continue + + + withdraw + + + diff --git a/demo/demo.css b/examples/demo/demo.css similarity index 100% rename from demo/demo.css rename to examples/demo/demo.css diff --git a/examples/demo/demo.js b/examples/demo/demo.js new file mode 100644 index 0000000..f2b2b95 --- /dev/null +++ b/examples/demo/demo.js @@ -0,0 +1,84 @@ +Demo = function() { + + var output = document.getElementById('output'), + demo = document.getElementById('demo'), + panic = document.getElementById('panic'), + warn = document.getElementById('warn'), + calm = document.getElementById('calm'), + clear = document.getElementById('clear'), + count = 0; + + var log = function(msg, separate) { + count = count + (separate ? 1 : 0); + output.value = count + ": " + msg + "\n" + (separate ? "\n" : "") + output.value; + refreshUI(); + }; + + var refreshUI = function() { + setTimeout(function() { + demo.className = fsm.state; + panic.disabled = fsm.cannot('panic', true); + warn.disabled = fsm.cannot('warn', true); + calm.disabled = fsm.cannot('calm', true); + clear.disabled = fsm.cannot('clear', true); + }, 0); // defer until end of current tick to allow fsm to complete transaction + }; + + var fsm = new StateMachine({ + + transitions: [ + { name: 'start', from: 'none', to: 'green' }, + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'green', to: 'red' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'red', to: 'green' }, + { name: 'clear', from: 'yellow', to: 'green' }, + ], + + methods: { + + onBeforeTransition: function(lifecycle) { + log("BEFORE: " + lifecycle.transition, true); + }, + + onLeaveState: function(lifecycle) { + log("LEAVE: " + lifecycle.from); + }, + + onEnterState: function(lifecycle) { + log("ENTER: " + lifecycle.to); + }, + + onAfterTransition: function(lifecycle) { + log("AFTER: " + lifecycle.transition); + }, + + onTransition: function(lifecycle) { + log("DURING: " + lifecycle.transition + " (from " + lifecycle.from + " to " + lifecycle.to + ")"); + }, + + onLeaveRed: function(lifecycle) { + return new Promise(function(resolve, reject) { + var msg = lifecycle.transition + ' to ' + lifecycle.to; + log("PENDING " + msg + " in ...3"); + setTimeout(function() { + log("PENDING " + msg + " in ...2"); + setTimeout(function() { + log("PENDING " + msg + " in ...1"); + setTimeout(function() { + resolve(); + }, 1000); + }, 1000); + }, 1000); + }); + } + + } + }); + + fsm.start(); + return fsm; + +}(); + diff --git a/demo/images/alerts.green.png b/examples/demo/images/alerts.green.png similarity index 100% rename from demo/images/alerts.green.png rename to examples/demo/images/alerts.green.png diff --git a/demo/images/alerts.red.png b/examples/demo/images/alerts.red.png similarity index 100% rename from demo/images/alerts.red.png rename to examples/demo/images/alerts.red.png diff --git a/demo/images/alerts.yellow.png b/examples/demo/images/alerts.yellow.png similarity index 100% rename from demo/images/alerts.yellow.png rename to examples/demo/images/alerts.yellow.png diff --git a/examples/horizontal_door.dot b/examples/horizontal_door.dot new file mode 100644 index 0000000..008113f --- /dev/null +++ b/examples/horizontal_door.dot @@ -0,0 +1,7 @@ +digraph "door" { + rankdir=LR; + "closed"; + "open"; + "closed" -> "open" [ color="blue" ; headport="n" ; label=" open " ; tailport="n" ]; + "open" -> "closed" [ color="red" ; headport="s" ; label=" close " ; tailport="s" ]; +} \ No newline at end of file diff --git a/examples/horizontal_door.js b/examples/horizontal_door.js new file mode 100644 index 0000000..1a2f676 --- /dev/null +++ b/examples/horizontal_door.js @@ -0,0 +1,16 @@ +var StateMachine = require('../src/app'), + visualize = require('../src/plugin/visualize'); + +var Door = StateMachine.factory({ + init: 'closed', + transitions: [ + { name: 'open', from: 'closed', to: 'open', dot: { color: 'blue', headport: 'n', tailport: 'n' } }, + { name: 'close', from: 'open', to: 'closed', dot: { color: 'red', headport: 's', tailport: 's' } } + ] +}); + +Door.visualize = function() { + return visualize(Door, { name: 'door', orientation: 'horizontal' }) +} + +module.exports = Door diff --git a/examples/horizontal_door.png b/examples/horizontal_door.png new file mode 100644 index 0000000000000000000000000000000000000000..65d8ddbe9d405b72e89d190d62c42da38ca16cbe GIT binary patch literal 11279 zcmbuFbySqm*Y6)dT0pu(T2cgI0O_G6MTC)VB!>p2q+2?b5&;FNp<5)Sk&teXl#~#- zhu^yE-gWQ$-oNg0Eo7LP=Q+ZT$l(!Opr2MM#n2__r15lvlr9d{`ym%@OScYi9 z9IlZq<(;73e)JsqsZ>`HyPB{1WE@dgJ=M_cF#f`B{8hCsGJT>U21iF4PDUxMdGA+J zxdKVT#?^`tF&WvzB@&mG?4he*R*}EgjFI) zyp9Q_#SZJR6`F;?=+yIX6{$3LP;)9ZNzqj&yW{g(LshSDwC0 zNFV{%HCg%=k|yrSrw~gQQSZ8uS64>`51yLR>(3M+nxCJqbKM~9ilxW5wzfVyKR3O( zzG_(EB*QB)YNi?cq$USmgFy!;C6V1DCS-ULPAzEF_TvYBXJ=>HBTKw#lr4soloTr~ zD~{I*U9&V@Vjc>WWbufa_hrq~zX(4+$zF>`hX)6_d3nrY9y?U}`ufCB1{jRIqT<+m z^XuN;-Uvw3%}t1ySS?%f{a2&r&*JLN&JXJw8WIfn3U_wwD=RAQLnyOOyuQA^JbH1D zdk_uG*~HaYSh3Z9vCGtq2Z0KQG#wosODAic7Sth5X6Coy;a~)4OaTMDZog$8`)3N#5ZvCVzTR8V;6ZnQ{X0C(-X)wK5F`ll@bIWM z@;~ULM1uqb1R$s)t=ep$zu)b$>EGcGC;){L`rh50uNcQr=dz~Kyg?EHkCX6pagmjg zX%{rYRJ8Gm?)W}TBde>cTRJ&6I}1UCgoG!46C)$U&~S_I>)A$6qV)9iqM{-%d#P$f zDMxiy3Z4idsocvdn9HhC>10(^6&fTXBXi;>%*(4*t5NGX=hi-w@$u6qv#X1fi==+r z!0>P{tcTC?Dl17aunB_=_!Qr~c``dUhXz$y4=KpXqN`_15(o+kx@}JoOqLldg1=mx zY-2NjTkTDZ&&Y_ZtAiDdzdGI=!2knE6LaT6$G||IY(3AC@@Kd_-3@APmS}2jMs82= z+6d7YR&|bzk=EDOYjP!5XUNdyzqN)0AD5Jt64TN~;gYhO^d&t=6LDf#AIc`8q@>Jx z;(b_=dEOR?k@m#<(e+_!Yg>Cen)P5-V0t<=4=*qBa8)@tG<5m)1K?YDczETm8|qUt zGv*zk1af+M+XFH@`6^>6MX5hD*oEq-$Am^tVD4>p zw`>0Zto@%6HMOhPSC{DAODH%`P!$i@v zADCEo8+kf=)m@2_1)I;>ud*n{L?5~^abR=u+&Mg)($&M6ZN^{S!1%i-A%s_-l`i9} zhd|fW-N8y#*%l7XC>yurL8x(!%VBWw`5iuniAo5OSX;Nv(c8>WIJ=i#)uvJof2C(y zKUt>07Kx=$uzldXg5`X~?tCdcQ(4JyZFuyFEMkgaqK3B-LizG3k;i6#GAu`S98Ur z!v*-SuX}nt)CJozxzLf9!p>`W&L>=gk+dQKc9VJoXeQ77h=@GQZJelf*Vj7lc8n+Q zPEHq8ZitTE72FKw>t)AG9NR-++Ft>1ZTD<15rY!wWnISCZW>> z_+*)mg*Q z|6oN3Ee1KfnH;vs9}|;drka!A9m}9zw#TgKgNwlY=+3S@nZ#&%`Yl>L zBwkmdUwp%F3qaeMEPE`>9UYQD!gN0{-P?d}W^c}1?L8VsKn_z40bP%s4?zH}qPZ4l zfS`4nKAjZd$B*U4CHLh5mO9e)&n{^t&w9K)z8YI&xvbw6yxy@t^`{kho8I%KtkOhq zL!b^RbSLC3c}cb(Iw6BaGv<3SiGRs7k0WX2?H1S7PW>kwJ3FQ07^H1D?~$P2rRPF@ zqreb}z0l-JSKj%BK_}j|Ox6*KW@_5DU54@DgDm$dRl?RQUDES&>%}&-3D(_FOezt= zvzZ0R*f^IQ4^JdkvEGM#s)_pS`t@lP>AkjovmL#Ot6l*KA)1Mgx8Le!)E7DUv()yp zxWqoqq?TWVFn~aJx{-3KE*=xs+^nDLwLvdz^|oUqPZ#6noT%Iq-}&qz?Q?POM-M&u zXr0WN(`t~M$!)RpZPwWp^Y1Fm1AmVNE}BU8rysc;9_gR!w|*Fxy}o#1vLu`H+A}wq znr^JWJ69WxR=9j5bicVfZ*%f%#o|Vh)~pbWpksjGY_fH#t!f}s-?J>6@lO|R$&+fU zr+XBl?vVr+=aa1g0_IaDx%(}G=O&aJ)DH#C2a=P>Oco?{U+<1bC0C4U=Z;fjB?`of zd+I%Z^zh!F1JfgT%XNlY+OqR;pk9AQBQ9=%Wru6cM6e9Te=J_wG?^S$4{@rU6S->f*E=IjtDf(*F{&~_E zd;U$LnlL^tF@n5X$JxUwaBQVJFpWyMm+yX{#QqpImDGnABMD!GO+ifIcx)d(pOwsK zscWdl(K5&bMt2_v2TDlLd&yKaeD7(?0)5U5U zG-C1Sf6M5bj))x}CtA?Zux2-ViW`A=k4#EI=Wp#_PtB6}@kz@SCM*5jj6PFDs>JlC z&|O|UO#FG;F_R8m@|9s5y&+{k$v-nrAkN?NM#|%RAX@t~*007QO$@%HpQBffhJKZF zVPH>{BMB9iSV>Zbf7^;me$<}8Fn@}oS?TG&BYA#DuO(}(W6>Fb9vj;hL2Ca`(>EgP zyP46-y=XSoDc1aY*AU%rOFz4&X<#mQye@Ye3I#cnrC+@|+V-J9$U7gOItVwq&j<_u zOYN|=RVpZXBPNbv?0Ztqts7NAt@xz~x$~>zbMQ(xera$=F=ISVc=R3JQlF;n$0DgG zU#aj*zrkV|ELmi|6ZB&R%1zM99q9#$N(1jz9ME;W9ihc0rcLg~$fGk~zWS@5B3f}~ zI@^)YeX_HE_I<_p@)%87sr>s<%&-$rhrGgXP_&85s32uSI3W`}F&dNM)XNQ50 z#_}#|^JgGAIeAZiKOATm(3Ujy^umF5(b3V#X=G5ZF67 zEG;jigPw?O-5gz8VC;; zS6(I(;wMjZ?nS`MYiq-Tf-stznijXVB2RZ`1&6!$$x-&#HorD&+Ls}YDmbfP&CBM=4WbPO5 zl9MrG6fgp=%Duh4+k1O)Yier1P@Ub}?m!lny)tl4Zf-dwQebbkJ}5F04+?-Y2gbz_ z`5bQsO8Q=yY!2sA3EA8O(aF4`!7N73HovAURDb`iH<5#wo<0W1Cm<^78XEF6vL*kV zoXBqszIV^e%%n9iFvxh*a`|_kg`fXcAl*K!f&$j)=;*twtmsD1eOXqL_Q^>~xzM{Z zCMHZkvMlvdsxJw>#i!(3Tx<`5`5bd5BqZeMez~96JKXB;f4uXHbgt1;@$cT;NUj|A z)YO#F*3{bC+O5d=YS3r&M)DQS`_lxxuFp3J+(N2t zT6i`hA|j@0ofrw}#e#qS)JaQEZ(mqoWKoEg1_F7c%vj0`_o2i?5fMu8Ii;shzo!dY z-vi3%^Jgx%-D&dN+*}-d{0^XY?mzk@I+SH~UqS+;s#DkATqE-G)WOT!`@WD685$ZI zm9RY(kUZAIM;q(w%R9fSVD4LFd3ky7fCh4Ma%#Fdow=22V$^&Ca|-X!>X9p0yasje z-n@B(1D&6p4L5loZBA8~>lhh1_B<0w2QzcATf1O${qKBrds`JMk_#gga+-hA;B)eM z_z;GkKVq{9Mn!h-o-}iOI9Px-2g{vF@7_t%#3*PQ`u{t?=G7|?c=F_l5)Z{QP0f4q z^77QOlUU8PVJZcA&9DECs`59(!8gU+Hl^_?cyi9pynM4i>no|K(v0yhm1zQ0tCkEJUt! z#RGj=?X>V=;;W%*a&j`bAywMZ#!zBwt5ig%86GZf?)UHTT(-w)s;PVs>EkJ5{t{3i-LaGqs5ziPJMPpLuz~=9;{pF)kx`fV=qgcfmg!sMp@HvBZ}1 zbz0vB(ZUc-1B0iD92)HLN^l_8-PZcZ!R6C$FCR|K0>U_;FRA@UMMWd|H}P z5H=Be1YB0osz2vtt)s+`rD)Kx_J&LJt3cU_1`=JdqM|}pb$K)5S)sZXP~yEE9YLr2 z3;Za$<_hZ}1{YUX7Dh(K$kXc6O=@zJK56#IL3RgDBq9-X7?4vSs;m9Pv!PSZ5SG7l__)gZp-Hin%5zX}-WM z-A-xq-+4RxceTha!{!vxP1G7SeVX zKP&9{_U$c*^3BfH(|2n>QWN3Kw$J0wC%%KXKoFc=Ir4gXlt8rImcK_7?p|1crrFPm zjg5V=ZG6*bM>EtGO)c0nJ)NQb>{&?4w_+J(W!(D4#<8=5m5`KC=3yHlA*+6>R|_py zW1oWUi#!uD74q9bZUuwh1I%^Xw{PDxNv#kP8kBPsSVf2mGx@6b zRg#fWQ71l4prlozP#^toE*E?x_zG=j8{DIKcz8Cyl(mo`RHDpJw#F?S9MnAb=S!VZ z8#1{-F0Zbw$pfP)oYkPHq^4Hzcm8!8q&fN3Fmt!*u@)!Ut!1YH9ROrqGoycR0^92H z@~D|LRwfBZ4K`0tPi-!cowi7T8eWZkA}BSeuWT{g5{@0n6iKYF7qzsurd2nj2k*+n z1cet>RwiU+W#J6_cLjoG2ADuD2zN7M=9se%7rD2O&uAET`%@JdrlzI?AM^^@R-d6NE8l+k@^YVYhmT! zFyEP~NRxQ&(Oi74qM}j`0tR#iXR?Yx%NuG?9d8{kcxVVZI5*(*zoA+@2*1<*a4Q=MwJ%0eLsFIfu0ZWf-0dM z4mvtIQ?kmz!p$}1%6Ufe+k1?RaqU6a+mGp26Z?wu^I4Xcm&=_NBzG2C89_Vl=ua0! zuJ==Wd3h}+YDl(cIW-YX@yIJ|W?)sO$P7$Yp0w&+ZzBncJq@ zY#67<(*+s}5;UF$PcPKL;eg1(yZrq8`I)DnUWF1ds*`f4|E$ieahy|ufLM@gxYA_l z(n26q9;HX8@V@-?8r&xvEMw5rHhm<)FF-y0j-{obPyiJR4j1yhI7U3Uc^eeeJ3gKa z!UvSl2)Lo`#qsY3B-iiXzggpz?vktwj{?|ou^h#J*W=A#A~oo)16iWaoVs5lL;(uQ z19c}pIhhxz6-Ubn5659sM{dH*&>eXwXtuzKfq;Q}ZMyc!KwdC+3kXhAzpA_=% zzj*QDk%-9T%*oHDuYj^mo=mK?YsD+wc_h7jG*+mAAzd2qMTe_Xe7`B*&gDtpE$~{b zkWVstb07~%gQX6c0Q6U0UESHZ-x76SE;Q%!XFR~K!sFrq@RE>*$2r`;fBy^!3kZ^w zl&p^Br=ax+6lY%6AH#$%+$@BqJlpjiK-o#6dx6D@2HD!$YVejp4BR5j@i^-0>Y$DL zG_x=Et{qo64G#pb@vKt0=z)&~d+)Iw~?d4IlH!FZ_ZU21A!BbNFRcmP^5a`NB1UIe^_ z?zx8H#lDxPU=#ytpdK`DQ%hLU85tP?Jw9?d@X?Ud3gD&&@>1y3l2O73H8^BLf7uhy zQf)LeIEV$^!Nf#^Bri5u-1cUvTdyy;J$9!9A(Q?1Is7Tt+uZ793$C(QF0y%Z{*!kGWVHX7DG~;MaPEKLU1F*QY|sp~aPK;pC)&fpwQDL^k*3nB~^b;^Ph?sbLVv2QXL~NEh(n z5v(M*qT=FX73STy^;JC!CIg`7oi--rR3dsYpz1a&P9GMYpZz-;Dt4Hu@yV?FHS7Yk z=?ipePy^xLmq|eie+0cfLA&_PD{nUDt*HtYw4#E!j*gXzsottQ-7mere$}@;wQ-N5 zqnCUGQ%id&kZW5{d!gd83p)Q@(K#0SC@Z_0Y_$L zX66LLT_1d}N=!_QdUJk==naN6vn73P#y>w7GW~Xk229r8r=kA-kHf>7E-o(2A|fJq zL_~#e-=fc14`qqU-HI(BEIQ?XleDa^TmsoG z!De&0zTycO1;5eLM0T~j+IgR-dH)+j;bz!$t~WVPPC1B1%N0GE2PD zL-#Em`nre@-0lsogCd20UQz}I!g_;P&@+T*M5~+G{_Zb0)wl|Wl(k;dfTo@%?0~ouAAj+D#72mW zib_f1_33JFL^d&yXt%4$-~Wc9exj(j(s@Z1L^}`k;-C+OB_+|4|Nh7s@|b-K#^n`$ z-~z0(C=50XY*jXDCh-}zm8IoxZR|rf!c27_sP$jIJR0A7NmWo#u)4RWzS0##3M7Vf zrdT;JCpubM2OkZyKa`vSN^N0kDs!|xFqSP#y1Wu6#a^s~u#+S#T+30@Z32QOw*Y4_ znSh^F#&2c^Yyl{JyRp5E|Fr{+#`1`QdYbU~ez(=JW| zy^0G(H~8#Uty%VwfjM>TDRcO;0w#e&RaN!ka^dFd0%kfYOUylzj-I|4sHLW6BO=g? zR`>TcfPZ#7-qZqWl_ngRCy{xtARvODe%3!9(~ts9=(+hyT8y!q7z<0#zpJZWpcSwG z`ro9M)gE%t#Ds#zs&IOGI;$5$2IgXEX$iD9#1)eSctGG_*(>y(R#^=^+Q}P3B&o37 zIzo`#&40e(4>SbJs-tk5x`j;IpbIb`!71NINCDH& z1?C{3u~GaAxC>w@@WF6B_UF~Ue*OBh_!&oJM1<{D?uP*w%FJVDN(S@`3o9!Hu-*%f zkB_Y-?4#JZxufQN{~7`X&IA(U;&jHz+vyqi$GW<-Pfycjfx84Q{{b7Dyp6INJ1ASX zU5X^C6DR<;Ir|y*!=0|&TRQ@_Ml7J#pRJ&hR|(wJlS8k(SJq#cqAKXqgAYf^1tz;0euLpFA%dl z(8Pgw7VMLL1$I_^&z8bgcX!opM~jZW+0E#`${mnS1-!1`zXL_k9VmhQ0M$x}Ud*jX z{`w&>t{3MU*|tB6v{*?ZiU0+c|Ku{`;xp2^8nNHdI(elv(jGUwJL z+u9c2*O;>ay6!hH`9hw128PV`gS%GvDOBy1uSpR*|L!-+R1%NTE|2$*K!up|VaS&QF7@NX#xC_TiKl-PhcF-Z6@0fGT~tB+yX+cBS8 zp9k_K(y-CvzMvrKhYufc2ngh*rJ+zldQhN=f<8!rZ5ivK51rr|$j#yVz)s}4ZVaZu zkj(Sm8}xGX8nl@MuvglengKwL16M^F9vj;Q>Q>H(%_5NRK-P2s4%E`p0=&DRnCISI zQ2GIat5HsGkH7)umXnk7mgtO*jk$wO2P0t4(csL)Ku7|Y{5I9d2RAS<5J*;$wq#cX zH`s?f1BKFgwTBoaOKw90&3iF-*;}+zWvy|$MRtpjfE71&a#|=dPfbc<5*Md^QD)S6 zOUl4r8sHulmX);o#!7rwN$5;m1%@nMSW@f$2gXEXxCY$IQlt3CaP0T9cOd zvGv$(|0gz_n3!nj9|4sf5F|iWWWBvbp_*t*OG`F9e0)IgbhzbEjg5_iX&+wii5~CH zPy+R9dn}dMQ5<)8=<>a@^S+oE4S0sSH|LLlEOK8P20RcuSu-)u!1Plgi>+8eg6DM^|yH7ML|P2Y|Qs6c0D=YX&3G>`5*zumAW_e9tLuy zSb&EYm5`~EhK=ck2Q)otYs2U|jzH2XnlVQ?{e<&j3p z1dLWRivzyA*!C-HpwX+wJ99nb3meO;cfs8JMOtM2ej+9OfYTRbs};k^!6I6@hr`kD zCFhL35PbXNDq_>7F0B`D^4Z77?WvqhO^?=CUl6S^at`AGETxU0`gh#g-&*Gqp9u}Jtf?T$bz-| zJZowW(H-TCo`f}cVD9V$IL?8cr?zqOGy#mMO3buJ@;2^t>K#+9j9ypnU=S)DI! zny{J;n_8YbH8%8bg^?#w`)TyB3M}hFzm^c^?wtlV5Z^=_!*(rRu&H)>$}``-gc1U4 z=i)E6-(?KuaZH@l-G*LN);po_Cq}{|>^2RWek#9}_}Uuy>tL zV(Cc{xM4@{ru0mD?kx`AXJUohJXR|pr|qtHE$Jm8$Bbs+MbQw3#n>|l-+d^8t^R=w zF;F!e8G`}M`{38PML4Xl%YIo(6BGBWtoA1%4V(voJ>o%CqM5`U?)zhiinjG7%W{Jc zU}6HbSTZ?Or-mVIw-Z|$Q7iK2ccH!NQ!)fWcT&1&qUHI;j$m%`X2`^x4%!q>a{!d` z9mY3UH1Ty2MdEiB_*e@(kU|UzB1Y0?O^rN2t#P4-pl47x#a&diG{SB&z;nTJAZfys z26~#?mAkemGvR;jf74w!=b8})mgpaowrQHPegBuw0_N|$qC<2=qcJn5W6oB1V(&d*V0t%Md9IHjRu84=+oa(zT}4?mx1(?r@*hw1fS zjEcKKM&2Q%&O=L^nL|?8%q;rC4edc8y5{$u{(wOfY#ysPg7J$cA28qN8w)$2Q}947 z7kI!)*gVGSIF80J(N9&+GWk_d@9litDY8(0Km)R@$_lr%D<|y}5(+5f5R5x?5%ym^ zbpR~dV9YEJtjKeDpH|NpOfdCOHF(%rXYR`DUjxIt7IlG|8GGfnr zVR-F6Ui`ryqRUDJtnE~zC%^7tM4$#ccT{PM#~z*CVa>9%jiK|(u$gJQLh@GxW`Fij z3WDAU;a^K#~ zw$+d4DkoyN`L!p&#|k#oys4kLD2Av6L)DDKV=Pr;GMHvzTV~&Jm>%G6{*369kh};l zeP)NQhd|)*=32V^CV6NA{n@Q8v1+i4QXWFBcWE&?I<}RyRuTu;O+eSzPYS~x7KEC#GF>-9;^oVxS2L>eY?{y!L(Fq~QIef9%z zo+FZ+n<-u?M~4e}erS1n;OO^gfwPMXIs}f>m;+|H38WGb&$qTkmM^tqaF7r$1l`#G z>apW&UEu1f1x!qg`OzbiA&I{Ru0}p9=WCQEdj>g0;cP(}f?+YRb?Cb-ER2xYeMf0^ zQ|b7ZH5}|ZaK9q^-_VH_Y!<-bfV{IoZa{a;`9Vc?lV9O*o&T0SX@V^-Vq$QJ3D})c zdJ!I;=)iiy#k3Y4mVe*>J}N3WS!bIoQJQ($-Zt zUJ8R#P=H-UIEOk;X;C|vuTW?hctW?b|8H8PBWU2x^6p0j1rO6B5e}bg@4PDO5Z#~J zOI;%tqoY%0#L{F`N^XZAha*3z*w}EQX`J`^fU?NvlK$P`S1J)4o5l8iEWMKhoOB{h?{LxM7cfqqAVs(T57DJW5|p8oYIdq zZ(_&Q(o!O2+$gDF!n8f))Xt)DbaeC|_(O0VeKsWQ`+uB;f&$9R9~v}y5wj@9!tL#O zu!tC<_gilmz&@QEV6R+UTnyqhh*HNs%gwlNvWp!=zlxS(X!T!g4`jAo?$fT}9S-1% z#9Fg41;o%rN0_o`%E?Zh#bx_j9Z@0f4N2WR`OgWW;h)1P$;l!4CsgymQ{zCe!yd7w zU%!4q0Xb5Wl2@Dgal`el*8hMNnyR*={QTuhh0O@_?SUz<=zy>KdU6iPc!_bVkrd^G z-rg+Q`hdCl!x~4-6dqF+8A^VvYa!XeXZIQg$F`Kz*@0bLscLKnPxT4qdKw%ypAD57CoB?@b^JlUBqYhU@ zc+Y<&Ik(>FPQWMi_bO8V{$TJLHKhUknJEJMtV>ESr7q-17oScY|Aiah`Gt;9cIX5~ z9Fi*9ZZiD(T!WdClDRm^rk^UWh_iiWFqO|RFP=p)0We>0FRx*Mu$B2zNr?qhz*f=k zx2f^*@oqQQzFfS#1;FC~@b~GKj>6%0c#T`K7@m0Li1R^PV}(SwK!yEjnlv~C_X%uf zk`PCQfiqozn%|xi(*jPPoQzCp2-Dh{)b|iqD~u4x?)3jqf!Xi`$SMb<(4oUCa90_>;ewa%Q z&5@3maCZQ?MdrMIcbmP$mNf{gVtjC>npCeSP>U-tiA-2kR5-<#L&T|a-)xx4stECH zZQ$K{D6L`?2X_>;k{SzI8uEB=phnVnD!;4@ss4?N-@5uMK4qE~D;ruWf0YiFurQBp zY|ZJ(H~gkkwkNZ&=-333Q`M}ro|>OJ9*NJNR~Q@d^QS1Tj;OI??Cge&85;Dzy6f(s zug|k*?nLzDFCDFPA;6X^`LLG^voHiE9;RR-_lv2RwDj{o0{r_+en1V;2Snk|Orwgg zY^=M{qaj*M{PK;*D_Aa~(%+*$R~|0esjy}G8R>ivb=laEdSj$>N9RSAFE7tj_`u-% z^j!D7eqkvo;p0s6yUr^%Cpx;4LJ3VzJf1Byb~~=W{>$JfFVACFtNrWD6&$LwvLYhr z?F?a){d_*#5kwtaScnuZggpkQU5l|D24oA&1aNo>33s|`Q9{3edb1BId_aqSCK4M< qbmQSpu8v(O|7|<^zZ`$PA!2|qs-?!$IKc^DNLgMT{#DlG?f(Ew&`T}= literal 0 HcmV?d00001 diff --git a/examples/horizontal_door.svg b/examples/horizontal_door.svg new file mode 100644 index 0000000..217e038 --- /dev/null +++ b/examples/horizontal_door.svg @@ -0,0 +1,35 @@ + + + + + + +door + + +closed + +closed + + +open + +open + + +closed:n->open:n + + + open + + +open:s->closed:s + + + close + + + diff --git a/examples/matter.dot b/examples/matter.dot new file mode 100644 index 0000000..9a5b12e --- /dev/null +++ b/examples/matter.dot @@ -0,0 +1,10 @@ +digraph "matter" { + rankdir=LR; + "solid"; + "liquid"; + "gas"; + "solid" -> "liquid" [ headport="nw" ; label=" melt " ]; + "liquid" -> "solid" [ headport="se" ; label=" freeze " ]; + "liquid" -> "gas" [ headport="nw" ; label=" vaporize " ]; + "gas" -> "liquid" [ headport="se" ; label=" condense " ]; +} \ No newline at end of file diff --git a/examples/matter.js b/examples/matter.js new file mode 100644 index 0000000..c3b960f --- /dev/null +++ b/examples/matter.js @@ -0,0 +1,18 @@ +var StateMachine = require('../src/app'), + visualize = require('../src/plugin/visualize'); + +var Matter = StateMachine.factory({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid', dot: { headport: 'nw' } }, + { name: 'freeze', from: 'liquid', to: 'solid', dot: { headport: 'se' } }, + { name: 'vaporize', from: 'liquid', to: 'gas', dot: { headport: 'nw' } }, + { name: 'condense', from: 'gas', to: 'liquid', dot: { headport: 'se' } } + ] +}); + +Matter.visualize = function() { + return visualize(Matter, { name: 'matter', orientation: 'horizontal' }) +} + +module.exports = Matter diff --git a/examples/matter.png b/examples/matter.png new file mode 100644 index 0000000000000000000000000000000000000000..cde3b89e88eff344c373cbdf183ce39c9c49c594 GIT binary patch literal 14731 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 Ykyx-k{`k^voUSB}Y3QrxAF&GgU(=( + + + + + +matter + + +solid + +solid + + +liquid + +liquid + + +solid->liquid:nw + + + melt + + +liquid->solid:se + + + freeze + + +gas + +gas + + +liquid->gas:nw + + + vaporize + + +gas->liquid:se + + + condense + + + diff --git a/examples/vertical_door.dot b/examples/vertical_door.dot new file mode 100644 index 0000000..822dad8 --- /dev/null +++ b/examples/vertical_door.dot @@ -0,0 +1,6 @@ +digraph "fsm" { + "closed"; + "open"; + "closed" -> "open" [ label=" open " ]; + "open" -> "closed" [ label=" close " ]; +} \ No newline at end of file diff --git a/examples/vertical_door.js b/examples/vertical_door.js new file mode 100644 index 0000000..b619195 --- /dev/null +++ b/examples/vertical_door.js @@ -0,0 +1,16 @@ +var StateMachine = require('../src/app'), + visualize = require('../src/plugin/visualize'); + +var Door = StateMachine.factory({ + init: 'closed', + transitions: [ + { name: 'open', from: 'closed', to: 'open' }, + { name: 'close', from: 'open', to: 'closed' } + ] +}); + +Door.visualize = function() { + return visualize(Door) +} + +module.exports = Door diff --git a/examples/vertical_door.png b/examples/vertical_door.png new file mode 100644 index 0000000000000000000000000000000000000000..c29023dc98f77f72923c970ffc21dd834b78711d GIT binary patch literal 8246 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 literal 0 HcmV?d00001 diff --git a/examples/vertical_door.svg b/examples/vertical_door.svg new file mode 100644 index 0000000..12dc09b --- /dev/null +++ b/examples/vertical_door.svg @@ -0,0 +1,35 @@ + + + + + + +fsm + + +closed + +closed + + +open + +open + + +closed->open + + + open + + +open->closed + + + close + + + diff --git a/examples/wizard.dot b/examples/wizard.dot new file mode 100644 index 0000000..c7e6f25 --- /dev/null +++ b/examples/wizard.dot @@ -0,0 +1,13 @@ +digraph "wizard" { + rankdir=LR; + "A"; + "B"; + "C"; + "D"; + "A" -> "B" [ headport="w" ; label=" step " ; tailport="ne" ]; + "B" -> "C" [ headport="w" ; label=" step " ; tailport="e" ]; + "C" -> "D" [ headport="w" ; label=" step " ; tailport="e" ]; + "B" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; + "C" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; + "D" -> "A" [ headport="se" ; label=" reset " ; tailport="s" ]; +} \ No newline at end of file diff --git a/examples/wizard.js b/examples/wizard.js new file mode 100644 index 0000000..8d1aa4c --- /dev/null +++ b/examples/wizard.js @@ -0,0 +1,18 @@ +var StateMachine = require('../src/app'), + visualize = require('../src/plugin/visualize'); + +var Wizard = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B', dot: { headport: 'w', tailport: 'ne' } }, + { name: 'step', from: 'B', to: 'C', dot: { headport: 'w', tailport: 'e' } }, + { name: 'step', from: 'C', to: 'D', dot: { headport: 'w', tailport: 'e' } }, + { name: 'reset', from: [ 'B', 'C', 'D' ], to: 'A', dot: { headport: 'se', tailport: 's' } } + ] +}); + +Wizard.visualize = function() { + return visualize(Wizard, { name: 'wizard', orientation: 'horizontal' }) +} + +module.exports = Wizard diff --git a/examples/wizard.png b/examples/wizard.png new file mode 100644 index 0000000000000000000000000000000000000000..74945ca3515d6b7a6326b55991834dd53ad20700 GIT binary patch literal 28377 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

nVX&N3Kl`}Qn4Zw5^3WmXLo%NBCk#LCUP0F27 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%0Die@2c1_T?1)MZu;NfS&!KyK9Rw=TJ+5`C> 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 JBbr&?{|^Ly&lLaw literal 0 HcmV?d00001 diff --git a/examples/wizard.svg b/examples/wizard.svg new file mode 100644 index 0000000..46edc96 --- /dev/null +++ b/examples/wizard.svg @@ -0,0 +1,69 @@ + + + + + + +wizard + + +A + +A + + +B + +B + + +A:ne->B:w + + + step + + +B:s->A:se + + + reset + + +C + +C + + +B:e->C:w + + + step + + +C:s->A:se + + + reset + + +D + +D + + +C:e->D:w + + + step + + +D:s->A:se + + + reset + + + diff --git a/index.html b/index.html index 2d6cb62..7beb6b8 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ Javascript Finite State Machine - + @@ -32,8 +32,8 @@

Finite State Machine

- - + + diff --git a/lib/history.js b/lib/history.js new file mode 100644 index 0000000..d604994 --- /dev/null +++ b/lib/history.js @@ -0,0 +1,187 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachineHistory", [], factory); + else if(typeof exports === 'object') + exports["StateMachineHistory"] = factory(); + else + root["StateMachineHistory"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(label) { + var n, word, words = label.split(/[_-]/), result = words[0]; + for(n = 1 ; n < words.length ; n++) { + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + } + return result; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var camelize = __webpack_require__(0); + +//------------------------------------------------------------------------------------------------- + +module.exports = function(options) { options = options || {}; + + var past = camelize(options.name || options.past || 'history'), + future = camelize( options.future || 'future'), + clear = camelize('clear-' + past), + back = camelize(past + '-back'), + forward = camelize(past + '-forward'), + canBack = camelize('can-' + back), + canForward = camelize('can-' + forward), + max = options.max; + + var plugin = { + + configure: function(config) { + config.addTransitionLifecycleNames(back); + config.addTransitionLifecycleNames(forward); + }, + + init: function(instance) { + instance[past] = []; + instance[future] = []; + }, + + lifecycle: function(instance, lifecycle) { + if (lifecycle.event === 'onEnterState') { + instance[past].push(lifecycle.to); + if (max && instance[past].length > max) + instance[past].shift(); + if (lifecycle.transition !== back && lifecycle.transition !== forward) + instance[future].length = 0; + } + }, + + methods: {}, + properties: {} + + } + + plugin.methods[clear] = function() { + this[past].length = 0 + this[future].length = 0 + } + + plugin.properties[canBack] = { + get: function() { + return this[past].length > 1 + } + } + + plugin.properties[canForward] = { + get: function() { + return this[future].length > 0 + } + } + + plugin.methods[back] = function() { + if (!this[canBack]) + throw Error('no history'); + var from = this[past].pop(), + to = this[past].pop(); + this[future].push(from); + this._fsm.transit(back, from, to, []); + } + + plugin.methods[forward] = function() { + if (!this[canForward]) + throw Error('no history'); + var from = this.state, + to = this[future].pop(); + this._fsm.transit(forward, from, to, []); + } + + return plugin; + +} + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/lib/state-machine.js b/lib/state-machine.js new file mode 100644 index 0000000..6ac51b3 --- /dev/null +++ b/lib/state-machine.js @@ -0,0 +1,644 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachine", [], factory); + else if(typeof exports === 'object') + exports["StateMachine"] = factory(); + else + root["StateMachine"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 6); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(target, sources) { + var n, source, key; + for(n = 1 ; n < arguments.length ; n++) { + source = arguments[n]; + for(key in source) { + if (source.hasOwnProperty(key)) + target[key] = source[key]; + } + } + return target; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0); + +//------------------------------------------------------------------------------------------------- + +module.exports = { + + build: function(target, config) { + var n, max, plugin, plugins = config.plugins; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (plugin.methods) + mixin(target, plugin.methods); + if (plugin.properties) + Object.defineProperties(target, plugin.properties); + } + }, + + hook: function(fsm, name, additional) { + var n, max, method, plugin, + plugins = fsm.config.plugins, + args = [fsm.context]; + + if (additional) + args = args.concat(additional) + + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n] + method = plugins[n][name] + if (method) + method.apply(plugin, args); + } + } + +} + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(label) { + var n, word, words = label.split(/[_-]/), result = words[0]; + for(n = 1 ; n < words.length ; n++) { + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + } + return result; +} + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0), + camelize = __webpack_require__(2); + +//------------------------------------------------------------------------------------------------- + +function Config(options, StateMachine) { + + options = options || {}; + + this.source = options; // preserving original options helps with visualize plugin + this.defaults = StateMachine.defaults; + this.states = []; + this.transitions = []; + this.map = {}; + this.lifecycle = this.configureLifecycle(); + this.init = this.configureInitTransition(options.init); + this.data = this.configureData(options.data); + this.methods = this.configureMethods(options.methods); + + this.map[this.defaults.wildcard] = {}; + + this.configureTransitions(options.transitions || []); + + this.plugins = this.configurePlugins(options.plugins, StateMachine.plugin); + +} + +//------------------------------------------------------------------------------------------------- + +mixin(Config.prototype, { + + addState: function(name) { + if (!this.map[name]) { + this.states.push(name); + this.addStateLifecycleNames(name); + this.map[name] = {}; + } + }, + + addStateLifecycleNames: function(name) { + this.lifecycle.onEnter[name] = camelize('on-enter-' + name); + this.lifecycle.onLeave[name] = camelize('on-leave-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + addTransition: function(name) { + if (this.transitions.indexOf(name) < 0) { + this.transitions.push(name); + this.addTransitionLifecycleNames(name); + } + }, + + addTransitionLifecycleNames: function(name) { + this.lifecycle.onBefore[name] = camelize('on-before-' + name); + this.lifecycle.onAfter[name] = camelize('on-after-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + mapTransition: function(transition) { + var name = transition.name, + from = transition.from, + to = transition.to; + this.addState(from); + if (typeof to !== 'function') + this.addState(to); + this.addTransition(name); + this.map[from][name] = transition; + return transition; + }, + + configureLifecycle: function() { + return { + onBefore: { transition: camelize('on-before-transition') }, + onAfter: { transition: camelize('on-after-transition') }, + onEnter: { state: camelize('on-enter-state') }, + onLeave: { state: camelize('on-leave-state') }, + on: { transition: camelize('on-transition') } + }; + }, + + configureInitTransition: function(init) { + if (typeof init === 'string') { + return this.mapTransition(mixin({}, this.defaults.init, { to: init, active: true })); + } + else if (typeof init === 'object') { + return this.mapTransition(mixin({}, this.defaults.init, init, { active: true })); + } + else { + this.addState(this.defaults.init.from); + return this.defaults.init; + } + }, + + configureData: function(data) { + if (typeof data === 'function') + return data; + else if (typeof data === 'object') + return function() { return data; } + else + return function() { return {}; } + }, + + configureMethods: function(methods) { + return methods || {}; + }, + + configurePlugins: function(plugins, builtin) { + plugins = plugins || []; + var n, max, plugin; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (typeof plugin === 'function') + plugins[n] = plugin = plugin() + if (plugin.configure) + plugin.configure(this); + } + return plugins + }, + + configureTransitions: function(transitions) { + var i, n, transition, from, to, wildcard = this.defaults.wildcard; + for(n = 0 ; n < transitions.length ; n++) { + transition = transitions[n]; + from = Array.isArray(transition.from) ? transition.from : [transition.from || wildcard] + to = transition.to || wildcard; + for(i = 0 ; i < from.length ; i++) { + this.mapTransition({ name: transition.name, from: from[i], to: to }); + } + } + }, + + transitionFor: function(state, transition) { + var wildcard = this.defaults.wildcard; + return this.map[state][transition] || + this.map[wildcard][transition]; + }, + + transitionsFor: function(state) { + var wildcard = this.defaults.wildcard; + return Object.keys(this.map[state]).concat(Object.keys(this.map[wildcard])); + }, + + allStates: function() { + return this.states; + }, + + allTransitions: function() { + return this.transitions; + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = Config; + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + +var mixin = __webpack_require__(0), + Exception = __webpack_require__(5), + plugin = __webpack_require__(1), + UNOBSERVED = [ null, [] ]; + +//------------------------------------------------------------------------------------------------- + +function JSM(context, config) { + this.context = context; + this.config = config; + this.state = config.init.from; + this.observers = [context]; +} + +//------------------------------------------------------------------------------------------------- + +mixin(JSM.prototype, { + + init: function(args) { + mixin(this.context, this.config.data.apply(this.context, args)); + plugin.hook(this, 'init'); + if (this.config.init.active) + return this.fire(this.config.init.name, []); + }, + + is: function(state) { + return Array.isArray(state) ? (state.indexOf(this.state) >= 0) : (this.state === state); + }, + + isPending: function() { + return this.pending; + }, + + can: function(transition) { + return !this.isPending() && !!this.seek(transition); + }, + + cannot: function(transition) { + return !this.can(transition); + }, + + allStates: function() { + return this.config.allStates(); + }, + + allTransitions: function() { + return this.config.allTransitions(); + }, + + transitions: function() { + return this.config.transitionsFor(this.state); + }, + + seek: function(transition, args) { + var wildcard = this.config.defaults.wildcard, + entry = this.config.transitionFor(this.state, transition), + to = entry && entry.to; + if (typeof to === 'function') + return to.apply(this.context, args); + else if (to === wildcard) + return this.state + else + return to + }, + + fire: function(transition, args) { + return this.transit(transition, this.state, this.seek(transition, args), args); + }, + + transit: function(transition, from, to, args) { + + var lifecycle = this.config.lifecycle, + changed = from !== to; + + if (!to) + return this.context.onInvalidTransition(transition, from, to); + + if (this.isPending()) + return this.context.onPendingTransition(transition, from, to); + + this.config.addState(to); // might need to add this state if it's unknown (e.g. conditional transition or goto) + + this.beginTransit(); + + args.unshift({ // this context will be passed to each lifecycle event observer + transition: transition, + from: from, + to: to, + fsm: this.context + }); + + return this.observeEvents([ + this.observersForEvent(lifecycle.onBefore.transition), + this.observersForEvent(lifecycle.onBefore[transition]), + changed ? this.observersForEvent(lifecycle.onLeave.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onLeave[from]) : UNOBSERVED, + this.observersForEvent(lifecycle.on.transition), + changed ? [ 'doTransit', [ this ] ] : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter[to]) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.on[to]) : UNOBSERVED, + this.observersForEvent(lifecycle.onAfter.transition), + this.observersForEvent(lifecycle.onAfter[transition]), + this.observersForEvent(lifecycle.on[transition]) + ], args); + }, + + beginTransit: function() { this.pending = true; }, + endTransit: function(result) { this.pending = false; return result; }, + doTransit: function(lifecycle) { this.state = lifecycle.to; }, + + observe: function(args) { + if (args.length === 2) { + var observer = {}; + observer[args[0]] = args[1]; + this.observers.push(observer); + } + else { + this.observers.push(args[0]); + } + }, + + observersForEvent: function(event) { // TODO: this could be cached + var n = 0, max = this.observers.length, observer, result = []; + for( ; n < max ; n++) { + observer = this.observers[n]; + if (observer[event]) + result.push(observer); + } + return [ event, result, true ] + }, + + observeEvents: function(events, args, previousEvent) { + if (events.length === 0) { + return this.endTransit(true); + } + + var event = events[0][0], + observers = events[0][1], + pluggable = events[0][2]; + + args[0].event = event; + if (event && pluggable && event !== previousEvent) + plugin.hook(this, 'lifecycle', args); + + if (observers.length === 0) { + events.shift(); + return this.observeEvents(events, args, event); + } + else { + var observer = observers.shift(), + result = observer[event].apply(observer, args); + if (result && typeof result.then === 'function') { + return result.then(this.observeEvents.bind(this, events, args, event)) + .catch(this.endTransit.bind(this)) + } + else if (result === false) { + return this.endTransit(false); + } + else { + return this.observeEvents(events, args, event); + } + } + }, + + onInvalidTransition: function(transition, from, to) { + throw new Exception("transition is invalid in current state", transition, from, to, this.state); + }, + + onPendingTransition: function(transition, from, to) { + throw new Exception("transition is invalid while previous transition is still in progress", transition, from, to, this.state); + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = JSM; + +//------------------------------------------------------------------------------------------------- + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(message, transition, from, to, current) { + this.message = message; + this.transition = transition; + this.from = from; + this.to = to; + this.current = current; +} + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//----------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0), + camelize = __webpack_require__(2), + plugin = __webpack_require__(1), + Config = __webpack_require__(3), + JSM = __webpack_require__(4); + +//----------------------------------------------------------------------------------------------- + +var PublicMethods = { + is: function(state) { return this._fsm.is(state) }, + can: function(transition) { return this._fsm.can(transition) }, + cannot: function(transition) { return this._fsm.cannot(transition) }, + observe: function() { return this._fsm.observe(arguments) }, + transitions: function() { return this._fsm.transitions() }, + allTransitions: function() { return this._fsm.allTransitions() }, + allStates: function() { return this._fsm.allStates() }, + onInvalidTransition: function(t, from, to) { return this._fsm.onInvalidTransition(t, from, to) }, + onPendingTransition: function(t, from, to) { return this._fsm.onPendingTransition(t, from, to) }, +} + +var PublicProperties = { + state: { + configurable: false, + enumerable: true, + get: function() { + return this._fsm.state; + }, + set: function(state) { + throw Error('use transitions to change state') + } + } +} + +//----------------------------------------------------------------------------------------------- + +function StateMachine(options) { + return apply(this || {}, options); +} + +function factory() { + var cstor, options; + if (typeof arguments[0] === 'function') { + cstor = arguments[0]; + options = arguments[1] || {}; + } + else { + cstor = function() { this._fsm.apply(this, arguments) }; + options = arguments[0] || {}; + } + var config = new Config(options, StateMachine); + build(cstor.prototype, config); + cstor.prototype._fsm.config = config; // convenience access to shared config without needing an instance + return cstor; +} + +//------------------------------------------------------------------------------------------------- + +function apply(instance, options) { + var config = new Config(options, StateMachine); + build(instance, config); + instance._fsm(); + return instance; +} + +function build(target, config) { + if ((typeof target !== 'object') || Array.isArray(target)) + throw Error('StateMachine can only be applied to objects'); + plugin.build(target, config); + Object.defineProperties(target, PublicProperties); + mixin(target, PublicMethods); + mixin(target, config.methods); + config.allTransitions().forEach(function(transition) { + target[camelize(transition)] = function() { + return this._fsm.fire(transition, [].slice.call(arguments)) + } + }); + target._fsm = function() { + this._fsm = new JSM(this, config); + this._fsm.init(arguments); + } +} + +//----------------------------------------------------------------------------------------------- + +StateMachine.version = '3.0.0'; +StateMachine.factory = factory; +StateMachine.apply = apply; +StateMachine.defaults = { + wildcard: '*', + init: { + name: 'init', + from: 'none' + } +} + +//=============================================================================================== + +module.exports = StateMachine; + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/lib/visualize.js b/lib/visualize.js new file mode 100644 index 0000000..531bf03 --- /dev/null +++ b/lib/visualize.js @@ -0,0 +1,269 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("StateMachineVisualize", [], factory); + else if(typeof exports === 'object') + exports["StateMachineVisualize"] = factory(); + else + root["StateMachineVisualize"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(target, sources) { + var n, source, key; + for(n = 1 ; n < arguments.length ; n++) { + source = arguments[n]; + for(key in source) { + if (source.hasOwnProperty(key)) + target[key] = source[key]; + } + } + return target; +} + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + +"use strict"; + + +//------------------------------------------------------------------------------------------------- + +var mixin = __webpack_require__(0) + +//------------------------------------------------------------------------------------------------- + +function visualize(fsm, options) { + return dotify(dotcfg(fsm, options)); +} + +//------------------------------------------------------------------------------------------------- + +function dotcfg(fsm, options) { + + options = options || {} + + var config = dotcfg.fetch(fsm), + name = options.name, + rankdir = dotcfg.rankdir(options.orientation), + states = dotcfg.states(config, options), + transitions = dotcfg.transitions(config, options), + result = { } + + if (name) + result.name = name + + if (rankdir) + result.rankdir = rankdir + + if (states && states.length > 0) + result.states = states + + if (transitions && transitions.length > 0) + result.transitions = transitions + + return result +} + +//------------------------------------------------------------------------------------------------- + +dotcfg.fetch = function(fsm) { + return (typeof fsm === 'function') ? fsm.prototype._fsm.config + : fsm._fsm.config +} + +dotcfg.rankdir = function(orientation) { + if (orientation === 'horizontal') + return 'LR'; + else if (orientation === 'vertical') + return 'TB'; +} + +dotcfg.states = function(config, options) { + var index, states = config.states; + if (!options.init) { // if not showing init transition, then slice out the implied init :from state + index = states.indexOf(config.init.from); + states = states.slice(0, index).concat(states.slice(index+1)); + } + return states; +} + +dotcfg.transitions = function(config, options) { + var n, max, transition, + init = config.init, + transitions = config.source.transitions || [], // easier to visualize using the ORIGINAL transition declarations rather than our run-time mapping + output = []; + if (options.init && init.active) + dotcfg.transition(init.name, init.from, init.to, init.dot, config, options, output) + for (n = 0, max = transitions.length ; n < max ; n++) { + transition = config.source.transitions[n] + dotcfg.transition(transition.name, transition.from, transition.to, transition.dot, config, options, output) + } + return output +} + +dotcfg.transition = function(name, from, to, dot, config, options, output) { + var n, max, wildcard = config.defaults.wildcard + + if (Array.isArray(from)) { + for(n = 0, max = from.length ; n < max ; n++) + dotcfg.transition(name, from[n], to, dot, config, options, output) + } + else if (from === wildcard || from === undefined) { + for(n = 0, max = config.states.length ; n < max ; n++) + dotcfg.transition(name, config.states[n], to, dot, config, options, output) + } + else if (to === wildcard || to === undefined) { + dotcfg.transition(name, from, from, dot, config, options, output) + } + else if (typeof to === 'function') { + // do nothing, can't display conditional transition + } + else { + output.push(mixin({}, { from: from, to: to, label: pad(name) }, dot || {})) + } + +} + +//------------------------------------------------------------------------------------------------- + +function pad(name) { + return " " + name + " " +} + +function quote(name) { + return "\"" + name + "\"" +} + +function dotify(dotcfg) { + + dotcfg = dotcfg || {}; + + var name = dotcfg.name || 'fsm', + states = dotcfg.states || [], + transitions = dotcfg.transitions || [], + rankdir = dotcfg.rankdir, + output = [], + n, max; + + output.push("digraph " + quote(name) + " {") + if (rankdir) + output.push(" rankdir=" + rankdir + ";") + for(n = 0, max = states.length ; n < max ; n++) + output.push(dotify.state(states[n])) + for(n = 0, max = transitions.length ; n < max ; n++) + output.push(dotify.edge(transitions[n])) + output.push("}") + return output.join("\n") + +} + +dotify.state = function(state) { + return " " + quote(state) + ";" +} + +dotify.edge = function(edge) { + return " " + quote(edge.from) + " -> " + quote(edge.to) + dotify.edge.attr(edge) + ";" +} + +dotify.edge.attr = function(edge) { + var n, max, key, keys = Object.keys(edge).sort(), output = []; + for(n = 0, max = keys.length ; n < max ; n++) { + key = keys[n]; + if (key !== 'from' && key !== 'to') + output.push(key + "=" + quote(edge[key])) + } + return output.length > 0 ? " [ " + output.join(" ; ") + " ]" : "" +} + +//------------------------------------------------------------------------------------------------- + +visualize.dotcfg = dotcfg; +visualize.dotify = dotify; + +//------------------------------------------------------------------------------------------------- + +module.exports = visualize; + +//------------------------------------------------------------------------------------------------- + + +/***/ } +/******/ ]); +}); \ No newline at end of file diff --git a/package.json b/package.json index a350191..8d0f5b1 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,58 @@ { "name": "javascript-state-machine", - "description": "A simple finite state machine library", + "description": "A finite state machine library", "homepage": "https://github.com/jakesgordon/javascript-state-machine", + "repository": { + "type": "git", + "url": "git://github.com/jakesgordon/javascript-state-machine.git" + }, "keywords": [ + "finite state machine", "state machine", "server", "client" ], - "author": "Jake Gordon ", - "repository": { - "type": "git", - "url": "git://github.com/jakesgordon/javascript-state-machine.git" + "author": { + "name": "Jake Gordon", + "email": "jake@codeincomplete.com" }, - "main": "state-machine.js", + "maintainers": [ + { + "name": "Jake Gordon", + "email": "jake@codeincomplete.com" + } + ], + "license": "LGPL-3.0", + "main": "lib/state-machine.js", "files": [ - "state-machine.js", - "state-machine.min.js", - "LICENSE" + "lib/**/*.js", + "dist/**/*.js" ], + "directories": {}, "devDependencies": { - "local-web-server": "~1.2.6", - "qunit": "~0.9.1", - "uglify-js": "^2.7.4" + "ava": "^0.17.0", + "fs-sync": "^1.0.3", + "glob": "^7.1.1", + "nyc": "^10.0.0", + "pascal-case": "^2.0.0", + "uglify-js": "^2.7.5", + "webpack": "^2.2.0-rc.1" }, - "version": "2.4.0", + "version": "3.0.0", "scripts": { - "start": "ws --rewrite '/test -> /test/'", - "test": "node test/runner", - "minify": "uglifyjs state-machine.js --output state-machine.min.js --compress --mangle --stats" + "start": "npm run watch", + "build": "npm run bundle && npm run minify", + "bundle": "webpack", + "minify": "bin/minify", + "watch": "ava --watch", + "test": "nyc ava -v && nyc report --reporter=html" + }, + "ava": { + "files": [ + "test/**/*.js" + ], + "source": [ + "src/**/*.js" + ] } } diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..672c99f --- /dev/null +++ b/src/app.js @@ -0,0 +1,102 @@ +'use strict' + +//----------------------------------------------------------------------------------------------- + +var mixin = require('./util/mixin'), + camelize = require('./util/camelize'), + plugin = require('./plugin'), + Config = require('./config'), + JSM = require('./jsm'); + +//----------------------------------------------------------------------------------------------- + +var PublicMethods = { + is: function(state) { return this._fsm.is(state) }, + can: function(transition) { return this._fsm.can(transition) }, + cannot: function(transition) { return this._fsm.cannot(transition) }, + observe: function() { return this._fsm.observe(arguments) }, + transitions: function() { return this._fsm.transitions() }, + allTransitions: function() { return this._fsm.allTransitions() }, + allStates: function() { return this._fsm.allStates() }, + onInvalidTransition: function(t, from, to) { return this._fsm.onInvalidTransition(t, from, to) }, + onPendingTransition: function(t, from, to) { return this._fsm.onPendingTransition(t, from, to) }, +} + +var PublicProperties = { + state: { + configurable: false, + enumerable: true, + get: function() { + return this._fsm.state; + }, + set: function(state) { + throw Error('use transitions to change state') + } + } +} + +//----------------------------------------------------------------------------------------------- + +function StateMachine(options) { + return apply(this || {}, options); +} + +function factory() { + var cstor, options; + if (typeof arguments[0] === 'function') { + cstor = arguments[0]; + options = arguments[1] || {}; + } + else { + cstor = function() { this._fsm.apply(this, arguments) }; + options = arguments[0] || {}; + } + var config = new Config(options, StateMachine); + build(cstor.prototype, config); + cstor.prototype._fsm.config = config; // convenience access to shared config without needing an instance + return cstor; +} + +//------------------------------------------------------------------------------------------------- + +function apply(instance, options) { + var config = new Config(options, StateMachine); + build(instance, config); + instance._fsm(); + return instance; +} + +function build(target, config) { + if ((typeof target !== 'object') || Array.isArray(target)) + throw Error('StateMachine can only be applied to objects'); + plugin.build(target, config); + Object.defineProperties(target, PublicProperties); + mixin(target, PublicMethods); + mixin(target, config.methods); + config.allTransitions().forEach(function(transition) { + target[camelize(transition)] = function() { + return this._fsm.fire(transition, [].slice.call(arguments)) + } + }); + target._fsm = function() { + this._fsm = new JSM(this, config); + this._fsm.init(arguments); + } +} + +//----------------------------------------------------------------------------------------------- + +StateMachine.version = '3.0.0'; +StateMachine.factory = factory; +StateMachine.apply = apply; +StateMachine.defaults = { + wildcard: '*', + init: { + name: 'init', + from: 'none' + } +} + +//=============================================================================================== + +module.exports = StateMachine; diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..771a3d2 --- /dev/null +++ b/src/config.js @@ -0,0 +1,161 @@ +'use strict' + +//------------------------------------------------------------------------------------------------- + +var mixin = require('./util/mixin'), + camelize = require('./util/camelize'); + +//------------------------------------------------------------------------------------------------- + +function Config(options, StateMachine) { + + options = options || {}; + + this.source = options; // preserving original options helps with visualize plugin + this.defaults = StateMachine.defaults; + this.states = []; + this.transitions = []; + this.map = {}; + this.lifecycle = this.configureLifecycle(); + this.init = this.configureInitTransition(options.init); + this.data = this.configureData(options.data); + this.methods = this.configureMethods(options.methods); + + this.map[this.defaults.wildcard] = {}; + + this.configureTransitions(options.transitions || []); + + this.plugins = this.configurePlugins(options.plugins, StateMachine.plugin); + +} + +//------------------------------------------------------------------------------------------------- + +mixin(Config.prototype, { + + addState: function(name) { + if (!this.map[name]) { + this.states.push(name); + this.addStateLifecycleNames(name); + this.map[name] = {}; + } + }, + + addStateLifecycleNames: function(name) { + this.lifecycle.onEnter[name] = camelize('on-enter-' + name); + this.lifecycle.onLeave[name] = camelize('on-leave-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + addTransition: function(name) { + if (this.transitions.indexOf(name) < 0) { + this.transitions.push(name); + this.addTransitionLifecycleNames(name); + } + }, + + addTransitionLifecycleNames: function(name) { + this.lifecycle.onBefore[name] = camelize('on-before-' + name); + this.lifecycle.onAfter[name] = camelize('on-after-' + name); + this.lifecycle.on[name] = camelize('on-' + name); + }, + + mapTransition: function(transition) { + var name = transition.name, + from = transition.from, + to = transition.to; + this.addState(from); + if (typeof to !== 'function') + this.addState(to); + this.addTransition(name); + this.map[from][name] = transition; + return transition; + }, + + configureLifecycle: function() { + return { + onBefore: { transition: camelize('on-before-transition') }, + onAfter: { transition: camelize('on-after-transition') }, + onEnter: { state: camelize('on-enter-state') }, + onLeave: { state: camelize('on-leave-state') }, + on: { transition: camelize('on-transition') } + }; + }, + + configureInitTransition: function(init) { + if (typeof init === 'string') { + return this.mapTransition(mixin({}, this.defaults.init, { to: init, active: true })); + } + else if (typeof init === 'object') { + return this.mapTransition(mixin({}, this.defaults.init, init, { active: true })); + } + else { + this.addState(this.defaults.init.from); + return this.defaults.init; + } + }, + + configureData: function(data) { + if (typeof data === 'function') + return data; + else if (typeof data === 'object') + return function() { return data; } + else + return function() { return {}; } + }, + + configureMethods: function(methods) { + return methods || {}; + }, + + configurePlugins: function(plugins, builtin) { + plugins = plugins || []; + var n, max, plugin; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (typeof plugin === 'function') + plugins[n] = plugin = plugin() + if (plugin.configure) + plugin.configure(this); + } + return plugins + }, + + configureTransitions: function(transitions) { + var i, n, transition, from, to, wildcard = this.defaults.wildcard; + for(n = 0 ; n < transitions.length ; n++) { + transition = transitions[n]; + from = Array.isArray(transition.from) ? transition.from : [transition.from || wildcard] + to = transition.to || wildcard; + for(i = 0 ; i < from.length ; i++) { + this.mapTransition({ name: transition.name, from: from[i], to: to }); + } + } + }, + + transitionFor: function(state, transition) { + var wildcard = this.defaults.wildcard; + return this.map[state][transition] || + this.map[wildcard][transition]; + }, + + transitionsFor: function(state) { + var wildcard = this.defaults.wildcard; + return Object.keys(this.map[state]).concat(Object.keys(this.map[wildcard])); + }, + + allStates: function() { + return this.states; + }, + + allTransitions: function() { + return this.transitions; + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = Config; + +//------------------------------------------------------------------------------------------------- diff --git a/src/jsm.js b/src/jsm.js new file mode 100644 index 0000000..14eb805 --- /dev/null +++ b/src/jsm.js @@ -0,0 +1,181 @@ + +var mixin = require('./util/mixin'), + Exception = require('./util/exception'), + plugin = require('./plugin'), + UNOBSERVED = [ null, [] ]; + +//------------------------------------------------------------------------------------------------- + +function JSM(context, config) { + this.context = context; + this.config = config; + this.state = config.init.from; + this.observers = [context]; +} + +//------------------------------------------------------------------------------------------------- + +mixin(JSM.prototype, { + + init: function(args) { + mixin(this.context, this.config.data.apply(this.context, args)); + plugin.hook(this, 'init'); + if (this.config.init.active) + return this.fire(this.config.init.name, []); + }, + + is: function(state) { + return Array.isArray(state) ? (state.indexOf(this.state) >= 0) : (this.state === state); + }, + + isPending: function() { + return this.pending; + }, + + can: function(transition) { + return !this.isPending() && !!this.seek(transition); + }, + + cannot: function(transition) { + return !this.can(transition); + }, + + allStates: function() { + return this.config.allStates(); + }, + + allTransitions: function() { + return this.config.allTransitions(); + }, + + transitions: function() { + return this.config.transitionsFor(this.state); + }, + + seek: function(transition, args) { + var wildcard = this.config.defaults.wildcard, + entry = this.config.transitionFor(this.state, transition), + to = entry && entry.to; + if (typeof to === 'function') + return to.apply(this.context, args); + else if (to === wildcard) + return this.state + else + return to + }, + + fire: function(transition, args) { + return this.transit(transition, this.state, this.seek(transition, args), args); + }, + + transit: function(transition, from, to, args) { + + var lifecycle = this.config.lifecycle, + changed = from !== to; + + if (!to) + return this.context.onInvalidTransition(transition, from, to); + + if (this.isPending()) + return this.context.onPendingTransition(transition, from, to); + + this.config.addState(to); // might need to add this state if it's unknown (e.g. conditional transition or goto) + + this.beginTransit(); + + args.unshift({ // this context will be passed to each lifecycle event observer + transition: transition, + from: from, + to: to, + fsm: this.context + }); + + return this.observeEvents([ + this.observersForEvent(lifecycle.onBefore.transition), + this.observersForEvent(lifecycle.onBefore[transition]), + changed ? this.observersForEvent(lifecycle.onLeave.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onLeave[from]) : UNOBSERVED, + this.observersForEvent(lifecycle.on.transition), + changed ? [ 'doTransit', [ this ] ] : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter.state) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.onEnter[to]) : UNOBSERVED, + changed ? this.observersForEvent(lifecycle.on[to]) : UNOBSERVED, + this.observersForEvent(lifecycle.onAfter.transition), + this.observersForEvent(lifecycle.onAfter[transition]), + this.observersForEvent(lifecycle.on[transition]) + ], args); + }, + + beginTransit: function() { this.pending = true; }, + endTransit: function(result) { this.pending = false; return result; }, + doTransit: function(lifecycle) { this.state = lifecycle.to; }, + + observe: function(args) { + if (args.length === 2) { + var observer = {}; + observer[args[0]] = args[1]; + this.observers.push(observer); + } + else { + this.observers.push(args[0]); + } + }, + + observersForEvent: function(event) { // TODO: this could be cached + var n = 0, max = this.observers.length, observer, result = []; + for( ; n < max ; n++) { + observer = this.observers[n]; + if (observer[event]) + result.push(observer); + } + return [ event, result, true ] + }, + + observeEvents: function(events, args, previousEvent) { + if (events.length === 0) { + return this.endTransit(true); + } + + var event = events[0][0], + observers = events[0][1], + pluggable = events[0][2]; + + args[0].event = event; + if (event && pluggable && event !== previousEvent) + plugin.hook(this, 'lifecycle', args); + + if (observers.length === 0) { + events.shift(); + return this.observeEvents(events, args, event); + } + else { + var observer = observers.shift(), + result = observer[event].apply(observer, args); + if (result && typeof result.then === 'function') { + return result.then(this.observeEvents.bind(this, events, args, event)) + .catch(this.endTransit.bind(this)) + } + else if (result === false) { + return this.endTransit(false); + } + else { + return this.observeEvents(events, args, event); + } + } + }, + + onInvalidTransition: function(transition, from, to) { + throw new Exception("transition is invalid in current state", transition, from, to, this.state); + }, + + onPendingTransition: function(transition, from, to) { + throw new Exception("transition is invalid while previous transition is still in progress", transition, from, to, this.state); + } + +}); + +//------------------------------------------------------------------------------------------------- + +module.exports = JSM; + +//------------------------------------------------------------------------------------------------- diff --git a/src/plugin.js b/src/plugin.js new file mode 100644 index 0000000..491e25a --- /dev/null +++ b/src/plugin.js @@ -0,0 +1,40 @@ +'use strict' + +//------------------------------------------------------------------------------------------------- + +var mixin = require('./util/mixin'); + +//------------------------------------------------------------------------------------------------- + +module.exports = { + + build: function(target, config) { + var n, max, plugin, plugins = config.plugins; + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n]; + if (plugin.methods) + mixin(target, plugin.methods); + if (plugin.properties) + Object.defineProperties(target, plugin.properties); + } + }, + + hook: function(fsm, name, additional) { + var n, max, method, plugin, + plugins = fsm.config.plugins, + args = [fsm.context]; + + if (additional) + args = args.concat(additional) + + for(n = 0, max = plugins.length ; n < max ; n++) { + plugin = plugins[n] + method = plugins[n][name] + if (method) + method.apply(plugin, args); + } + } + +} + +//------------------------------------------------------------------------------------------------- diff --git a/src/plugin/history.js b/src/plugin/history.js new file mode 100644 index 0000000..ccfcd98 --- /dev/null +++ b/src/plugin/history.js @@ -0,0 +1,83 @@ +'use strict' + +//------------------------------------------------------------------------------------------------- + +var camelize = require('../util/camelize'); + +//------------------------------------------------------------------------------------------------- + +module.exports = function(options) { options = options || {}; + + var past = camelize(options.name || options.past || 'history'), + future = camelize( options.future || 'future'), + clear = camelize('clear-' + past), + back = camelize(past + '-back'), + forward = camelize(past + '-forward'), + canBack = camelize('can-' + back), + canForward = camelize('can-' + forward), + max = options.max; + + var plugin = { + + configure: function(config) { + config.addTransitionLifecycleNames(back); + config.addTransitionLifecycleNames(forward); + }, + + init: function(instance) { + instance[past] = []; + instance[future] = []; + }, + + lifecycle: function(instance, lifecycle) { + if (lifecycle.event === 'onEnterState') { + instance[past].push(lifecycle.to); + if (max && instance[past].length > max) + instance[past].shift(); + if (lifecycle.transition !== back && lifecycle.transition !== forward) + instance[future].length = 0; + } + }, + + methods: {}, + properties: {} + + } + + plugin.methods[clear] = function() { + this[past].length = 0 + this[future].length = 0 + } + + plugin.properties[canBack] = { + get: function() { + return this[past].length > 1 + } + } + + plugin.properties[canForward] = { + get: function() { + return this[future].length > 0 + } + } + + plugin.methods[back] = function() { + if (!this[canBack]) + throw Error('no history'); + var from = this[past].pop(), + to = this[past].pop(); + this[future].push(from); + this._fsm.transit(back, from, to, []); + } + + plugin.methods[forward] = function() { + if (!this[canForward]) + throw Error('no history'); + var from = this.state, + to = this[future].pop(); + this._fsm.transit(forward, from, to, []); + } + + return plugin; + +} diff --git a/src/plugin/visualize.js b/src/plugin/visualize.js new file mode 100644 index 0000000..3544ee9 --- /dev/null +++ b/src/plugin/visualize.js @@ -0,0 +1,161 @@ +'use strict' + +//------------------------------------------------------------------------------------------------- + +var mixin = require('../util/mixin') + +//------------------------------------------------------------------------------------------------- + +function visualize(fsm, options) { + return dotify(dotcfg(fsm, options)); +} + +//------------------------------------------------------------------------------------------------- + +function dotcfg(fsm, options) { + + options = options || {} + + var config = dotcfg.fetch(fsm), + name = options.name, + rankdir = dotcfg.rankdir(options.orientation), + states = dotcfg.states(config, options), + transitions = dotcfg.transitions(config, options), + result = { } + + if (name) + result.name = name + + if (rankdir) + result.rankdir = rankdir + + if (states && states.length > 0) + result.states = states + + if (transitions && transitions.length > 0) + result.transitions = transitions + + return result +} + +//------------------------------------------------------------------------------------------------- + +dotcfg.fetch = function(fsm) { + return (typeof fsm === 'function') ? fsm.prototype._fsm.config + : fsm._fsm.config +} + +dotcfg.rankdir = function(orientation) { + if (orientation === 'horizontal') + return 'LR'; + else if (orientation === 'vertical') + return 'TB'; +} + +dotcfg.states = function(config, options) { + var index, states = config.states; + if (!options.init) { // if not showing init transition, then slice out the implied init :from state + index = states.indexOf(config.init.from); + states = states.slice(0, index).concat(states.slice(index+1)); + } + return states; +} + +dotcfg.transitions = function(config, options) { + var n, max, transition, + init = config.init, + transitions = config.source.transitions || [], // easier to visualize using the ORIGINAL transition declarations rather than our run-time mapping + output = []; + if (options.init && init.active) + dotcfg.transition(init.name, init.from, init.to, init.dot, config, options, output) + for (n = 0, max = transitions.length ; n < max ; n++) { + transition = config.source.transitions[n] + dotcfg.transition(transition.name, transition.from, transition.to, transition.dot, config, options, output) + } + return output +} + +dotcfg.transition = function(name, from, to, dot, config, options, output) { + var n, max, wildcard = config.defaults.wildcard + + if (Array.isArray(from)) { + for(n = 0, max = from.length ; n < max ; n++) + dotcfg.transition(name, from[n], to, dot, config, options, output) + } + else if (from === wildcard || from === undefined) { + for(n = 0, max = config.states.length ; n < max ; n++) + dotcfg.transition(name, config.states[n], to, dot, config, options, output) + } + else if (to === wildcard || to === undefined) { + dotcfg.transition(name, from, from, dot, config, options, output) + } + else if (typeof to === 'function') { + // do nothing, can't display conditional transition + } + else { + output.push(mixin({}, { from: from, to: to, label: pad(name) }, dot || {})) + } + +} + +//------------------------------------------------------------------------------------------------- + +function pad(name) { + return " " + name + " " +} + +function quote(name) { + return "\"" + name + "\"" +} + +function dotify(dotcfg) { + + dotcfg = dotcfg || {}; + + var name = dotcfg.name || 'fsm', + states = dotcfg.states || [], + transitions = dotcfg.transitions || [], + rankdir = dotcfg.rankdir, + output = [], + n, max; + + output.push("digraph " + quote(name) + " {") + if (rankdir) + output.push(" rankdir=" + rankdir + ";") + for(n = 0, max = states.length ; n < max ; n++) + output.push(dotify.state(states[n])) + for(n = 0, max = transitions.length ; n < max ; n++) + output.push(dotify.edge(transitions[n])) + output.push("}") + return output.join("\n") + +} + +dotify.state = function(state) { + return " " + quote(state) + ";" +} + +dotify.edge = function(edge) { + return " " + quote(edge.from) + " -> " + quote(edge.to) + dotify.edge.attr(edge) + ";" +} + +dotify.edge.attr = function(edge) { + var n, max, key, keys = Object.keys(edge).sort(), output = []; + for(n = 0, max = keys.length ; n < max ; n++) { + key = keys[n]; + if (key !== 'from' && key !== 'to') + output.push(key + "=" + quote(edge[key])) + } + return output.length > 0 ? " [ " + output.join(" ; ") + " ]" : "" +} + +//------------------------------------------------------------------------------------------------- + +visualize.dotcfg = dotcfg; +visualize.dotify = dotify; + +//------------------------------------------------------------------------------------------------- + +module.exports = visualize; + +//------------------------------------------------------------------------------------------------- diff --git a/src/util/camelize.js b/src/util/camelize.js new file mode 100644 index 0000000..87c7540 --- /dev/null +++ b/src/util/camelize.js @@ -0,0 +1,9 @@ +'use strict' + +module.exports = function(label) { + var n, word, words = label.split(/[_-]/), result = words[0]; + for(n = 1 ; n < words.length ; n++) { + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + } + return result; +} diff --git a/src/util/exception.js b/src/util/exception.js new file mode 100644 index 0000000..cf62304 --- /dev/null +++ b/src/util/exception.js @@ -0,0 +1,9 @@ +'use strict' + +module.exports = function(message, transition, from, to, current) { + this.message = message; + this.transition = transition; + this.from = from; + this.to = to; + this.current = current; +} diff --git a/src/util/mixin.js b/src/util/mixin.js new file mode 100644 index 0000000..330664b --- /dev/null +++ b/src/util/mixin.js @@ -0,0 +1,13 @@ +'use strict' + +module.exports = function(target, sources) { + var n, source, key; + for(n = 1 ; n < arguments.length ; n++) { + source = arguments[n]; + for(key in source) { + if (source.hasOwnProperty(key)) + target[key] = source[key]; + } + } + return target; +} diff --git a/state-machine.js b/state-machine.js deleted file mode 100755 index e917a2a..0000000 --- a/state-machine.js +++ /dev/null @@ -1,230 +0,0 @@ -/* - - Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine - - Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors - Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE - -*/ - -(function () { - - var StateMachine = { - - //--------------------------------------------------------------------------- - - VERSION: "2.4.0", - - //--------------------------------------------------------------------------- - - Result: { - SUCCEEDED: 1, // the event transitioned successfully from one state to another - NOTRANSITION: 2, // the event was successfull but no state transition was necessary - CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback - PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs - }, - - Error: { - INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state - PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending - INVALID_CALLBACK: 300 // caller provided callback function threw an exception - }, - - WILDCARD: '*', - ASYNC: 'async', - - //--------------------------------------------------------------------------- - - create: function(cfg, target) { - - var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false } - var terminal = cfg.terminal || cfg['final']; - var fsm = target || cfg.target || {}; - var events = cfg.events || []; - var callbacks = cfg.callbacks || {}; - var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } } - var transitions = {}; // track events allowed from a state { state: [ event ] } - - var add = function(e) { - var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified - map[e.name] = map[e.name] || {}; - for (var n = 0 ; n < from.length ; n++) { - transitions[from[n]] = transitions[from[n]] || []; - transitions[from[n]].push(e.name); - - map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified - } - if (e.to) - transitions[e.to] = transitions[e.to] || []; - }; - - if (initial) { - initial.event = initial.event || 'startup'; - add({ name: initial.event, from: 'none', to: initial.state }); - } - - for(var n = 0 ; n < events.length ; n++) - add(events[n]); - - for(var name in map) { - if (map.hasOwnProperty(name)) - fsm[name] = StateMachine.buildEvent(name, map[name]); - } - - for(var name in callbacks) { - if (callbacks.hasOwnProperty(name)) - fsm[name] = callbacks[name] - } - - fsm.current = 'none'; - fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); }; - fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); } - fsm.cannot = function(event) { return !this.can(event); }; - fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); }; - fsm.isFinished = function() { return this.is(terminal); }; - fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17) - fsm.states = function() { return Object.keys(transitions).sort() }; - - if (initial && !initial.defer) - fsm[initial.event](); - - return fsm; - - }, - - //=========================================================================== - - doCallback: function(fsm, func, name, from, to, args) { - if (func) { - try { - return func.apply(fsm, [name, from, to].concat(args)); - } - catch(e) { - return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e); - } - } - }, - - beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); }, - afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); }, - leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); }, - enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); }, - changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); }, - - beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); }, - afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); }, - leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); }, - enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); }, - - beforeEvent: function(fsm, name, from, to, args) { - if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) || - (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args))) - return false; - }, - - afterEvent: function(fsm, name, from, to, args) { - StateMachine.afterThisEvent(fsm, name, from, to, args); - StateMachine.afterAnyEvent( fsm, name, from, to, args); - }, - - leaveState: function(fsm, name, from, to, args) { - var specific = StateMachine.leaveThisState(fsm, name, from, to, args), - general = StateMachine.leaveAnyState( fsm, name, from, to, args); - if ((false === specific) || (false === general)) - return false; - else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general)) - return StateMachine.ASYNC; - }, - - enterState: function(fsm, name, from, to, args) { - StateMachine.enterThisState(fsm, name, from, to, args); - StateMachine.enterAnyState( fsm, name, from, to, args); - }, - - //=========================================================================== - - buildEvent: function(name, map) { - return function() { - - var from = this.current; - var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from; - var args = Array.prototype.slice.call(arguments); // turn arguments into pure array - - if (this.transition) - return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete"); - - if (this.cannot(name)) - return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current); - - if (false === StateMachine.beforeEvent(this, name, from, to, args)) - return StateMachine.Result.CANCELLED; - - if (from === to) { - StateMachine.afterEvent(this, name, from, to, args); - return StateMachine.Result.NOTRANSITION; - } - - // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState) - var fsm = this; - this.transition = function() { - fsm.transition = null; // this method should only ever be called once - fsm.current = to; - StateMachine.enterState( fsm, name, from, to, args); - StateMachine.changeState(fsm, name, from, to, args); - StateMachine.afterEvent( fsm, name, from, to, args); - return StateMachine.Result.SUCCEEDED; - }; - this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22) - fsm.transition = null; - StateMachine.afterEvent(fsm, name, from, to, args); - } - - var leave = StateMachine.leaveState(this, name, from, to, args); - if (false === leave) { - this.transition = null; - return StateMachine.Result.CANCELLED; - } - else if (StateMachine.ASYNC === leave) { - return StateMachine.Result.PENDING; - } - else { - if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC - return this.transition(); - } - - }; - } - - }; // StateMachine - - //=========================================================================== - - //====== - // NODE - //====== - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = StateMachine; - } - exports.StateMachine = StateMachine; - } - //============ - // AMD/REQUIRE - //============ - else if (typeof define === 'function' && define.amd) { - define(function(require) { return StateMachine; }); - } - //======== - // BROWSER - //======== - else if (typeof window !== 'undefined') { - window.StateMachine = StateMachine; - } - //=========== - // WEB WORKER - //=========== - else if (typeof self !== 'undefined') { - self.StateMachine = StateMachine; - } - -}()); diff --git a/state-machine.min.js b/state-machine.min.js deleted file mode 100644 index 9093160..0000000 --- a/state-machine.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){var t={VERSION:"2.4.0",Result:{SUCCEEDED:1,NOTRANSITION:2,CANCELLED:3,PENDING:4},Error:{INVALID_TRANSITION:100,PENDING_TRANSITION:200,INVALID_CALLBACK:300},WILDCARD:"*",ASYNC:"async",create:function(e,n){var r="string"==typeof e.initial?{state:e.initial}:e.initial,i=e.terminal||e.final,a=n||e.target||{},o=e.events||[],u=e.callbacks||{},s={},c={},f=function(e){var n=Array.isArray(e.from)?e.from:e.from?[e.from]:[t.WILDCARD];s[e.name]=s[e.name]||{};for(var r=0;r=0:this.current===t},a.can=function(e){return!this.transition&&void 0!==s[e]&&(s[e].hasOwnProperty(this.current)||s[e].hasOwnProperty(t.WILDCARD))},a.cannot=function(t){return!this.can(t)},a.transitions=function(){return(c[this.current]||[]).concat(c[t.WILDCARD]||[])},a.isFinished=function(){return this.is(i)},a.error=e.error||function(t,e,n,r,i,a,o){throw o||a},a.states=function(){return Object.keys(c).sort()},r&&!r.defer&&a[r.event](),a},doCallback:function(e,n,r,i,a,o){if(n)try{return n.apply(e,[r,i,a].concat(o))}catch(n){return e.error(r,i,a,o,t.Error.INVALID_CALLBACK,"an exception occurred in a caller-provided callback function",n)}},beforeAnyEvent:function(e,n,r,i,a){return t.doCallback(e,e.onbeforeevent,n,r,i,a)},afterAnyEvent:function(e,n,r,i,a){return t.doCallback(e,e.onafterevent||e.onevent,n,r,i,a)},leaveAnyState:function(e,n,r,i,a){return t.doCallback(e,e.onleavestate,n,r,i,a)},enterAnyState:function(e,n,r,i,a){return t.doCallback(e,e.onenterstate||e.onstate,n,r,i,a)},changeState:function(e,n,r,i,a){return t.doCallback(e,e.onchangestate,n,r,i,a)},beforeThisEvent:function(e,n,r,i,a){return t.doCallback(e,e["onbefore"+n],n,r,i,a)},afterThisEvent:function(e,n,r,i,a){return t.doCallback(e,e["onafter"+n]||e["on"+n],n,r,i,a)},leaveThisState:function(e,n,r,i,a){return t.doCallback(e,e["onleave"+r],n,r,i,a)},enterThisState:function(e,n,r,i,a){return t.doCallback(e,e["onenter"+i]||e["on"+i],n,r,i,a)},beforeEvent:function(e,n,r,i,a){if(!1===t.beforeThisEvent(e,n,r,i,a)||!1===t.beforeAnyEvent(e,n,r,i,a))return!1},afterEvent:function(e,n,r,i,a){t.afterThisEvent(e,n,r,i,a),t.afterAnyEvent(e,n,r,i,a)},leaveState:function(e,n,r,i,a){var o=t.leaveThisState(e,n,r,i,a),u=t.leaveAnyState(e,n,r,i,a);return!1!==o&&!1!==u&&(t.ASYNC===o||t.ASYNC===u?t.ASYNC:void 0)},enterState:function(e,n,r,i,a){t.enterThisState(e,n,r,i,a),t.enterAnyState(e,n,r,i,a)},buildEvent:function(e,n){return function(){var r=this.current,i=n[r]||(n[t.WILDCARD]!=t.WILDCARD?n[t.WILDCARD]:r)||r,a=Array.prototype.slice.call(arguments);if(this.transition)return this.error(e,r,i,a,t.Error.PENDING_TRANSITION,"event "+e+" inappropriate because previous transition did not complete");if(this.cannot(e))return this.error(e,r,i,a,t.Error.INVALID_TRANSITION,"event "+e+" inappropriate in current state "+this.current);if(!1===t.beforeEvent(this,e,r,i,a))return t.Result.CANCELLED;if(r===i)return t.afterEvent(this,e,r,i,a),t.Result.NOTRANSITION;var o=this;this.transition=function(){return o.transition=null,o.current=i,t.enterState(o,e,r,i,a),t.changeState(o,e,r,i,a),t.afterEvent(o,e,r,i,a),t.Result.SUCCEEDED},this.transition.cancel=function(){o.transition=null,t.afterEvent(o,e,r,i,a)};var u=t.leaveState(this,e,r,i,a);return!1===u?(this.transition=null,t.Result.CANCELLED):t.ASYNC===u?t.Result.PENDING:this.transition?this.transition():void 0}}};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=t),exports.StateMachine=t):"function"==typeof define&&define.amd?define(function(e){return t}):"undefined"!=typeof window?window.StateMachine=t:"undefined"!=typeof self&&(self.StateMachine=t)}(); \ No newline at end of file diff --git a/test/basics.js b/test/basics.js new file mode 100644 index 0000000..fdd2fc4 --- /dev/null +++ b/test/basics.js @@ -0,0 +1,130 @@ +import test from 'ava'; +import StateMachine from '../src/app'; + +//------------------------------------------------------------------------------------------------- + +test('version', t => { + t.is(StateMachine.version, '3.0.0'); +}); + +//------------------------------------------------------------------------------------------------- + +test('state machine', t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' } + ] + }) + + t.is(fsm.state, 'green') + + fsm.warn(); t.is(fsm.state, 'yellow') + fsm.panic(); t.is(fsm.state, 'red') + fsm.calm(); t.is(fsm.state, 'yellow') + fsm.clear(); t.is(fsm.state, 'green') + +}); + +//----------------------------------------------------------------------------- + +test('state machine factory', t => { + + var Alarm = StateMachine.factory({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' } + ] + }), + a = new Alarm(), + b = new Alarm(); + + t.is(a.state, 'green') + t.is(b.state, 'green') + + a.warn(); t.is(a.state, 'yellow'); t.is(b.state, 'green') + a.panic(); t.is(a.state, 'red'); t.is(b.state, 'green') + a.calm(); t.is(a.state, 'yellow'); t.is(b.state, 'green') + a.clear(); t.is(a.state, 'green'); t.is(b.state, 'green') + + b.warn(); t.is(a.state, 'green'); t.is(b.state, 'yellow') + b.panic(); t.is(a.state, 'green'); t.is(b.state, 'red') + b.calm(); t.is(a.state, 'green'); t.is(b.state, 'yellow') + b.clear(); t.is(a.state, 'green'); t.is(b.state, 'green') + +}); + +//----------------------------------------------------------------------------- + +test('state machine - applied to existing object', t => { + + var obj = { name: 'alarm' } + + StateMachine.apply(obj, { + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' } + ] + }); + + t.is(obj.name, 'alarm'); + t.is(obj.state, 'green'); + + obj.warn(); t.is(obj.state, 'yellow') + obj.panic(); t.is(obj.state, 'red') + obj.calm(); t.is(obj.state, 'yellow') + obj.clear(); t.is(obj.state, 'green') + +}); + +//----------------------------------------------------------------------------- + +test('state machine factory - applied to existing class', t => { + + function Alarm(name) { + this.name = name + this._fsm(); // manual step needed to construct this FSM instance + } + + StateMachine.factory(Alarm, { + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' } + ] + }); + + var a = new Alarm('A'), + b = new Alarm('B'); + + t.is(a.name, 'A') + t.is(b.name, 'B') + + t.is(a.state, 'green') + t.is(b.state, 'green') + + a.warn(); t.is(a.state, 'yellow'); t.is(b.state, 'green') + a.panic(); t.is(a.state, 'red'); t.is(b.state, 'green') + a.calm(); t.is(a.state, 'yellow'); t.is(b.state, 'green') + a.clear(); t.is(a.state, 'green'); t.is(b.state, 'green') + + b.warn(); t.is(a.state, 'green'); t.is(b.state, 'yellow') + b.panic(); t.is(a.state, 'green'); t.is(b.state, 'red') + b.calm(); t.is(a.state, 'green'); t.is(b.state, 'yellow') + b.clear(); t.is(a.state, 'green'); t.is(b.state, 'green') + +}); + +//----------------------------------------------------------------------------- diff --git a/test/construction.js b/test/construction.js new file mode 100644 index 0000000..911b5a3 --- /dev/null +++ b/test/construction.js @@ -0,0 +1,229 @@ +import test from 'ava' +import StateMachine from '../src/app' + +//------------------------------------------------------------------------------------------------- + +test('singleton construction', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'init', from: 'none', to: 'A' }, + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'none') + + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm.transitions(), [ 'init' ]) + +}) + + +//------------------------------------------------------------------------------------------------- + +test('singleton construction - with init state', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'A') + + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm.transitions(), [ 'step1' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('singleton construction - with init state and transition', t => { + + var fsm = new StateMachine({ + init: { name: 'boot', to: 'A' }, + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'A') + + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm.allTransitions(), [ 'boot', 'step1', 'step2' ]) + t.deepEqual(fsm.transitions(), [ 'step1' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('singleton construction - with init state, transition, AND from state', t => { + + var fsm = new StateMachine({ + init: { name: 'boot', from: 'booting', to: 'A' }, + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'A') + + t.deepEqual(fsm.allStates(), [ 'booting', 'A', 'B', 'C' ]) + t.deepEqual(fsm.allTransitions(), [ 'boot', 'step1', 'step2' ]) + t.deepEqual(fsm.transitions(), [ 'step1' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('singleton construction - with custom data and methods', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ], + data: { + value: 42 + }, + methods: { + talk: function() { + return this.state + ' - ' + this.value + } + } + }); + + t.is(fsm.state, 'A') + t.is(fsm.value, 42) + t.is(fsm.talk(), 'A - 42') + + fsm.step1() + + t.is(fsm.state, 'B') + t.is(fsm.value, 42) + t.is(fsm.talk(), 'B - 42') + + fsm.value = 99 + + t.is(fsm.state, 'B') + t.is(fsm.value, 99) + t.is(fsm.talk(), 'B - 99') + +}) + +//------------------------------------------------------------------------------------------------- + +test('factory construction', t => { + + var MyClass = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + var fsm1 = new MyClass(), + fsm2 = new MyClass(), + fsm3 = new MyClass(); + + fsm2.step1() + fsm3.step1() + fsm3.step2() + + t.is(fsm1.state, 'A') + t.is(fsm2.state, 'B') + t.is(fsm3.state, 'C') + + t.deepEqual(fsm1.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm2.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm3.allStates(), [ 'none', 'A', 'B', 'C' ]) + + t.deepEqual(fsm1.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm2.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm3.allTransitions(), [ 'init', 'step1', 'step2' ]) + + t.deepEqual(fsm1.transitions(), [ 'step1' ]) + t.deepEqual(fsm2.transitions(), [ 'step2' ]) + t.deepEqual(fsm3.transitions(), [ ]) + + t.is(fsm1.allStates, MyClass.prototype.allStates) + t.is(fsm2.allStates, MyClass.prototype.allStates) + t.is(fsm3.allStates, MyClass.prototype.allStates) + +}) + +//------------------------------------------------------------------------------------------------- + +test('factory construction - with custom data and methods', t => { + + var MyClass = StateMachine.factory({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ], + data: function(value) { + return { + value: value + } + }, + methods: { + talk: function() { + return this.state + ' - ' + this.value + } + } + }); + + var fsm1 = new MyClass(1), + fsm2 = new MyClass(2), + fsm3 = new MyClass(3); + + t.is(fsm1.state, 'A') + t.is(fsm2.state, 'A') + t.is(fsm3.state, 'A') + + t.is(fsm1.talk(), 'A - 1') + t.is(fsm2.talk(), 'A - 2') + t.is(fsm3.talk(), 'A - 3') + + fsm2.step1() + fsm3.step1() + fsm3.step2() + + t.is(fsm1.state, 'A') + t.is(fsm2.state, 'B') + t.is(fsm3.state, 'C') + + t.is(fsm1.talk(), 'A - 1') + t.is(fsm2.talk(), 'B - 2') + t.is(fsm3.talk(), 'C - 3') + + t.deepEqual(fsm1.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm2.allStates(), [ 'none', 'A', 'B', 'C' ]) + t.deepEqual(fsm3.allStates(), [ 'none', 'A', 'B', 'C' ]) + + t.deepEqual(fsm1.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm2.allTransitions(), [ 'init', 'step1', 'step2' ]) + t.deepEqual(fsm3.allTransitions(), [ 'init', 'step1', 'step2' ]) + + t.deepEqual(fsm1.transitions(), [ 'step1' ]) + t.deepEqual(fsm2.transitions(), [ 'step2' ]) + t.deepEqual(fsm3.transitions(), [ ]) + + t.is(fsm1.allStates, MyClass.prototype.allStates) + t.is(fsm2.allStates, MyClass.prototype.allStates) + t.is(fsm3.allStates, MyClass.prototype.allStates) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/defaults.js b/test/defaults.js new file mode 100644 index 0000000..da1bc08 --- /dev/null +++ b/test/defaults.js @@ -0,0 +1,62 @@ +import test from 'ava'; +import StateMachine from '../src/app'; + +//------------------------------------------------------------------------------------------------- + +const defaults = JSON.stringify(StateMachine.defaults); + +test.afterEach.always('restore defaults', t => { + StateMachine.defaults = JSON.parse(defaults); +}); + +//------------------------------------------------------------------------------------------------- + +test.serial('override global initialization defaults', t => { + + StateMachine.defaults.init = { + name: 'boot', + from: 'booting' + } + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'A'); + + t.deepEqual(fsm.allStates(), [ 'booting', 'A', 'B', 'C' ]); + t.deepEqual(fsm.allTransitions(), [ 'boot', 'step1', 'step2' ]); + t.deepEqual(fsm.transitions(), [ 'step1' ]); + +}); + +//------------------------------------------------------------------------------------------------- + +test.serial('override global initialization defaults (again)', t => { + + StateMachine.defaults.init = { + name: 'start', + from: 'unknown' + } + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' } + ] + }); + + t.is(fsm.state, 'A'); + + t.deepEqual(fsm.allStates(), [ 'unknown', 'A', 'B', 'C' ]); + t.deepEqual(fsm.allTransitions(), [ 'start', 'step1', 'step2' ]); + t.deepEqual(fsm.transitions(), [ 'step1' ]); + +}); + +//------------------------------------------------------------------------------------------------- diff --git a/test/empty.js b/test/empty.js new file mode 100644 index 0000000..ad2ce62 --- /dev/null +++ b/test/empty.js @@ -0,0 +1,79 @@ +import test from 'ava' +import StateMachine from '../src/app' + +//------------------------------------------------------------------------------------------------- + +test('empty state machine', t => { + + var fsm = new StateMachine(); + + t.is(fsm.state, 'none') + + t.deepEqual(fsm.allStates(), [ 'none' ]) + t.deepEqual(fsm.allTransitions(), [ ]) + t.deepEqual(fsm.transitions(), [ ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('empty state machine - but caller forgot new keyword', t => { + + var fsm = StateMachine() // NOTE: missing 'new' + + t.is(fsm.state, 'none') + + t.deepEqual(fsm.allStates(), [ 'none' ]) + t.deepEqual(fsm.allTransitions(), [ ]) + t.deepEqual(fsm.transitions(), [ ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('empty state machine - applied to existing object', t => { + + var fsm = {}; + + StateMachine.apply(fsm) + + t.is(fsm.state, 'none') + + t.deepEqual(fsm.allStates(), [ 'none' ]) + t.deepEqual(fsm.allTransitions(), [ ]) + t.deepEqual(fsm.transitions(), [ ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('empty state machine factory', t => { + + var FSM = StateMachine.factory(), + fsm = new FSM(); + + t.is(fsm.state, 'none') + t.deepEqual(fsm.allStates(), [ 'none' ]) + t.deepEqual(fsm.allTransitions(), [ ]) + t.deepEqual(fsm.transitions(), [ ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('empty state machine factory - applied to existing class', t => { + + var FSM = function() { this._fsm() }; + + StateMachine.factory(FSM) + + var fsm = new FSM() + + t.is(fsm.state, 'none') + t.deepEqual(fsm.allStates(), [ 'none' ]) + t.deepEqual(fsm.allTransitions(), [ ]) + t.deepEqual(fsm.transitions(), [ ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/errors.js b/test/errors.js new file mode 100644 index 0000000..fb852ca --- /dev/null +++ b/test/errors.js @@ -0,0 +1,160 @@ +import test from 'ava' +import StateMachine from '../src/app' + +//------------------------------------------------------------------------------------------------- + +test('state cannot be modified directly', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }) + + t.is(fsm.state, 'none') + var error = t.throws(() => { + fsm.state = 'other' + }) + t.is(error.message, 'use transitions to change state') + t.is(fsm.state, 'none') + +}) + +//------------------------------------------------------------------------------------------------- + +test('StateMachine.apply only allowed on objects', t => { + + var config = { + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }; + + var error = t.throws(() => { + StateMachine.apply(function() {}, config) + }) + t.is(error.message, 'StateMachine can only be applied to objects') + + error = t.throws(() => { + StateMachine.apply([], config) + }) + t.is(error.message, 'StateMachine can only be applied to objects') + + error = t.throws(() => { + StateMachine.apply(42, config) + }) + t.is(error.message, 'StateMachine can only be applied to objects') + +}) + +//------------------------------------------------------------------------------------------------- + +test('invalid transition raises an exception', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step1', from: 'none', to: 'A' }, + { name: 'step2', from: 'A', to: 'B' } + ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.can('step1'), true) + t.is(fsm.can('step2'), false) + + const error = t.throws(() => { + fsm.step2(); + }) + + t.is(error.message, 'transition is invalid in current state') + t.is(error.transition, 'step2') + t.is(error.from, 'none') + t.is(error.to, undefined) + t.is(error.current, 'none') + +}) + +//------------------------------------------------------------------------------------------------- + +test('invalid transition handler can be customized', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step1', from: 'none', to: 'A' }, + { name: 'step2', from: 'A', to: 'B' } + ], + methods: { + onInvalidTransition: function() { return 'custom error'; } + } + }); + + t.is(fsm.state, 'none') + t.is(fsm.can('step1'), true) + t.is(fsm.can('step2'), false) + t.is(fsm.step2(), 'custom error') + t.is(fsm.state, 'none') + +}) + +//------------------------------------------------------------------------------------------------- + +test('fire transition while existing transition is still in process raises an exception', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'A' }, + { name: 'other', from: '*', to: 'X' } + ], + methods: { + onBeforeStep: function() { this.other(); }, + onBeforeOther: function() { t.fail('should never happen') }, + onEnterX: function() { t.fail('should never happen') } + } + }); + + t.is(fsm.state, 'none') + t.is(fsm.can('step'), true) + t.is(fsm.can('other'), true) + + const error = t.throws(() => { + fsm.step() + }) + + t.is(error.message, 'transition is invalid while previous transition is still in progress') + t.is(error.transition, 'other') + t.is(error.from, 'none') + t.is(error.to, 'X') + t.is(error.current, 'none') + + t.is(fsm.state, 'none', 'entire transition was cancelled by the exception') + +}) + +//------------------------------------------------------------------------------------------------- + +test('pending transition handler can be customized', t => { + + var error = "", + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'A' }, + { name: 'other', from: '*', to: 'X' } + ], + methods: { + onBeforeStep: function() { error = this.other(); return false }, + onPendingTransition: function() { return 'custom error' }, + onBeforeOther: function() { t.fail('should never happen') }, + onEnterX: function() { t.fail('should never happen') } + } + }); + + t.is(fsm.state, 'none') + t.is(fsm.can('step'), true) + t.is(fsm.can('other'), true) + t.is(fsm.step(), false) + t.is(fsm.state, 'none') + t.is(error, 'custom error') + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/goto.js b/test/goto.js new file mode 100644 index 0000000..e8fcbcc --- /dev/null +++ b/test/goto.js @@ -0,0 +1,195 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +function goto(state) { + return state +} + +//------------------------------------------------------------------------------------------------- + +test('goto transition', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'goto', from: '*', to: goto } + ], + methods: { + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeStep: logger, + onBeforeGoto: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveA: logger, + onLeaveB: logger, + onLeaveC: logger, + onLeaveD: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterA: logger, + onEnterB: logger, + onEnterC: logger, + onEnterD: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterStep: logger, + onAfterGoto: logger + } + }); + + t.is(fsm.state, 'A') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.allTransitions(), [ 'init', 'step', 'goto' ]) + + logger.clear() + + fsm.goto('C') + + t.is(fsm.state, 'C') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'goto', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onBeforeGoto', transition: 'goto', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onLeaveState', transition: 'goto', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onLeaveA', transition: 'goto', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onTransition', transition: 'goto', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onEnterState', transition: 'goto', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onEnterC', transition: 'goto', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onAfterTransition', transition: 'goto', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onAfterGoto', transition: 'goto', from: 'A', to: 'C', current: 'C', args: [ 'C' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('goto can have additional arguments', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'goto', from: '*', to: goto } + ], + methods: { + onStep: logger, + onGoto: logger + } + }); + + t.is(fsm.state, 'A') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.allTransitions(), [ 'init', 'step', 'goto' ]) + + logger.clear() + + fsm.goto('C', 'with', 4, 'additional', 'arguments') + + t.is(fsm.state, 'C') + t.deepEqual(logger.log, [ + { event: 'onGoto', transition: 'goto', from: 'A', to: 'C', current: 'C', args: [ 'C', 'with', 4, 'additional', 'arguments' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('goto can go to an unknown state', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'goto', from: '*', to: goto } + ] + }) + + t.is(fsm.state, 'A') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D' ]); + + fsm.goto('B') + t.is(fsm.state, 'B') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D' ]); + + fsm.goto('X') + t.is(fsm.state, 'X') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D', 'X' ]); + +}) + +//------------------------------------------------------------------------------------------------- + +test('goto can be configured with a custom name', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'jump', from: '*', to: goto } + ], + methods: { + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeStep: logger, + onBeforeJump: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveA: logger, + onLeaveB: logger, + onLeaveC: logger, + onLeaveD: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterA: logger, + onEnterB: logger, + onEnterC: logger, + onEnterD: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterStep: logger, + onAfterJump: logger + } + }); + + t.is(fsm.state, 'A') + t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.allTransitions(), [ 'init', 'step', 'jump' ]) + t.is(fsm.goto, undefined) + + logger.clear() + + fsm.jump('C') + + t.is(fsm.state, 'C') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'jump', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onBeforeJump', transition: 'jump', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onLeaveState', transition: 'jump', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onLeaveA', transition: 'jump', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onTransition', transition: 'jump', from: 'A', to: 'C', current: 'A', args: [ 'C' ] }, + { event: 'onEnterState', transition: 'jump', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onEnterC', transition: 'jump', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onAfterTransition', transition: 'jump', from: 'A', to: 'C', current: 'C', args: [ 'C' ] }, + { event: 'onAfterJump', transition: 'jump', from: 'A', to: 'C', current: 'C', args: [ 'C' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/helpers/lifecycle_logger.js b/test/helpers/lifecycle_logger.js new file mode 100644 index 0000000..c74d229 --- /dev/null +++ b/test/helpers/lifecycle_logger.js @@ -0,0 +1,25 @@ + +module.exports = function() { + + let entries = [], + logger = function(lifecycle) { + var entry = { + event: lifecycle.event, + transition: lifecycle.transition, + from: lifecycle.from, + to: lifecycle.to, + current: lifecycle.fsm.state + } + if (arguments.length > 1) + entry.args = [].slice.call(arguments, 1); + entries.push(entry); + }; + + logger.clear = function() { + entries.length = 0; + } + + logger.log = entries; + + return logger; +} diff --git a/test/index.html b/test/index.html deleted file mode 100755 index 2cc8628..0000000 --- a/test/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - Finite State Machine Tests - - - - - - - - - - -

QUnit Test Suite

-

-
-

-
    -
    test markup
    - - diff --git a/test/introspection.js b/test/introspection.js new file mode 100644 index 0000000..be9e176 --- /dev/null +++ b/test/introspection.js @@ -0,0 +1,204 @@ +import test from 'ava'; +import StateMachine from '../src/app'; + +//----------------------------------------------------------------------------- + +test('is', t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' } + ]}); + + t.is(fsm.state, 'green') + + t.is(fsm.is('green'), true) + t.is(fsm.is('yellow'), false) + t.is(fsm.is(['green', 'red']), true, 'current state should match when included in array') + t.is(fsm.is(['yellow', 'red']), false, 'current state should NOT match when not included in array') + + fsm.warn() + + t.is(fsm.state, 'yellow') + t.is(fsm.is('green'), false) + t.is(fsm.is('yellow'), true) + t.is(fsm.is(['green', 'red']), false, 'current state should NOT match when not included in array') + t.is(fsm.is(['yellow', 'red']), true, 'current state should match when included in array') + +}); + +//----------------------------------------------------------------------------- + +test('can & cannot', t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + ] + }); + + t.is(fsm.state, 'green') + t.is(fsm.can('warn'), true) + t.is(fsm.can('panic'), false) + t.is(fsm.can('calm'), false) + t.is(fsm.cannot('warn'), false) + t.is(fsm.cannot('panic'), true) + t.is(fsm.cannot('calm'), true) + + fsm.warn(); + t.is(fsm.state, 'yellow') + t.is(fsm.can('warn'), false) + t.is(fsm.can('panic'), true) + t.is(fsm.can('calm'), false) + t.is(fsm.cannot('warn'), true) + t.is(fsm.cannot('panic'), false) + t.is(fsm.cannot('calm'), true) + + fsm.panic(); + t.is(fsm.state, 'red') + t.is(fsm.can('warn'), false) + t.is(fsm.can('panic'), false) + t.is(fsm.can('calm'), true) + t.is(fsm.cannot('warn'), true) + t.is(fsm.cannot('panic'), true) + t.is(fsm.cannot('calm'), false) + + t.is(fsm.can('jibber'), false, "unknown event should not crash") + t.is(fsm.cannot('jabber'), true, "unknown event should not crash") + +}); + +//----------------------------------------------------------------------------- + +test('can is always false during lifecycle events', t => { + + t.plan(81); + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + ], + methods: { + assertTransitionsNotAllowed: function() { + t.false(this.can('warn')) + t.false(this.can('panic')) + t.false(this.can('calm')) + }, + onBeforeTransition: function() { this.assertTransitionsNotAllowed(); }, + onBeforeWarn: function() { this.assertTransitionsNotAllowed(); }, + onBeforePanic: function() { this.assertTransitionsNotAllowed(); }, + onBeforeCalm: function() { this.assertTransitionsNotAllowed(); }, + onLeaveState: function() { this.assertTransitionsNotAllowed(); }, + onLeaveNone: function() { this.assertTransitionsNotAllowed(); }, + onLeaveGreen: function() { this.assertTransitionsNotAllowed(); }, + onLeaveYellow: function() { this.assertTransitionsNotAllowed(); }, + onLeaveRed: function() { this.assertTransitionsNotAllowed(); }, + onTransition: function() { this.assertTransitionsNotAllowed(); }, + onEnterState: function() { this.assertTransitionsNotAllowed(); }, + onEnterNone: function() { this.assertTransitionsNotAllowed(); }, + onEnterGreen: function() { this.assertTransitionsNotAllowed(); }, + onEnterYellow: function() { this.assertTransitionsNotAllowed(); }, + onEnterRed: function() { this.assertTransitionsNotAllowed(); }, + onAfterTransition: function() { this.assertTransitionsNotAllowed(); }, + onAfterInit: function() { this.assertTransitionsNotAllowed(); }, + onAfterWarn: function() { this.assertTransitionsNotAllowed(); }, + onAfterPanic: function() { this.assertTransitionsNotAllowed(); }, + onAfterCalm: function() { this.assertTransitionsNotAllowed(); } + } + }); + + t.is(fsm.state, 'green') + fsm.warn() + t.is(fsm.state, 'yellow') + fsm.panic() + t.is(fsm.state, 'red') + +}); + +//----------------------------------------------------------------------------- + +test('all states', t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' }, + { name: 'finish', from: 'green', to: 'done' }, + ]}); + + t.deepEqual(fsm.allStates(), [ 'none', 'green', 'yellow', 'red', 'done' ]); + +}); + +//----------------------------------------------------------------------------- + +test("all transitions", t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' }, + { name: 'finish', from: 'green', to: 'done' }, + ]}); + + t.deepEqual(fsm.allTransitions(), [ + 'init', 'warn', 'panic', 'calm', 'clear', 'finish' + ]); +}) + +//----------------------------------------------------------------------------- + +test("valid transitions", t => { + + var fsm = new StateMachine({ + init: 'green', + transitions: [ + { name: 'warn', from: 'green', to: 'yellow' }, + { name: 'panic', from: 'yellow', to: 'red' }, + { name: 'calm', from: 'red', to: 'yellow' }, + { name: 'clear', from: 'yellow', to: 'green' }, + { name: 'finish', from: 'green', to: 'done' }, + ]}); + + t.is(fsm.state, 'green') + t.deepEqual(fsm.transitions(), ['warn', 'finish']) + + fsm.warn(); + t.is(fsm.state, 'yellow') + t.deepEqual(fsm.transitions(), ['panic', 'clear']) + + fsm.panic(); + t.is(fsm.state, 'red') + t.deepEqual(fsm.transitions(), ['calm']) + + fsm.calm(); + t.is(fsm.state, 'yellow') + t.deepEqual(fsm.transitions(), ['panic', 'clear']) + + fsm.clear(); + t.is(fsm.state, 'green') + t.deepEqual(fsm.transitions(), ['warn', 'finish']) + + fsm.finish(); + t.is(fsm.state, 'done') + t.deepEqual(fsm.transitions(), []) + +}); + +//----------------------------------------------------------------------------- diff --git a/test/issues.js b/test/issues.js new file mode 100644 index 0000000..ff7741d --- /dev/null +++ b/test/issues.js @@ -0,0 +1,103 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +test('github issue #12 - transition return values', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'init', from: 'none', to: 'A' }, + { name: 'cancelled', from: 'A', to: 'X' }, + { name: 'async', from: 'A', to: 'X' } + ], + methods: { + onBeforeCancelled: function() { return false; }, + onBeforeAsync: function() { return new Promise(function(resolve, reject) {}); } + } + }); + + t.is(fsm.init(), true, 'successful (synchronous) transition returns true') + t.is(fsm.cancelled(), false, 'cancelled (synchronous) transition returns true') + + var promise = fsm.async(); + t.is(typeof promise.then, 'function', 'asynchronous transition returns a promise'); + +}) + +//------------------------------------------------------------------------------------------------- + +test('github issue #17 - exceptions in lifecycle events are NOT swallowed', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onTransition: function() { throw Error('oops') } + } + }); + + t.is(fsm.state, 'none') + + const error = t.throws(() => { + fsm.step(); + }) + + t.is(error.message, 'oops') + +}) + +//------------------------------------------------------------------------------------------------- + +test('github issue #19 - lifecycle events have correct this when applying StateMachine to a custom class', t => { + + var FSM = function() { + this.stepped = false; + this._fsm(); + } + + FSM.prototype.onStep = function(lifecycle) { this.stepped = true } + + StateMachine.factory(FSM, { + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }) + + var a = new FSM(), + b = new FSM(); + + t.is(a.state, 'none') + t.is(b.state, 'none') + t.is(a.stepped, false) + t.is(b.stepped, false) + + a.step(); + + t.is(a.state, 'complete') + t.is(b.state, 'none') + t.is(a.stepped, true) + t.is(b.stepped, false) + +}); + +//------------------------------------------------------------------------------------------------- + +test('github issue #64 - double wildcard transition does not change state', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: '*' /* no-op */ } + ] + }); + + t.is(fsm.state, 'none') + + fsm.step(); t.is(fsm.state, 'none') + fsm.step(); t.is(fsm.state, 'none') + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/lifecycle.js b/test/lifecycle.js new file mode 100644 index 0000000..4375d65 --- /dev/null +++ b/test/lifecycle.js @@ -0,0 +1,880 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events occur in correct order', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onBeforeTransition: logger, + onBeforeStep: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveComplete: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterComplete: logger, + onAfterTransition: logger, + onAfterStep: logger + } + }); + + t.is(fsm.state, 'none') + + fsm.step() + + t.is(fsm.state, 'complete') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events occur in correct order - for same state transition', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'noop', from: 'none', to: 'none' } + ], + methods: { + onBeforeTransition: logger, + onBeforeNoop: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveComplete: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterComplete: logger, + onAfterTransition: logger, + onAfterNoop: logger + } + }); + + t.is(fsm.state, 'none') + + fsm.noop() + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onBeforeNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events using shortcut names', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + methods: { + onNone: logger, + onSolid: logger, + onLiquid: logger, + onGas: logger, + onInit: logger, + onMelt: logger, + onFreeze: logger, + onVaporize: logger, + onCondense: logger + } + }); + + t.is(fsm.state, 'solid') + + t.deepEqual(logger.log, [ + { event: "onSolid", transition: "init", from: "none", to: "solid", current: "solid" }, + { event: "onInit", transition: "init", from: "none", to: "solid", current: "solid" } + ]) + + logger.clear() + fsm.melt() + t.is(fsm.state, 'liquid') + + t.deepEqual(logger.log, [ + { event: "onLiquid", transition: "melt", from: "solid", to: "liquid", current: "liquid" }, + { event: "onMelt", transition: "melt", from: "solid", to: "liquid", current: "liquid" } + ]); + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events with dash or underscore are camelized', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'has-dash', + transitions: [ + { name: 'do-with-dash', from: 'has-dash', to: 'has_underscore' }, + { name: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized' }, + { name: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash' } + ], + methods: { + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeDoWithDash: logger, + onBeforeDoWithUnderscore: logger, + onBeforeDoAlreadyCamelized: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveHasDash: logger, + onLeaveHasUnderscore: logger, + onLeaveAlreadyCamelized: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterHasDash: logger, + onEnterHasUnderscore: logger, + onEnterAlreadyCamelized: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterDoWithDash: logger, + onAfterDoWithUnderscore: logger, + onAfterDoAlreadyCamelized: logger + } + }); + + t.is(fsm.state, 'has-dash') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'init', from: 'none', to: 'has-dash', current: 'none' }, + { event: 'onBeforeInit', transition: 'init', from: 'none', to: 'has-dash', current: 'none' }, + { event: 'onLeaveState', transition: 'init', from: 'none', to: 'has-dash', current: 'none' }, + { event: 'onLeaveNone', transition: 'init', from: 'none', to: 'has-dash', current: 'none' }, + { event: 'onTransition', transition: 'init', from: 'none', to: 'has-dash', current: 'none' }, + { event: 'onEnterState', transition: 'init', from: 'none', to: 'has-dash', current: 'has-dash' }, + { event: 'onEnterHasDash', transition: 'init', from: 'none', to: 'has-dash', current: 'has-dash' }, + { event: 'onAfterTransition', transition: 'init', from: 'none', to: 'has-dash', current: 'has-dash' }, + { event: 'onAfterInit', transition: 'init', from: 'none', to: 'has-dash', current: 'has-dash' } + ]) + + logger.clear() + fsm.doWithDash() + t.is(fsm.state, 'has_underscore') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has-dash' }, + { event: 'onBeforeDoWithDash', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has-dash' }, + { event: 'onLeaveState', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has-dash' }, + { event: 'onLeaveHasDash', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has-dash' }, + { event: 'onTransition', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has-dash' }, + { event: 'onEnterState', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has_underscore' }, + { event: 'onEnterHasUnderscore', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has_underscore' }, + { event: 'onAfterTransition', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has_underscore' }, + { event: 'onAfterDoWithDash', transition: 'do-with-dash', from: 'has-dash', to: 'has_underscore', current: 'has_underscore' } + ]) + + logger.clear() + fsm.doWithUnderscore() + t.is(fsm.state, 'alreadyCamelized') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'has_underscore' }, + { event: 'onBeforeDoWithUnderscore', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'has_underscore' }, + { event: 'onLeaveState', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'has_underscore' }, + { event: 'onLeaveHasUnderscore', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'has_underscore' }, + { event: 'onTransition', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'has_underscore' }, + { event: 'onEnterState', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'alreadyCamelized' }, + { event: 'onEnterAlreadyCamelized', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'alreadyCamelized' }, + { event: 'onAfterTransition', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'alreadyCamelized' }, + { event: 'onAfterDoWithUnderscore', transition: 'do_with_underscore', from: 'has_underscore', to: 'alreadyCamelized', current: 'alreadyCamelized' } + ]) + + logger.clear() + fsm.doAlreadyCamelized() + t.is(fsm.state, 'has-dash') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'alreadyCamelized' }, + { event: 'onBeforeDoAlreadyCamelized', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'alreadyCamelized' }, + { event: 'onLeaveState', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'alreadyCamelized' }, + { event: 'onLeaveAlreadyCamelized', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'alreadyCamelized' }, + { event: 'onTransition', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'alreadyCamelized' }, + { event: 'onEnterState', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'has-dash' }, + { event: 'onEnterHasDash', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'has-dash' }, + { event: 'onAfterTransition', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'has-dash' }, + { event: 'onAfterDoAlreadyCamelized', transition: 'doAlreadyCamelized', from: 'alreadyCamelized', to: 'has-dash', current: 'has-dash' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events receive arbitrary transition arguments', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'init', from: 'none', to: 'A' }, + { name: 'step', from: 'A', to: 'B' } + ], + methods: { + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeStep: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveA: logger, + onLeaveB: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterA: logger, + onEnterB: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterStep: logger + } + }); + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, []) + + fsm.init() + + t.is(fsm.state, 'A') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onBeforeInit', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveState', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveNone', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onTransition', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onEnterState', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onEnterA', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterTransition', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterInit', transition: 'init', from: 'none', to: 'A', current: 'A' } + ]) + logger.clear() + + fsm.step('with', 4, 'more', 'arguments') + + t.is(fsm.state, 'B') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'A', to: 'B', current: 'A', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'A', to: 'B', current: 'A', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'A', to: 'B', current: 'A', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onLeaveA', transition: 'step', from: 'A', to: 'B', current: 'A', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'A', to: 'B', current: 'A', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'A', to: 'B', current: 'B', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onEnterB', transition: 'step', from: 'A', to: 'B', current: 'B', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'A', to: 'B', current: 'B', args: [ 'with', 4, 'more', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'A', to: 'B', current: 'B', args: [ 'with', 4, 'more', 'arguments' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events are cancelable', t => { + + var FSM = StateMachine.factory({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + data: function(cancel) { + return { + cancel: cancel, + logger: new LifecycleLogger() + } + }, + methods: { + onBeforeTransition: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onBeforeStep: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onEnterState: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onEnterNone: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onEnterComplete: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onTransition: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onLeaveState: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onLeaveNone: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onLeaveComplete: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onAfterTransition: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel }, + onAfterStep: function(lifecycle) { this.logger(lifecycle); return lifecycle.event !== this.cancel } + } + }); + + var cancelledBeforeTransition = new FSM('onBeforeTransition'), + cancelledBeforeStep = new FSM('onBeforeStep'), + cancelledLeaveState = new FSM('onLeaveState'), + cancelledLeaveNone = new FSM('onLeaveNone'), + cancelledTransition = new FSM('onTransition'), + cancelledEnterState = new FSM('onEnterState'), + cancelledEnterComplete = new FSM('onEnterComplete'), + cancelledAfterTransition = new FSM('onAfterTransition'), + cancelledAfterStep = new FSM('onAfterStep'); + + t.is(cancelledBeforeTransition.state, 'none') + t.is(cancelledBeforeStep.state, 'none') + t.is(cancelledLeaveState.state, 'none') + t.is(cancelledLeaveNone.state, 'none') + t.is(cancelledTransition.state, 'none') + t.is(cancelledEnterState.state, 'none') + t.is(cancelledEnterComplete.state, 'none') + t.is(cancelledAfterTransition.state, 'none') + t.is(cancelledAfterStep.state, 'none') + + cancelledBeforeTransition.step() + cancelledBeforeStep.step() + cancelledLeaveState.step() + cancelledLeaveNone.step() + cancelledTransition.step() + cancelledEnterState.step() + cancelledEnterComplete.step() + cancelledAfterTransition.step() + cancelledAfterStep.step() + + t.is(cancelledBeforeTransition.state, 'none') + t.is(cancelledBeforeStep.state, 'none') + t.is(cancelledLeaveState.state, 'none') + t.is(cancelledLeaveNone.state, 'none') + t.is(cancelledTransition.state, 'none') + t.is(cancelledEnterState.state, 'complete') + t.is(cancelledEnterComplete.state, 'complete') + t.is(cancelledAfterTransition.state, 'complete') + t.is(cancelledAfterStep.state, 'complete') + + t.deepEqual(cancelledBeforeTransition.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' } + ]) + + t.deepEqual(cancelledBeforeStep.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' } + ]) + + t.deepEqual(cancelledLeaveState.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' } + ]) + + t.deepEqual(cancelledLeaveNone.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' } + ]) + + t.deepEqual(cancelledTransition.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' } + ]) + + t.deepEqual(cancelledEnterState.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + + t.deepEqual(cancelledEnterComplete.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + + t.deepEqual(cancelledAfterTransition.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + + t.deepEqual(cancelledAfterStep.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events can be deferred using a promise', t => { + return new Promise(function(resolveTest, rejectTest) { + + var logger = new LifecycleLogger(), + start = Date.now(), + pause = function(ms) { return new Promise(function(resolve, reject) { setTimeout(resolve, ms); }); }, + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onBeforeTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onBeforeStep: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterState: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterNone: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterComplete: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onLeaveState: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onLeaveNone: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onLeaveComplete: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onAfterTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onAfterStep: function(lifecycle, a, b) { logger(lifecycle, a, b); return done(); } + } + }); + + function done() { + var duration = Date.now() - start; + t.is(fsm.state, 'complete') + t.is(duration > 600, true) + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + ]) + resolveTest() + } + + fsm.step('additional', 'arguments') + + }); +}); + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events can be cancelled using a promise', t => { + return new Promise(function(resolveTest, rejectTest) { + + var logger = new LifecycleLogger(), + start = Date.now(), + pause = function(ms) { + return new Promise(function(resolve, reject) { + setTimeout(resolve, ms); + }); + }, + cancel = function(ms) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + reject(); + done(); + }, ms); + }); + }, + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + methods: { + onBeforeTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onBeforeStep: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterState: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterNone: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onEnterComplete: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, + onTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return cancel(100); }, + onLeaveState: function(lifecycle, a, b) { logger(lifecycle, a, b); }, + onLeaveNone: function(lifecycle, a, b) { logger(lifecycle, a, b); }, + onLeaveComplete: function(lifecycle, a, b) { logger(lifecycle, a, b); }, + onAfterTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); }, + onAfterStep: function(lifecycle, a, b) { logger(lifecycle, a, b); } + } + }); + + function done() { + var duration = Date.now() - start; + t.is(fsm.state, 'none'); + t.is(duration > 300, true); + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] } + ]); + resolveTest(); + } + + fsm.step('additional', 'arguments') + + }) +}) + +//------------------------------------------------------------------------------------------------- + +test('transition cannot fire while lifecycle event is in progress', t => { + + t.plan(20); + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'other', from: '*', to: 'X' } + ], + methods: { + + onBeforeStep: function(lifecycle) { + t.false(this.can('other')); + const error = t.throws(function() { + fsm.other(); + }); + t.is(error.message, 'transition is invalid while previous transition is still in progress'); + t.is(error.transition, 'other'); + t.is(error.from, 'A'); + t.is(error.to, 'X'); + t.is(error.current, 'A'); + }, + + onAfterStep: function(lifecycle) { + t.false(this.can('other')); + const error = t.throws(function() { + fsm.other(); + }); + t.is(error.message, 'transition is invalid while previous transition is still in progress'); + t.is(error.transition, 'other'); + t.is(error.from, 'B'); + t.is(error.to, 'X'); + t.is(error.current, 'B'); + }, + + onBeforeOther: function(lifecycle) { t.fail('should never happen') }, + onAfterOther: function(lifecycle) { t.fail('should never happen') }, + onLeaveA: function(lifecycle) { t.false(this.can('other')) }, + onEnterB: function(lifecycle) { t.false(this.can('other')) }, + onLeaveB: function(lifecycle) { t.fail('should never happen') }, + onEnterX: function(lifecycle) { t.fail('should never happen') }, + onLeaveX: function(lifecycle) { t.fail('should never happen') } + + } + }); + + t.is(fsm.state, 'A') + t.true(fsm.can('other')) + + fsm.step() + + t.is(fsm.state, 'B') + t.true(fsm.can('other')) + +}) + +//------------------------------------------------------------------------------------------------- + +test('transition cannot fire while asynchronous lifecycle event is in progress', t => { + return new Promise(function(resolveTest, rejectTest) { + + t.plan(20); + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'other', from: '*', to: 'X' } + ], + methods: { + + onBeforeStep: function(lifecycle) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + t.false(fsm.can('other')); + const error = t.throws(function() { + fsm.other(); + }); + t.is(error.message, 'transition is invalid while previous transition is still in progress'); + t.is(error.transition, 'other'); + t.is(error.from, 'A'); + t.is(error.to, 'X'); + t.is(error.current, 'A'); + resolve(); + }, 200); + }); + }, + + onAfterStep: function(lifecycle) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + t.false(fsm.can('other')); + const error = t.throws(function() { + fsm.other(); + }); + t.is(error.message, 'transition is invalid while previous transition is still in progress'); + t.is(error.transition, 'other'); + t.is(error.from, 'B'); + t.is(error.to, 'X'); + t.is(error.current, 'B'); + resolve(); + setTimeout(done, 0); // HACK - let lifecycle finish before calling done() + }, 200); + }); + }, + + onBeforeOther: function(lifecycle) { t.fail('should never happen') }, + onAfterOther: function(lifecycle) { t.fail('should never happen') }, + onLeaveA: function(lifecycle) { t.false(this.can('other')) }, + onEnterB: function(lifecycle) { t.false(this.can('other')) }, + onLeaveB: function(lifecycle) { t.fail('should never happen') }, + onEnterX: function(lifecycle) { t.fail('should never happen') }, + onLeaveX: function(lifecycle) { t.fail('should never happen') } + + } + }); + + t.is(fsm.state, 'A') + t.true(fsm.can('other')) + + function done() { + t.is(fsm.state, 'B'); + t.true(fsm.can('other')); + resolveTest(); + } + + fsm.step(); // kick off the async behavior + + }) +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events for transitions with multiple :from or :to states', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'hungry', + transitions: [ + { name: 'eat', from: 'hungry', to: 'satisfied' }, + { name: 'eat', from: 'satisfied', to: 'full' }, + { name: 'rest', from: [ 'satisfied', 'full' ], to: 'hungry' } + ], + methods: { + onBeforeTransition: logger, + onBeforeEat: logger, + onBeforeRest: logger, + onLeaveState: logger, + onLeaveHungry: logger, + onLeaveSatisfied: logger, + onLeaveFull: logger, + onTransition: logger, + onEnterState: logger, + onEnterHungry: logger, + onEnterSatisfied: logger, + onEnterFull: logger, + onAfterTransition: logger, + onAfterEat: logger, + onAfterRest: logger + } + }); + + + t.is(fsm.state, 'hungry') + logger.clear() + + fsm.eat() + t.is(fsm.state, 'satisfied') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'hungry' }, + { event: 'onBeforeEat', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'hungry' }, + { event: 'onLeaveState', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'hungry' }, + { event: 'onLeaveHungry', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'hungry' }, + { event: 'onTransition', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'hungry' }, + { event: 'onEnterState', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'satisfied' }, + { event: 'onEnterSatisfied', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'satisfied' }, + { event: 'onAfterTransition', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'satisfied' }, + { event: 'onAfterEat', transition: 'eat', from: 'hungry', to: 'satisfied', current: 'satisfied' } + ]) + + logger.clear() + fsm.eat() + t.is(fsm.state, 'full') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'eat', from: 'satisfied', to: 'full', current: 'satisfied' }, + { event: 'onBeforeEat', transition: 'eat', from: 'satisfied', to: 'full', current: 'satisfied' }, + { event: 'onLeaveState', transition: 'eat', from: 'satisfied', to: 'full', current: 'satisfied' }, + { event: 'onLeaveSatisfied', transition: 'eat', from: 'satisfied', to: 'full', current: 'satisfied' }, + { event: 'onTransition', transition: 'eat', from: 'satisfied', to: 'full', current: 'satisfied' }, + { event: 'onEnterState', transition: 'eat', from: 'satisfied', to: 'full', current: 'full' }, + { event: 'onEnterFull', transition: 'eat', from: 'satisfied', to: 'full', current: 'full' }, + { event: 'onAfterTransition', transition: 'eat', from: 'satisfied', to: 'full', current: 'full' }, + { event: 'onAfterEat', transition: 'eat', from: 'satisfied', to: 'full', current: 'full' } + ]) + + logger.clear() + fsm.rest() + t.is(fsm.state, 'hungry') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'rest', from: 'full', to: 'hungry', current: 'full' }, + { event: 'onBeforeRest', transition: 'rest', from: 'full', to: 'hungry', current: 'full' }, + { event: 'onLeaveState', transition: 'rest', from: 'full', to: 'hungry', current: 'full' }, + { event: 'onLeaveFull', transition: 'rest', from: 'full', to: 'hungry', current: 'full' }, + { event: 'onTransition', transition: 'rest', from: 'full', to: 'hungry', current: 'full' }, + { event: 'onEnterState', transition: 'rest', from: 'full', to: 'hungry', current: 'hungry' }, + { event: 'onEnterHungry', transition: 'rest', from: 'full', to: 'hungry', current: 'hungry' }, + { event: 'onAfterTransition', transition: 'rest', from: 'full', to: 'hungry', current: 'hungry' }, + { event: 'onAfterRest', transition: 'rest', from: 'full', to: 'hungry', current: 'hungry' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events for factory generated state machines', t => { + + var FSM = StateMachine.factory({ + transitions: [ + { name: 'stepA', from: 'none', to: 'A' }, + { name: 'stepB', from: 'none', to: 'B' } + ], + data: function(name) { + return { + name: name, + logger: new LifecycleLogger() + } + }, + methods: { + onBeforeTransition: function(lifecycle) { this.logger(lifecycle) }, + onBeforeStepA: function(lifecycle) { this.logger(lifecycle) }, + onBeforeStepB: function(lifecycle) { this.logger(lifecycle) }, + onLeaveState: function(lifecycle) { this.logger(lifecycle) }, + onLeaveNone: function(lifecycle) { this.logger(lifecycle) }, + onLeaveA: function(lifecycle) { this.logger(lifecycle) }, + onLeaveB: function(lifecycle) { this.logger(lifecycle) }, + onTransition: function(lifecycle) { this.logger(lifecycle) }, + onEnterState: function(lifecycle) { this.logger(lifecycle) }, + onEnterNone: function(lifecycle) { this.logger(lifecycle) }, + onEnterA: function(lifecycle) { this.logger(lifecycle) }, + onEnterB: function(lifecycle) { this.logger(lifecycle) }, + onAfterTransition: function(lifecycle) { this.logger(lifecycle) }, + onAfterStepA: function(lifecycle) { this.logger(lifecycle) }, + onAfterStepB: function(lifecycle) { this.logger(lifecycle) } + } + }); + + var a = new FSM('a'), + b = new FSM('b'); + + t.is(a.state, 'none') + t.is(b.state, 'none') + + t.deepEqual(a.logger.log, []) + t.deepEqual(b.logger.log, []) + + a.stepA() + b.stepB() + + t.is(a.state, 'A') + t.is(b.state, 'B') + + t.deepEqual(a.logger.log, [ + { event: 'onBeforeTransition', transition: 'stepA', from: 'none', to: 'A', current: 'none' }, + { event: 'onBeforeStepA', transition: 'stepA', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveState', transition: 'stepA', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveNone', transition: 'stepA', from: 'none', to: 'A', current: 'none' }, + { event: 'onTransition', transition: 'stepA', from: 'none', to: 'A', current: 'none' }, + { event: 'onEnterState', transition: 'stepA', from: 'none', to: 'A', current: 'A' }, + { event: 'onEnterA', transition: 'stepA', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterTransition', transition: 'stepA', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterStepA', transition: 'stepA', from: 'none', to: 'A', current: 'A' } + ]) + + t.deepEqual(b.logger.log, [ + { event: 'onBeforeTransition', transition: 'stepB', from: 'none', to: 'B', current: 'none' }, + { event: 'onBeforeStepB', transition: 'stepB', from: 'none', to: 'B', current: 'none' }, + { event: 'onLeaveState', transition: 'stepB', from: 'none', to: 'B', current: 'none' }, + { event: 'onLeaveNone', transition: 'stepB', from: 'none', to: 'B', current: 'none' }, + { event: 'onTransition', transition: 'stepB', from: 'none', to: 'B', current: 'none' }, + { event: 'onEnterState', transition: 'stepB', from: 'none', to: 'B', current: 'B' }, + { event: 'onEnterB', transition: 'stepB', from: 'none', to: 'B', current: 'B' }, + { event: 'onAfterTransition', transition: 'stepB', from: 'none', to: 'B', current: 'B' }, + { event: 'onAfterStepB', transition: 'stepB', from: 'none', to: 'B', current: 'B' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events for custom init transition', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: { name: 'boot', from: 'booting', to: 'complete' }, + methods: { + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeBoot: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveBooting: logger, + onLeaveComplete: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterBooting: logger, + onEnterComplete: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterBoot: logger + } + }); + + t.is(fsm.state, 'complete') + + t.deepEqual(fsm.allStates(), [ 'booting', 'complete' ]) + t.deepEqual(fsm.allTransitions(), [ 'boot' ]) + t.deepEqual(fsm.transitions(), [ ]) + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'boot', from: 'booting', to: 'complete', current: 'booting' }, + { event: 'onBeforeBoot', transition: 'boot', from: 'booting', to: 'complete', current: 'booting' }, + { event: 'onLeaveState', transition: 'boot', from: 'booting', to: 'complete', current: 'booting' }, + { event: 'onLeaveBooting', transition: 'boot', from: 'booting', to: 'complete', current: 'booting' }, + { event: 'onTransition', transition: 'boot', from: 'booting', to: 'complete', current: 'booting' }, + { event: 'onEnterState', transition: 'boot', from: 'booting', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'boot', from: 'booting', to: 'complete', current: 'complete' }, + { event: 'onAfterTransition', transition: 'boot', from: 'booting', to: 'complete', current: 'complete' }, + { event: 'onAfterBoot', transition: 'boot', from: 'booting', to: 'complete', current: 'complete' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/observers.js b/test/observers.js new file mode 100644 index 0000000..f20ab6f --- /dev/null +++ b/test/observers.js @@ -0,0 +1,151 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events can be observed by external observer methods', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }); + + fsm.observe("onBeforeTransition", logger) + fsm.observe("onBeforeStep", logger) + fsm.observe("onLeaveState", logger) + fsm.observe("onLeaveNone", logger) + fsm.observe("onLeaveComplete", logger) + fsm.observe("onTransition", logger) + fsm.observe("onEnterState", logger) + fsm.observe("onEnterNone", logger) + fsm.observe("onEnterComplete", logger) + fsm.observe("onAfterTransition", logger) + fsm.observe("onAfterStep", logger) + + fsm.step('additional', 'arguments') + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events can be observed by external observer classes', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }); + + fsm.observe({ + "onBeforeTransition": logger, + "onBeforeStep": logger, + "onLeaveState": logger, + "onLeaveNone": logger, + "onLeaveComplete": logger, + "onTransition": logger, + "onEnterState": logger, + "onEnterNone": logger, + "onEnterComplete": logger, + "onAfterTransition": logger, + "onAfterStep": logger, + }) + + fsm.step('additional', 'arguments') + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('lifecycle events can be observed by multiple observers', t => { + + var logger1 = new LifecycleLogger(), + logger2 = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ] + }); + + fsm.observe("onBeforeTransition", logger1) + fsm.observe("onBeforeStep", logger1) + fsm.observe("onLeaveState", logger1) + fsm.observe("onLeaveNone", logger1) + fsm.observe("onLeaveComplete", logger1) + fsm.observe("onTransition", logger1) + fsm.observe("onEnterState", logger1) + fsm.observe("onEnterNone", logger1) + fsm.observe("onEnterComplete", logger1) + fsm.observe("onAfterTransition", logger1) + fsm.observe("onAfterStep", logger1) + + fsm.observe({ + "onBeforeTransition": logger2, + "onBeforeStep": logger2, + "onLeaveState": logger2, + "onLeaveNone": logger2, + "onLeaveComplete": logger2, + "onTransition": logger2, + "onEnterState": logger2, + "onEnterNone": logger2, + "onEnterComplete": logger2, + "onAfterTransition": logger2, + "onAfterStep": logger2, + }) + + fsm.step('additional', 'arguments') + + t.deepEqual(logger1.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] } + ]) + + t.deepEqual(logger2.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] } + ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/plugin/history.js b/test/plugin/history.js new file mode 100644 index 0000000..00f73ef --- /dev/null +++ b/test/plugin/history.js @@ -0,0 +1,493 @@ +import test from 'ava' +import StateMachine from '../../src/app' +import StateMachineHistory from '../../src/plugin/history' +import LifecycleLogger from '../helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +test('history', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + StateMachineHistory + ] + }) + + t.is(fsm.state, 'solid'); t.deepEqual(fsm.history, [ 'solid' ]) + fsm.melt(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + fsm.vaporize(); t.is(fsm.state, 'gas'); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + fsm.condense(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid' ]); + +}) + +//------------------------------------------------------------------------------------------------- + +test('history can be cleared', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'init', from: 'none', to: 'A' }, + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'A' } + ], + plugins: [ + StateMachineHistory + ] + }) + + fsm.init() + fsm.step() + + t.is(fsm.state, 'B') + t.deepEqual(fsm.history, ['A', 'B']) + + fsm.clearHistory() + + t.is(fsm.state, 'B') + t.deepEqual(fsm.history, []) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history does not record no-op transitions', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' }, + { name: 'noop', from: '*', to: '*' } + ], + plugins: [ + StateMachineHistory + ] + }) + + t.is(fsm.state, 'solid'); t.deepEqual(fsm.history, [ 'solid' ]) + fsm.noop(); t.is(fsm.state, 'solid'); t.deepEqual(fsm.history, [ 'solid' ]) + fsm.melt(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + fsm.noop(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + fsm.vaporize(); t.is(fsm.state, 'gas'); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + fsm.noop(); t.is(fsm.state, 'gas'); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history with configurable names', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + new StateMachineHistory({ name: 'memory', future: 'yonder' }) + ] + }) + + t.is(fsm.state, 'solid'); t.deepEqual(fsm.memory, [ 'solid' ]) + fsm.melt(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.memory, [ 'solid', 'liquid' ]) + fsm.vaporize(); t.is(fsm.state, 'gas'); t.deepEqual(fsm.memory, [ 'solid', 'liquid', 'gas' ]) + fsm.condense(); t.is(fsm.state, 'liquid'); t.deepEqual(fsm.memory, [ 'solid', 'liquid', 'gas', 'liquid' ]) + + t.is(fsm.canMemoryBack, true) + t.is(fsm.canMemoryForward, false) + t.deepEqual(fsm.yonder, [ ]) + + fsm.memoryBack() + + t.is(fsm.state, 'gas') + t.deepEqual(fsm.memory, [ 'solid', 'liquid', 'gas' ]) + t.deepEqual(fsm.yonder, [ 'liquid' ]) + + fsm.clearMemory() + t.deepEqual(fsm.memory, []) + t.deepEqual(fsm.yonder, []) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history, by default, just keeps growing', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + new StateMachineHistory() + ] + }) + + t.is(fsm.state, 'solid') + t.deepEqual(fsm.history, [ 'solid' ]) + + fsm.melt(); t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + fsm.vaporize(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + fsm.condense(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid' ]) + fsm.freeze(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid' ]) + fsm.melt(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid', 'liquid' ]) + fsm.vaporize(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid', 'liquid', 'gas' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history can be limited to N entries', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + new StateMachineHistory({ max: 3 }) + ] + }) + + t.is(fsm.state, 'solid') + t.deepEqual(fsm.history, [ 'solid' ]) + + fsm.melt(); t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + fsm.vaporize(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + fsm.condense(); t.deepEqual(fsm.history, [ 'liquid', 'gas', 'liquid' ]) + fsm.freeze(); t.deepEqual(fsm.history, [ 'gas', 'liquid', 'solid' ]) + fsm.melt(); t.deepEqual(fsm.history, [ 'liquid', 'solid', 'liquid' ]) + fsm.vaporize(); t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history back and forward', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ], + plugins: [ + StateMachineHistory + ] + }) + + t.is(fsm.state, 'A') + t.is(fsm.canHistoryBack, false) + t.deepEqual(fsm.history, [ 'A' ]) + t.deepEqual(fsm.future, [ ]) + + var error = t.throws(() => { + fsm.historyBack() + }) + t.is(error.message, 'no history') + + fsm.step() + fsm.step() + fsm.step() + + t.is(fsm.state, 'D') + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, false) + t.deepEqual(fsm.history, [ 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.future, []) + + fsm.historyBack() + t.is(fsm.state, 'C') + t.deepEqual(fsm.history, [ 'A', 'B', 'C' ]) + t.deepEqual(fsm.future, [ 'D' ]) + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, true) + + fsm.historyBack() + t.is(fsm.state, 'B') + t.deepEqual(fsm.history, [ 'A', 'B' ]) + t.deepEqual(fsm.future, [ 'D', 'C' ]) + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, true) + + fsm.historyBack() + t.is(fsm.state, 'A') + t.deepEqual(fsm.history, [ 'A' ]) + t.deepEqual(fsm.future, [ 'D', 'C', 'B' ]) + t.is(fsm.canHistoryBack, false) + t.is(fsm.canHistoryForward, true) + + fsm.historyForward() + t.is(fsm.state, 'B') + t.deepEqual(fsm.history, [ 'A', 'B' ]) + t.deepEqual(fsm.future, [ 'D', 'C' ]) + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, true) + + fsm.historyForward() + t.is(fsm.state, 'C') + t.deepEqual(fsm.history, [ 'A', 'B', 'C' ]) + t.deepEqual(fsm.future, [ 'D' ]) + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, true) + + fsm.step() + t.is(fsm.state, 'D') + t.deepEqual(fsm.history, [ 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.future, [ ]) + t.is(fsm.canHistoryBack, true) + t.is(fsm.canHistoryForward, false) + + error = t.throws(() => { + fsm.historyForward() + }) + t.is(error.message, 'no history') + +}) + +//------------------------------------------------------------------------------------------------- + +test('history back and forward lifecycle events', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ], + methods: { + onBeforeTransition: logger, + onBeforeStep: logger, + onBeforeHistoryBack: logger, + onBeforeHistoryForward: logger, + onLeaveState: logger, + onLeaveA: logger, + onLeaveB: logger, + onLeaveC: logger, + onLeaveD: logger, + onTransition: logger, + onEnterState: logger, + onEnterA: logger, + onEnterB: logger, + onEnterC: logger, + onEnterD: logger, + onAfterTransition: logger, + onAfterStep: logger, + onAfterHistoryBack: logger, + onAfterHistoryForward: logger + }, + plugins: [ + StateMachineHistory + ] + }) + + fsm.step() + fsm.step() + fsm.step() + logger.clear() + + t.is(fsm.state, 'D') + t.deepEqual(fsm.history, [ 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.future, [ ]) + + fsm.historyBack() + + t.is(fsm.state, 'C') + t.deepEqual(fsm.history, [ 'A', 'B', 'C' ]) + t.deepEqual(fsm.future, [ 'D' ]) + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'historyBack', from: 'D', to: 'C', current: 'D' }, + { event: 'onBeforeHistoryBack', transition: 'historyBack', from: 'D', to: 'C', current: 'D' }, + { event: 'onLeaveState', transition: 'historyBack', from: 'D', to: 'C', current: 'D' }, + { event: 'onLeaveD', transition: 'historyBack', from: 'D', to: 'C', current: 'D' }, + { event: 'onTransition', transition: 'historyBack', from: 'D', to: 'C', current: 'D' }, + { event: 'onEnterState', transition: 'historyBack', from: 'D', to: 'C', current: 'C' }, + { event: 'onEnterC', transition: 'historyBack', from: 'D', to: 'C', current: 'C' }, + { event: 'onAfterTransition', transition: 'historyBack', from: 'D', to: 'C', current: 'C' }, + { event: 'onAfterHistoryBack', transition: 'historyBack', from: 'D', to: 'C', current: 'C' } + ]) + + logger.clear() + + fsm.historyForward() + + t.is(fsm.state, 'D') + t.deepEqual(fsm.history, [ 'A', 'B', 'C', 'D' ]) + t.deepEqual(fsm.future, [ ]) + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'historyForward', from: 'C', to: 'D', current: 'C' }, + { event: 'onBeforeHistoryForward', transition: 'historyForward', from: 'C', to: 'D', current: 'C' }, + { event: 'onLeaveState', transition: 'historyForward', from: 'C', to: 'D', current: 'C' }, + { event: 'onLeaveC', transition: 'historyForward', from: 'C', to: 'D', current: 'C' }, + { event: 'onTransition', transition: 'historyForward', from: 'C', to: 'D', current: 'C' }, + { event: 'onEnterState', transition: 'historyForward', from: 'C', to: 'D', current: 'D' }, + { event: 'onEnterD', transition: 'historyForward', from: 'C', to: 'D', current: 'D' }, + { event: 'onAfterTransition', transition: 'historyForward', from: 'C', to: 'D', current: 'D' }, + { event: 'onAfterHistoryForward', transition: 'historyForward', from: 'C', to: 'D', current: 'D' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history can be used with a state machine factory', t => { + + var FSM = StateMachine.factory({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + StateMachineHistory + ] + }) + + var a = new FSM(), + b = new FSM(); + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + t.deepEqual(a.history, [ 'solid' ]) + t.deepEqual(b.history, [ 'solid' ]) + + a.melt() + a.vaporize() + a.condense() + a.freeze() + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + t.deepEqual(a.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid' ]) + t.deepEqual(b.history, [ 'solid' ]) + + b.melt() + b.freeze() + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + + t.deepEqual(a.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid' ]) + t.deepEqual(b.history, [ 'solid', 'liquid', 'solid' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history can be used with a singleton state machine applied to existing object', t => { + + var fsm = { + name: 'jake' + } + + StateMachine.apply(fsm, { + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + StateMachineHistory + ] + }) + + t.is(fsm.name, 'jake') + t.is(fsm.state, 'solid') + t.deepEqual(fsm.history, [ 'solid' ]) + + fsm.melt(); + t.is(fsm.state, 'liquid') + t.deepEqual(fsm.history, [ 'solid', 'liquid' ]) + + fsm.vaporize(); + t.is(fsm.state, 'gas') + t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas' ]) + + fsm.condense() + t.is(fsm.state, 'liquid') + t.deepEqual(fsm.history, [ 'solid', 'liquid', 'gas', 'liquid' ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test('history can be used with a state machine factory applied to existing class', t => { + + function FSM(name) { + this.name = name + this._fsm() + } + + StateMachine.factory(FSM, { + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ], + plugins: [ + StateMachineHistory + ] + }) + + var a = new FSM('A'), + b = new FSM('B'); + + t.is(a.name, 'A') + t.is(b.name, 'B') + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + t.deepEqual(a.history, [ 'solid' ]) + t.deepEqual(b.history, [ 'solid' ]) + + a.melt() + a.vaporize() + a.condense() + a.freeze() + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + t.deepEqual(a.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid' ]) + t.deepEqual(b.history, [ 'solid' ]) + + b.melt() + b.freeze() + + t.is(a.state, 'solid') + t.is(b.state, 'solid') + + t.deepEqual(a.history, [ 'solid', 'liquid', 'gas', 'liquid', 'solid' ]) + t.deepEqual(b.history, [ 'solid', 'liquid', 'solid' ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/plugin/visualize.js b/test/plugin/visualize.js new file mode 100644 index 0000000..a2b9388 --- /dev/null +++ b/test/plugin/visualize.js @@ -0,0 +1,443 @@ +import test from 'ava' +import StateMachine from '../../src/app' +import visualize from '../../src/plugin/visualize' + +var dotcfg = visualize.dotcfg, // converts FSM to DOT CONFIG + dotify = visualize.dotify; // converts DOT CONFIG to DOT OUTPUT + +//------------------------------------------------------------------------------------------------- + +test('visualize state machine', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }) + + t.is(visualize(fsm), `digraph "fsm" { + "solid"; + "liquid"; + "gas"; + "solid" -> "liquid" [ label=" melt " ]; + "liquid" -> "solid" [ label=" freeze " ]; + "liquid" -> "gas" [ label=" vaporize " ]; + "gas" -> "liquid" [ label=" condense " ]; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('visualize state machine factory', t => { + + var FSM = StateMachine.factory({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }) + + t.is(visualize(FSM), `digraph "fsm" { + "solid"; + "liquid"; + "gas"; + "solid" -> "liquid" [ label=" melt " ]; + "liquid" -> "solid" [ label=" freeze " ]; + "liquid" -> "gas" [ label=" vaporize " ]; + "gas" -> "liquid" [ label=" condense " ]; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('visualize with custom .dot markup', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid', dot: { color: 'red', headport: 'nw', tailport: 'ne' } }, + { name: 'freeze', from: 'liquid', to: 'solid', dot: { color: 'grey', headport: 'se', tailport: 'sw' } }, + { name: 'vaporize', from: 'liquid', to: 'gas', dot: { color: 'yellow', headport: 'nw', tailport: 'ne' } }, + { name: 'condense', from: 'gas', to: 'liquid', dot: { color: 'brown', headport: 'se', tailport: 'sw' } } + ] + }) + + t.is(visualize(fsm, { name: 'matter', orientation: 'horizontal' }), `digraph "matter" { + rankdir=LR; + "solid"; + "liquid"; + "gas"; + "solid" -> "liquid" [ color="red" ; headport="nw" ; label=" melt " ; tailport="ne" ]; + "liquid" -> "solid" [ color="grey" ; headport="se" ; label=" freeze " ; tailport="sw" ]; + "liquid" -> "gas" [ color="yellow" ; headport="nw" ; label=" vaporize " ; tailport="ne" ]; + "gas" -> "liquid" [ color="brown" ; headport="se" ; label=" condense " ; tailport="sw" ]; +}`) +}) + +//================================================================================================= +// TEST FSM => DOTCFG +//================================================================================================= + +test('dotcfg simple state machine', t => { + + var fsm = new StateMachine({ + init: 'solid', + transitions: [ + { name: 'melt', from: 'solid', to: 'liquid' }, + { name: 'freeze', from: 'liquid', to: 'solid' }, + { name: 'vaporize', from: 'liquid', to: 'gas' }, + { name: 'condense', from: 'gas', to: 'liquid' } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'solid', 'liquid', 'gas' ], + transitions: [ + { from: 'solid', to: 'liquid', label: ' melt ' }, + { from: 'liquid', to: 'solid', label: ' freeze ' }, + { from: 'liquid', to: 'gas', label: ' vaporize ' }, + { from: 'gas', to: 'liquid', label: ' condense ' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for state machine - optionally include :init transition', t => { + + var fsm = new StateMachine({ + init: { name: 'boot', from: 'booting', to: 'ready', dot: { color: 'red' } } + }) + + t.deepEqual(dotcfg(fsm, { init: false }), { + states: [ 'ready' ] + }) + + t.deepEqual(dotcfg(fsm, { init: true }), { + states: [ 'booting', 'ready' ], + transitions: [ + { from: 'booting', to: 'ready', label: ' boot ', color: 'red' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for fsm with multiple transitions with same :name', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'A', 'B', 'C', 'D' ], + transitions: [ + { from: 'A', to: 'B', label: ' step ' }, + { from: 'B', to: 'C', label: ' step ' }, + { from: 'C', to: 'D', label: ' step ' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for fsm transition with multiple :from', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'reset', from: [ 'A', 'B' ], to: 'A' } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'A', 'B', 'C', 'D' ], + transitions: [ + { from: 'A', to: 'B', label: ' step ' }, + { from: 'B', to: 'C', label: ' step ' }, + { from: 'C', to: 'D', label: ' step ' }, + { from: 'A', to: 'A', label: ' reset ' }, + { from: 'B', to: 'A', label: ' reset ' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for fsm with wildcard/missing :from', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'reset', from: '*', to: 'A' }, + { name: 'finish', /* missing */ to: 'X' } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'A', 'B', 'C', 'D', 'X' ], + transitions: [ + { from: 'A', to: 'B', label: ' step ' }, + { from: 'B', to: 'C', label: ' step ' }, + { from: 'C', to: 'D', label: ' step ' }, + { from: 'none', to: 'A', label: ' reset ' }, + { from: 'A', to: 'A', label: ' reset ' }, + { from: 'B', to: 'A', label: ' reset ' }, + { from: 'C', to: 'A', label: ' reset ' }, + { from: 'D', to: 'A', label: ' reset ' }, + { from: 'X', to: 'A', label: ' reset ' }, + { from: 'none', to: 'X', label: ' finish ' }, + { from: 'A', to: 'X', label: ' finish ' }, + { from: 'B', to: 'X', label: ' finish ' }, + { from: 'C', to: 'X', label: ' finish ' }, + { from: 'D', to: 'X', label: ' finish ' }, + { from: 'X', to: 'X', label: ' finish ' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for fsm with wildcard/missing :to', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'step', from: 'B', to: 'C' }, + { name: 'step', from: 'C', to: 'D' }, + { name: 'stay', from: 'A', to: 'A' }, + { name: 'stay', from: 'B', to: '*' }, + { name: 'stay', from: 'C' /* missing */ }, + { name: 'noop', from: '*', to: '*' } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'A', 'B', 'C', 'D' ], + transitions: [ + { from: 'A', to: 'B', label: ' step ' }, + { from: 'B', to: 'C', label: ' step ' }, + { from: 'C', to: 'D', label: ' step ' }, + { from: 'A', to: 'A', label: ' stay ' }, + { from: 'B', to: 'B', label: ' stay ' }, + { from: 'C', to: 'C', label: ' stay ' }, + { from: 'none', to: 'none', label: ' noop ' }, + { from: 'A', to: 'A', label: ' noop ' }, + { from: 'B', to: 'B', label: ' noop ' }, + { from: 'C', to: 'C', label: ' noop ' }, + { from: 'D', to: 'D', label: ' noop ' } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for fsm - conditional transition is not displayed', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: '*', to: function(n) { return this.skip(n) } }, + ], + methods: { + skip: function(amount) { + var code = this.state.charCodeAt(0); + return String.fromCharCode(code + (amount || 1)); + } + } + }); + + t.deepEqual(dotcfg(fsm), { + states: [ 'A' ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg with custom transition .dot edge markup', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B', dot: { color: "red", headport: 'nw', tailport: 'ne', label: 'A2B' } }, + { name: 'step', from: 'B', to: 'C', dot: { color: "green", headport: 'sw', tailport: 'se', label: 'B2C' } } + ] + }) + + t.deepEqual(dotcfg(fsm), { + states: [ 'A', 'B', 'C' ], + transitions: [ + { from: 'A', to: 'B', label: 'A2B', color: "red", headport: "nw", tailport: "ne" }, + { from: 'B', to: 'C', label: 'B2C', color: "green", headport: "sw", tailport: "se" } + ] + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg with custom name', t => { + + var fsm = new StateMachine(); + + t.deepEqual(dotcfg(fsm, { name: 'bob' }), { + name: 'bob', + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg with custom orientation', t => { + + var fsm = new StateMachine(); + + t.deepEqual(dotcfg(fsm, { orientation: 'horizontal' }), { + rankdir: 'LR', + }) + + t.deepEqual(dotcfg(fsm, { orientation: 'vertical' }), { + rankdir: 'TB', + }) + +}) + +//------------------------------------------------------------------------------------------------- + +test('dotcfg for empty state machine', t => { + + var fsm = new StateMachine(); + + t.deepEqual(dotcfg(fsm), {}) + +}) + +//================================================================================================= +// TEST DOTCFG => DOT OUTPUT +//================================================================================================= + +test('dotify empty', t => { + var expected = `digraph "fsm" { +}` + t.is(dotify(), expected) + t.is(dotify({}), expected) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify name', t => { + t.is(dotify({ name: 'bob' }), `digraph "bob" { +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify rankdir', t => { + t.is(dotify({ rankdir: 'LR' }), `digraph "fsm" { + rankdir=LR; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify states', t => { + var states = [ 'A', 'B' ]; + t.is(dotify({ states: states }), `digraph "fsm" { + "A"; + "B"; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify transitions', t => { + var transitions = [ + { from: 'A', to: 'B' }, + { from: 'B', to: 'C' }, + ]; + t.is(dotify({ transitions: transitions }), `digraph "fsm" { + "A" -> "B"; + "B" -> "C"; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify transitions with labels', t => { + var transitions = [ + { from: 'A', to: 'B', label: 'first' }, + { from: 'B', to: 'C', label: 'second' } + ]; + t.is(dotify({ transitions: transitions }), `digraph "fsm" { + "A" -> "B" [ label="first" ]; + "B" -> "C" [ label="second" ]; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify transitions with custom .dot edge markup', t => { + var transitions = [ + { from: 'A', to: 'B', label: 'first', color: 'red', headport: 'nw', tailport: 'ne' }, + { from: 'B', to: 'A', label: 'second', color: 'green', headport: 'se', tailport: 'sw' } + ] + t.is(dotify({ transitions: transitions }), `digraph "fsm" { + "A" -> "B" [ color="red" ; headport="nw" ; label="first" ; tailport="ne" ]; + "B" -> "A" [ color="green" ; headport="se" ; label="second" ; tailport="sw" ]; +}`) +}) + +//------------------------------------------------------------------------------------------------- + +test('dotify kitchen sink', t => { + var name = "my fsm", + rankdir = "LR", + states = [ 'none', 'solid', 'liquid', 'gas' ], + transitions = [ + { from: 'none', to: 'solid', color: 'red', label: 'init' }, + { from: 'solid', to: 'liquid', color: 'red', label: 'melt' }, + { from: 'liquid', to: 'solid', color: 'green', label: 'freeze' }, + { from: 'liquid', to: 'gas', color: 'red', label: 'vaporize' }, + { from: 'gas', to: 'liquid', color: 'green', label: 'condense' } + ]; + t.is(dotify({ name: name, rankdir: rankdir, states: states, transitions: transitions }), `digraph "my fsm" { + rankdir=LR; + "none"; + "solid"; + "liquid"; + "gas"; + "none" -> "solid" [ color="red" ; label="init" ]; + "solid" -> "liquid" [ color="red" ; label="melt" ]; + "liquid" -> "solid" [ color="green" ; label="freeze" ]; + "liquid" -> "gas" [ color="red" ; label="vaporize" ]; + "gas" -> "liquid" [ color="green" ; label="condense" ]; +}`) +}) + +//================================================================================================= diff --git a/test/plugins.js b/test/plugins.js new file mode 100644 index 0000000..486125b --- /dev/null +++ b/test/plugins.js @@ -0,0 +1,151 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//------------------------------------------------------------------------------------------------- + +test('an empty plugin object', t => { + + var plugin = { + init: function(instance) { + instance.plugged = true + } + }; + + var fsm = new StateMachine({ + plugins: [ plugin ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.plugged, true) + +}) + +//------------------------------------------------------------------------------------------------- + +test('an empty plugin function', t => { + + var plugin = function() { + return { + init: function(instance) { + instance.plugged = true + } + } + }; + + var fsm = new StateMachine({ + plugins: [ plugin ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.plugged, true) + +}) + +//------------------------------------------------------------------------------------------------- + +test('an empty plugin function with configuration', t => { + + var plugin = function(value) { + return { + init: function(instance) { + instance.plugged = value + } + } + }; + + var fsm = new StateMachine({ + plugins: [ new plugin(42) ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.plugged, 42) + +}) + +//------------------------------------------------------------------------------------------------- + +test('plugin can add methods', t => { + + var plugin = { + methods: { + foo: function() { return 'FOO' }, + bar: function() { return 'BAR' } + } + }; + + var fsm = new StateMachine({ + plugins: [ plugin ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.foo(), 'FOO') + t.is(fsm.bar(), 'BAR') + +}) + +//------------------------------------------------------------------------------------------------- + +test('plugin can add properties', t => { + + var plugin = { + properties: { + color: { get: function() { return 'red' } } + } + }; + + var fsm = new StateMachine({ + plugins: [ plugin ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.color, 'red') + +}) + +//------------------------------------------------------------------------------------------------- + +test('plugin lifecycle hook', t => { + + var plugin = { + + init: function(instance) { + instance.logger = new LifecycleLogger(); + }, + + lifecycle: function(instance, lifecycle) { + instance.logger(lifecycle) + } + + }; + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'complete' } + ], + plugins: [ plugin ] + }); + + t.is(fsm.state, 'none') + t.deepEqual(fsm.logger.log, []) + + fsm.step() + + t.is(fsm.state, 'complete') + t.deepEqual(fsm.logger.log, [ + { event: 'onBeforeTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onBeforeStep', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveState', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none' }, + { event: 'onEnterState', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onEnterComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onComplete', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete' }, + { event: 'onStep', transition: 'step', from: 'none', to: 'complete', current: 'complete' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/qunit/qunit.css b/test/qunit/qunit.css deleted file mode 100644 index 93026e3..0000000 --- a/test/qunit/qunit.css +++ /dev/null @@ -1,237 +0,0 @@ -/*! - * QUnit 1.14.0 - * http://qunitjs.com/ - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-01-31T16:40Z - */ - -/** Font Family and Sizes */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; -} - -#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } -#qunit-tests { font-size: smaller; } - - -/** Resets */ - -#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; -} - - -/** Header */ - -#qunit-header { - padding: 0.5em 0 0.5em 1em; - - color: #8699A4; - background-color: #0D3349; - - font-size: 1.5em; - line-height: 1em; - font-weight: 400; - - border-radius: 5px 5px 0 0; -} - -#qunit-header a { - text-decoration: none; - color: #C2CCD1; -} - -#qunit-header a:hover, -#qunit-header a:focus { - color: #FFF; -} - -#qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 0.5em 0 0.1em; -} - -#qunit-banner { - height: 5px; -} - -#qunit-testrunner-toolbar { - padding: 0.5em 0 0.5em 2em; - color: #5E740B; - background-color: #EEE; - overflow: hidden; -} - -#qunit-userAgent { - padding: 0.5em 0 0.5em 2.5em; - background-color: #2B81AF; - color: #FFF; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; -} - -#qunit-modulefilter-container { - float: right; -} - -/** Tests: Pass/Fail */ - -#qunit-tests { - list-style-position: inside; -} - -#qunit-tests li { - padding: 0.4em 0.5em 0.4em 2.5em; - border-bottom: 1px solid #FFF; - list-style-position: inside; -} - -#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { - display: none; -} - -#qunit-tests li strong { - cursor: pointer; -} - -#qunit-tests li a { - padding: 0.5em; - color: #C2CCD1; - text-decoration: none; -} -#qunit-tests li a:hover, -#qunit-tests li a:focus { - color: #000; -} - -#qunit-tests li .runtime { - float: right; - font-size: smaller; -} - -.qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; - - background-color: #FFF; - - border-radius: 5px; -} - -.qunit-collapsed { - display: none; -} - -#qunit-tests table { - border-collapse: collapse; - margin-top: 0.2em; -} - -#qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 0.5em 0 0; -} - -#qunit-tests td { - vertical-align: top; -} - -#qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; -} - -#qunit-tests del { - background-color: #E0F2BE; - color: #374E0C; - text-decoration: none; -} - -#qunit-tests ins { - background-color: #FFCACA; - color: #500; - text-decoration: none; -} - -/*** Test Counts */ - -#qunit-tests b.counts { color: #000; } -#qunit-tests b.passed { color: #5E740B; } -#qunit-tests b.failed { color: #710909; } - -#qunit-tests li li { - padding: 5px; - background-color: #FFF; - border-bottom: none; - list-style-position: inside; -} - -/*** Passing Styles */ - -#qunit-tests li li.pass { - color: #3C510C; - background-color: #FFF; - border-left: 10px solid #C6E746; -} - -#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } -#qunit-tests .pass .test-name { color: #366097; } - -#qunit-tests .pass .test-actual, -#qunit-tests .pass .test-expected { color: #999; } - -#qunit-banner.qunit-pass { background-color: #C6E746; } - -/*** Failing Styles */ - -#qunit-tests li li.fail { - color: #710909; - background-color: #FFF; - border-left: 10px solid #EE5757; - white-space: pre; -} - -#qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; -} - -#qunit-tests .fail { color: #000; background-color: #EE5757; } -#qunit-tests .fail .test-name, -#qunit-tests .fail .module-name { color: #000; } - -#qunit-tests .fail .test-actual { color: #EE5757; } -#qunit-tests .fail .test-expected { color: #008000; } - -#qunit-banner.qunit-fail { background-color: #EE5757; } - - -/** Result */ - -#qunit-testresult { - padding: 0.5em 0.5em 0.5em 2.5em; - - color: #2B81AF; - background-color: #D2E0E6; - - border-bottom: 1px solid #FFF; -} -#qunit-testresult .module-name { - font-weight: 700; -} - -/** Fixture */ - -#qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; -} diff --git a/test/qunit/qunit.js b/test/qunit/qunit.js deleted file mode 100644 index 0e279fd..0000000 --- a/test/qunit/qunit.js +++ /dev/null @@ -1,2288 +0,0 @@ -/*! - * QUnit 1.14.0 - * http://qunitjs.com/ - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-01-31T16:40Z - */ - -(function( window ) { - -var QUnit, - assert, - config, - onErrorFnPrev, - testId = 0, - fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - defined = { - document: typeof window.document !== "undefined", - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. - /*jshint newcap: false */ - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[key]; - vals[key] = val === Object(val) ? objectValues(val) : val; - } - } - return vals; - }; - - -// Root QUnit object. -// `QUnit` initialized at top of scope -QUnit = { - - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - config.currentModule = name; - config.currentModuleTestEnvironment = testEnvironment; - config.modules[name] = true; - }, - - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test, - nameHtml = "" + escapeText( testName ) + ""; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - if ( config.currentModule ) { - nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml; - } - - test = new Test({ - nameHtml: nameHtml, - testName: testName, - expected: expected, - async: async, - callback: callback, - module: config.currentModule, - moduleTestEnvironment: config.currentModuleTestEnvironment, - stack: sourceFromStacktrace( 2 ) - }); - - if ( !validTest( test ) ) { - return; - } - - test.queue(); - }, - - // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if (arguments.length === 1) { - config.current.expected = asserts; - } else { - return config.current.expected; - } - }, - - start: function( count ) { - // QUnit hasn't been initialized yet. - // Note: RequireJS (et al) may delay onLoad - if ( config.semaphore === undefined ) { - QUnit.begin(function() { - // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first - setTimeout(function() { - QUnit.start( count ); - }); - }); - return; - } - - config.semaphore -= count || 1; - // don't start until equal number of stop-calls - if ( config.semaphore > 0 ) { - return; - } - // ignore if start is called more often then stop - if ( config.semaphore < 0 ) { - config.semaphore = 0; - QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); - return; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - setTimeout(function() { - if ( config.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - config.blocking = false; - process( true ); - }, 13); - } else { - config.blocking = false; - process( true ); - } - }, - - stop: function( count ) { - config.semaphore += count || 1; - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - config.semaphore = 1; - QUnit.start(); - }, config.testTimeout ); - } - } -}; - -// We use the prototype to distinguish between properties that should -// be exposed as globals (and in exports) and those that shouldn't -(function() { - function F() {} - F.prototype = QUnit; - QUnit = new F(); - // Make F QUnit's constructor so that we can add to the prototype later - QUnit.constructor = F; -}()); - -/** - * Config object: Maintain internal state - * Later exposed as QUnit.config - * `config` initialized at top of scope - */ -config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // when enabled, show only failing tests - // gets persisted through sessionStorage and can be changed in UI via checkbox - hidepassed: false, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // by default, scroll to top of the page when suite is done - scrolltop: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: {}, - - // logging callback queues - begin: [], - done: [], - log: [], - testStart: [], - testDone: [], - moduleStart: [], - moduleDone: [] -}; - -// Initialize more QUnit.config and QUnit.urlParams -(function() { - var i, current, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - if ( urlParams[ current[ 0 ] ] ) { - urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] ); - } else { - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - // Exact match of the module name - config.module = urlParams.module; - - config.testNumber = []; - if ( urlParams.testNumber ) { - - // Ensure that urlParams.testNumber is an array - urlParams.testNumber = [].concat( urlParams.testNumber ); - for ( i = 0; i < urlParams.testNumber.length; i++ ) { - current = urlParams.testNumber[ i ]; - config.testNumber.push( parseInt( current, 10 ) ); - } - } - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; -}()); - -extend( QUnit, { - - config: config, - - // Initialize the configuration options - init: function() { - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date(), - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filter: "", - queue: [], - semaphore: 1 - }); - - var tests, banner, result, - qunit = id( "qunit" ); - - if ( qunit ) { - qunit.innerHTML = - "

    " + escapeText( document.title ) + "

    " + - "

    " + - "
    " + - "

    " + - "
      "; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
       "; - } - }, - - // Resets the test setup. Useful for tests that modify the DOM. - /* - DEPRECATED: Use multiple tests instead of resetting inside a test. - Use testStart or testDone for custom cleanup. - This method will throw an error in 2.0, and will be removed in 2.1 - */ - reset: function() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - fixture.innerHTML = config.fixture; - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - } - - // Consider: typeof null === object - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), - type = match && match[1] || ""; - - switch ( type ) { - case "Number": - if ( isNaN(obj) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - push: function( result, actual, expected, message ) { - if ( !config.current ) { - throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); - } - - var output, source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeText( message ) || ( result ? "okay" : "failed" ); - message = "" + message + ""; - output = message; - - if ( !result ) { - expected = escapeText( QUnit.jsDump.parse(expected) ); - actual = escapeText( QUnit.jsDump.parse(actual) ); - output += ""; - - if ( actual !== expected ) { - output += ""; - output += ""; - } - - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
      Expected:
      " + expected + "
      Result:
      " + actual + "
      Diff:
      " + QUnit.diff( expected, actual ) + "
      Source:
      " + escapeText( source ) + "
      "; - } - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !config.current ) { - throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - - var output, - details = { - module: config.current.module, - name: config.current.testName, - result: false, - message: message - }; - - message = escapeText( message ) || "error"; - message = "" + message + ""; - output = message; - - output += ""; - - if ( actual ) { - output += ""; - } - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
      Result:
      " + escapeText( actual ) + "
      Source:
      " + escapeText( source ) + "
      "; - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: false, - message: output - }); - }, - - url: function( params ) { - params = extend( extend( {}, QUnit.urlParams ), params ); - var key, - querystring = "?"; - - for ( key in params ) { - if ( hasOwn.call( params, key ) ) { - querystring += encodeURIComponent( key ) + "=" + - encodeURIComponent( params[ key ] ) + "&"; - } - } - return window.location.protocol + "//" + window.location.host + - window.location.pathname + querystring.slice( 0, -1 ); - }, - - extend: extend, - id: id, - addEvent: addEvent, - addClass: addClass, - hasClass: hasClass, - removeClass: removeClass - // load, equiv, jsDump, diff: Attached later -}); - -/** - * @deprecated: Created for backwards compatibility with test runner that set the hook function - * into QUnit.{hook}, instead of invoking it and passing the hook function. - * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. - * Doing this allows us to tell if the following methods have been overwritten on the actual - * QUnit object. - */ -extend( QUnit.constructor.prototype, { - - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: registerLoggingCallback( "begin" ), - - // done: { failed, passed, total, runtime } - done: registerLoggingCallback( "done" ), - - // log: { result, actual, expected, message } - log: registerLoggingCallback( "log" ), - - // testStart: { name } - testStart: registerLoggingCallback( "testStart" ), - - // testDone: { name, failed, passed, total, runtime } - testDone: registerLoggingCallback( "testDone" ), - - // moduleStart: { name } - moduleStart: registerLoggingCallback( "moduleStart" ), - - // moduleDone: { name, failed, passed, total } - moduleDone: registerLoggingCallback( "moduleDone" ) -}); - -if ( !defined.document || document.readyState === "complete" ) { - config.autorun = true; -} - -QUnit.load = function() { - runLoggingCallbacks( "begin", QUnit, {} ); - - // Initialize the config, saving the execution queue - var banner, filter, i, j, label, len, main, ol, toolbar, val, selection, - urlConfigContainer, moduleFilter, userAgent, - numModules = 0, - moduleNames = [], - moduleFilterHtml = "", - urlConfigHtml = "", - oldconfig = extend( {}, config ); - - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - len = config.urlConfig.length; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[i]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val - }; - } - config[ val.id ] = QUnit.urlParams[ val.id ]; - if ( !val.value || typeof val.value === "string" ) { - urlConfigHtml += ""; - } else { - urlConfigHtml += ""; - } - } - for ( i in config.modules ) { - if ( config.modules.hasOwnProperty( i ) ) { - moduleNames.push(i); - } - } - numModules = moduleNames.length; - moduleNames.sort( function( a, b ) { - return a.localeCompare( b ); - }); - moduleFilterHtml += ""; - - // `userAgent` initialized at top of scope - userAgent = id( "qunit-userAgent" ); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - - // `banner` initialized at top of scope - banner = id( "qunit-header" ); - if ( banner ) { - banner.innerHTML = "
      " + banner.innerHTML + " "; - } - - // `toolbar` initialized at top of scope - toolbar = id( "qunit-testrunner-toolbar" ); - if ( toolbar ) { - // `filter` initialized at top of scope - filter = document.createElement( "input" ); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - - addEvent( filter, "click", function() { - var tmp, - ol = id( "qunit-tests" ); - - if ( filter.checked ) { - ol.className = ol.className + " hidepass"; - } else { - tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; - ol.className = tmp.replace( / hidepass /, " " ); - } - if ( defined.sessionStorage ) { - if (filter.checked) { - sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); - } else { - sessionStorage.removeItem( "qunit-filter-passed-tests" ); - } - } - }); - - if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { - filter.checked = true; - // `ol` initialized at top of scope - ol = id( "qunit-tests" ); - ol.className = ol.className + " hidepass"; - } - toolbar.appendChild( filter ); - - // `label` initialized at top of scope - label = document.createElement( "label" ); - label.setAttribute( "for", "qunit-filter-pass" ); - label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - - urlConfigContainer = document.createElement("span"); - urlConfigContainer.innerHTML = urlConfigHtml; - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" for checkboxes - // * Fallback from event.target to event.srcElement - addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.checked ? - target.defaultValue || true : - undefined; - window.location = QUnit.url( params ); - }); - addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.options[ target.selectedIndex ].value || undefined; - window.location = QUnit.url( params ); - }); - toolbar.appendChild( urlConfigContainer ); - - if (numModules > 1) { - moduleFilter = document.createElement( "span" ); - moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); - moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter.lastChild, "change", function() { - var selectBox = moduleFilter.getElementsByTagName("select")[0], - selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); - - window.location = QUnit.url({ - module: ( selectedModule === "" ) ? undefined : selectedModule, - // Remove any existing filters - filter: undefined, - testNumber: undefined - }); - }); - toolbar.appendChild(moduleFilter); - } - } - - // `main` initialized at top of scope - main = id( "qunit-fixture" ); - if ( main ) { - config.fixture = main.innerHTML; - } - - if ( config.autostart ) { - QUnit.start(); - } -}; - -if ( defined.document ) { - addEvent( window, "load", QUnit.load ); -} - -// `onErrorFnPrev` initialized at top of scope -// Preserve other handlers -onErrorFnPrev = window.onerror; - -// Cover uncaught exceptions -// Returning true will suppress the default browser handler, -// returning false will let it run. -window.onerror = function ( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not suppressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend( function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: validTest } ) ); - } - return false; - } - - return ret; -}; - -function done() { - config.autorun = true; - - // Log the last module results - if ( config.previousModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - delete config.previousModule; - - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - runtime = +new Date() - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - "Tests completed in ", - runtime, - " milliseconds.
      ", - "", - passed, - " assertions of ", - config.stats.all, - " passed, ", - config.stats.bad, - " failed." - ].join( "" ); - - if ( banner ) { - banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && defined.document && document.title ) { - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( config.stats.bad ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { - // `key` & `i` initialized at top of scope - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( config.scrolltop && window.scrollTo ) { - window.scrollTo(0, 0); - } - - runLoggingCallbacks( "done", QUnit, { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); -} - -/** @return Boolean: true if this test should be ran */ -function validTest( test ) { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = config.module && config.module.toLowerCase(), - fullName = ( test.module + ": " + test.testName ).toLowerCase(); - - // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { - delete test.callback.validTest; - return true; - } - - if ( config.testNumber.length > 0 ) { - if ( inArray( test.testNumber, config.testNumber ) < 0 ) { - return false; - } - } - - if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; -} - -// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) -// Later Safari and IE10 are supposed to support error.stack as well -// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack -function extractStacktrace( e, offset ) { - offset = offset === undefined ? 3 : offset; - - var stack, include, i; - - if ( e.stacktrace ) { - // Opera - return e.stacktrace.split( "\n" )[ offset + 3 ]; - } else if ( e.stack ) { - // Firefox, Chrome - stack = e.stack.split( "\n" ); - if (/^error$/i.test( stack[0] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - } else if ( e.sourceURL ) { - // Safari, PhantomJS - // hopefully one day Safari provides actual stacktraces - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } -} -function sourceFromStacktrace( offset ) { - try { - throw new Error(); - } catch ( e ) { - return extractStacktrace( e, offset ); - } -} - -/** - * Escape text for attribute or text content. - */ -function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch( s ) { - case "'": - return "'"; - case "\"": - return """; - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - } - }); -} - -function synchronize( callback, last ) { - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process( last ); - } -} - -function process( last ) { - function next() { - process( last ); - } - var start = new Date().getTime(); - config.depth = config.depth ? config.depth + 1 : 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { - config.queue.shift()(); - } else { - setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - if ( hasOwn.call( window, key ) ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } - } -} - -function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; - - saveGlobal(); - - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); - } - - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; -} - -function extend( a, b ) { - for ( var prop in b ) { - if ( hasOwn.call( b, prop ) ) { - // Avoid "Member not found" error in IE8 caused by messing with window.constructor - if ( !( prop === "constructor" && a === window ) ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; - } else { - a[ prop ] = b[ prop ]; - } - } - } - } - - return a; -} - -/** - * @param {HTMLElement} elem - * @param {string} type - * @param {Function} fn - */ -function addEvent( elem, type, fn ) { - if ( elem.addEventListener ) { - - // Standards-based browsers - elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - - // support: IE <9 - elem.attachEvent( "on" + type, fn ); - } else { - - // Caller must ensure support for event listeners is present - throw new Error( "addEvent() was called in a context without event listener support" ); - } -} - -/** - * @param {Array|NodeList} elems - * @param {string} type - * @param {Function} fn - */ -function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[i], type, fn ); - } -} - -function hasClass( elem, name ) { - return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; -} - -function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += (elem.className ? " " : "") + name; - } -} - -function removeClass( elem, name ) { - var set = " " + elem.className + " "; - // Class name may appear multiple times - while ( set.indexOf(" " + name + " ") > -1 ) { - set = set.replace(" " + name + " " , " "); - } - // If possible, trim it for prettiness, but not necessarily - elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, ""); -} - -function id( name ) { - return defined.document && document.getElementById && document.getElementById( name ); -} - -function registerLoggingCallback( key ) { - return function( callback ) { - config[key].push( callback ); - }; -} - -// Supports deprecated method of completely overwriting logging callbacks -function runLoggingCallbacks( key, scope, args ) { - var i, callbacks; - if ( QUnit.hasOwnProperty( key ) ) { - QUnit[ key ].call(scope, args ); - } else { - callbacks = config[ key ]; - for ( i = 0; i < callbacks.length; i++ ) { - callbacks[ i ].call( scope, args ); - } - } -} - -// from jquery.js -function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; -} - -function Test( settings ) { - extend( this, settings ); - this.assertions = []; - this.testNumber = ++Test.count; -} - -Test.count = 0; - -Test.prototype = { - init: function() { - var a, b, li, - tests = id( "qunit-tests" ); - - if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; - - // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; - a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); - li.appendChild( b ); - li.appendChild( a ); - li.className = "running"; - li.id = this.id = "qunit-test-output" + testId++; - - tests.appendChild( li ); - } - }, - setup: function() { - if ( - // Emit moduleStart when we're switching from one module to another - this.module !== config.previousModule || - // They could be equal (both undefined) but if the previousModule property doesn't - // yet exist it means this is the first test in a suite that isn't wrapped in a - // module, in which case we'll just emit a moduleStart event for 'undefined'. - // Without this, reporters can get testStart before moduleStart which is a problem. - !hasOwn.call( config, "previousModule" ) - ) { - if ( hasOwn.call( config, "previousModule" ) ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } - - config.current = this; - - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment ); - - this.started = +new Date(); - runLoggingCallbacks( "testStart", QUnit, { - name: this.testName, - module: this.module - }); - - /*jshint camelcase:false */ - - - /** - * Expose the current test environment. - * - * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead. - */ - QUnit.current_testEnvironment = this.testEnvironment; - - /*jshint camelcase:true */ - - if ( !config.pollution ) { - saveGlobal(); - } - if ( config.notrycatch ) { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - return; - } - try { - this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - }, - run: function() { - config.current = this; - - var running = id( "qunit-testresult" ); - - if ( running ) { - running.innerHTML = "Running:
      " + this.nameHtml; - } - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = +new Date(); - - if ( config.notrycatch ) { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - return; - } - - try { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - } catch( e ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - teardown: function() { - config.current = this; - if ( config.notrycatch ) { - if ( typeof this.callbackRuntime === "undefined" ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - } - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - return; - } else { - try { - this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); - } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - } - checkPollution(); - }, - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); - } - - var i, assertion, a, b, time, li, ol, - test = this, - good = 0, - bad = 0, - tests = id( "qunit-tests" ); - - this.runtime = +new Date() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - ol = document.createElement( "ol" ); - ol.className = "qunit-assert-list"; - - for ( i = 0; i < this.assertions.length; i++ ) { - assertion = this.assertions[i]; - - li = document.createElement( "li" ); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - if ( QUnit.config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); - } - } - - if ( bad === 0 ) { - addClass( ol, "qunit-collapsed" ); - } - - // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; - - addEvent(b, "click", function() { - var next = b.parentNode.lastChild, - collapsed = hasClass( next, "qunit-collapsed" ); - ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); - }); - - addEvent(b, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = QUnit.url({ testNumber: test.testNumber }); - } - }); - - // `time` initialized at top of scope - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; - - // `li` initialized at top of scope - li = id( this.id ); - li.className = bad ? "fail" : "pass"; - li.removeChild( li.firstChild ); - a = li.firstChild; - li.appendChild( b ); - li.appendChild( a ); - li.appendChild( time ); - li.appendChild( ol ); - - } else { - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - runLoggingCallbacks( "testDone", QUnit, { - name: this.testName, - module: this.module, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - runtime: this.runtime, - // DEPRECATED: this property will be removed in 2.0.0, use runtime instead - duration: this.runtime - }); - - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - } -}; - -// `assert` initialized at top of scope -// Assert helpers -// All of these must either call QUnit.push() or manually do: -// - runLoggingCallbacks( "log", .. ); -// - config.current.assertions.push({ .. }); -assert = QUnit.assert = { - /** - * Asserts rough true-ish result. - * @name ok - * @function - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function( result, msg ) { - if ( !config.current ) { - throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - result = !!result; - msg = msg || ( result ? "okay" : "failed" ); - - var source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: msg - }; - - msg = "" + escapeText( msg ) + ""; - - if ( !result ) { - source = sourceFromStacktrace( 2 ); - if ( source ) { - details.source = source; - msg += "
      Source:
      " +
      -					escapeText( source ) +
      -					"
      "; - } - } - runLoggingCallbacks( "log", QUnit, details ); - config.current.assertions.push({ - result: result, - message: msg - }); - }, - - /** - * Assert that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * @name equal - * @function - * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); - */ - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected == actual, actual, expected, message ); - }, - - /** - * @name notEqual - * @function - */ - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected != actual, actual, expected, message ); - }, - - /** - * @name propEqual - * @function - */ - propEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notPropEqual - * @function - */ - notPropEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name deepEqual - * @function - */ - deepEqual: function( actual, expected, message ) { - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notDeepEqual - * @function - */ - notDeepEqual: function( actual, expected, message ) { - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name strictEqual - * @function - */ - strictEqual: function( actual, expected, message ) { - QUnit.push( expected === actual, actual, expected, message ); - }, - - /** - * @name notStrictEqual - * @function - */ - notStrictEqual: function( actual, expected, message ) { - QUnit.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, - expectedOutput = expected, - ok = false; - - // 'expected' is optional - if ( !message && typeof expected === "string" ) { - message = expected; - expected = null; - } - - config.current.ignoreGlobalErrors = true; - try { - block.call( config.current.testEnvironment ); - } catch (e) { - actual = e; - } - config.current.ignoreGlobalErrors = false; - - if ( actual ) { - - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - - // expected is an Error object - } else if ( expected instanceof Error ) { - ok = actual instanceof Error && - actual.name === expected.name && - actual.message === expected.message; - - // expected is a regexp - } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( errorString( actual ) ); - - // expected is a string - } else if ( QUnit.objectType( expected ) === "string" ) { - ok = expected === errorString( actual ); - - // expected is a constructor - } else if ( actual instanceof expected ) { - ok = true; - - // expected is a validation function which returns true is validation passed - } else if ( expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - - QUnit.push( ok, actual, expectedOutput, message ); - } else { - QUnit.pushFailure( message, null, "No exception was thrown." ); - } - } -}; - -/** - * @deprecated since 1.8.0 - * Kept assertion helpers in root for backwards compatibility. - */ -extend( QUnit.constructor.prototype, assert ); - -/** - * @deprecated since 1.9.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.raises = function() { - QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" ); -}; - -/** - * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 - * Kept to avoid TypeErrors for undefined methods. - */ -QUnit.constructor.prototype.equals = function() { - QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); -}; -QUnit.constructor.prototype.same = function() { - QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); -}; - -// Test for equality any JavaScript type. -// Author: Philippe Rathé -QUnit.equiv = (function() { - - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - // stack to decide between skip/abort functions - callers = [], - // stack to avoiding loops from circular referencing - parents = [], - parentsB = [], - - getProto = Object.getPrototypeOf || function ( obj ) { - /*jshint camelcase:false */ - return obj.__proto__; - }, - callbacks = (function () { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - // to catch short annotation VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - // the regex itself - a.source === b.source && - // and its modifiers - a.global === b.global && - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[callers.length - 1]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop, aCircular, bCircular; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - parents.pop(); - parentsB.pop(); - return false; - } - } - } - if ( !loop && !innerEquiv(a[i], b[i]) ) { - parents.pop(); - parentsB.pop(); - return false; - } - } - parents.pop(); - parentsB.pop(); - return true; - }, - - "object": function( b, a ) { - /*jshint forin:false */ - var i, j, loop, aCircular, bCircular, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || - ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - - // track reference to avoid circular references - parents.push( a ); - parentsB.push( b ); - - // be strict: don't ensure hasOwnProperty and go deep - for ( i in a ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - aCircular = parents[j] === a[i]; - bCircular = parentsB[j] === b[i]; - if ( aCircular || bCircular ) { - if ( a[i] === b[i] || aCircular && bCircular ) { - loop = true; - } else { - eq = false; - break; - } - } - } - aProperties.push(i); - if ( !loop && !innerEquiv(a[i], b[i]) ) { - eq = false; - break; - } - } - - parents.pop(); - parentsB.pop(); - callers.pop(); // unstack, we are done - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType(a) !== QUnit.objectType(b) ) { - return false; // don't lose time with error prone cases - } else { - return bindCallbacks(a, callbacks, [ b, a ]); - } - - // apply transition with (1..n) arguments - }( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) ); - }; - - return innerEquiv; -}()); - -/** - * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | - * http://flesler.blogspot.com Licensed under BSD - * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 - * - * @projectDescription Advanced and extensible data dumping for Javascript. - * @version 1.0.0 - * @author Ariel Flesler - * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} - */ -QUnit.jsDump = (function() { - function quote( str ) { - return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = jsDump.separator(), - base = jsDump.indent(), - inner = jsDump.indent(1); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join(s); - } - function array( arr, stack ) { - var i = arr.length, ret = new Array(i); - this.up(); - while ( i-- ) { - ret[i] = this.parse( arr[i] , undefined , stack); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - jsDump = { - // type is used mostly internally, you can fix a (custom)type in advance - parse: function( obj, type, stack ) { - stack = stack || [ ]; - var inStack, res, - parser = this.parsers[ type || this.typeOf(obj) ]; - - type = typeof parser; - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + (inStack - stack.length) + ")"; - } - if ( type === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( type === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj) ) { - type = "date"; - } else if ( QUnit.is( "function", obj) ) { - type = "function"; - } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - // native arrays - toString.call( obj ) === "[object Array]" || - // NodeList objects - ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "
      " : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this.depth + ( extra || 0 ) ).join(chr); - }, - up: function( a ) { - this.depth += a || 1; - }, - down: function( a ) { - this.depth -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - depth: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function(error) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - // functions never have name in IE - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - /*jshint forin:false */ - var ret = [ ], keys, key, val, i; - QUnit.jsDump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); - } - QUnit.jsDump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = QUnit.jsDump.HTML ? "<" : "<", - close = QUnit.jsDump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[i].nodeValue; - // IE6 includes all attributes in .attributes, even ones not explicitly set. - // Those have values like undefined, null, 0, false, "" or "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array(l); - while ( l-- ) { - // 97 is 'a' - args[l] = String.fromCharCode(97+l); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return jsDump; -}()); - -/* - * Javascript Diff Algorithm - * By John Resig (http://ejohn.org/) - * Modified by Chu Alan "sprite" - * - * Released under the MIT license. - * - * More Info: - * http://ejohn.org/projects/javascript-diff-algorithm/ - * - * Usage: QUnit.diff(expected, actual) - * - * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" - */ -QUnit.diff = (function() { - /*jshint eqeqeq:false, eqnull:true */ - function diff( o, n ) { - var i, - ns = {}, - os = {}; - - for ( i = 0; i < n.length; i++ ) { - if ( !hasOwn.call( ns, n[i] ) ) { - ns[ n[i] ] = { - rows: [], - o: null - }; - } - ns[ n[i] ].rows.push( i ); - } - - for ( i = 0; i < o.length; i++ ) { - if ( !hasOwn.call( os, o[i] ) ) { - os[ o[i] ] = { - rows: [], - n: null - }; - } - os[ o[i] ].rows.push( i ); - } - - for ( i in ns ) { - if ( hasOwn.call( ns, i ) ) { - if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { - n[ ns[i].rows[0] ] = { - text: n[ ns[i].rows[0] ], - row: os[i].rows[0] - }; - o[ os[i].rows[0] ] = { - text: o[ os[i].rows[0] ], - row: ns[i].rows[0] - }; - } - } - } - - for ( i = 0; i < n.length - 1; i++ ) { - if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && - n[ i + 1 ] == o[ n[i].row + 1 ] ) { - - n[ i + 1 ] = { - text: n[ i + 1 ], - row: n[i].row + 1 - }; - o[ n[i].row + 1 ] = { - text: o[ n[i].row + 1 ], - row: i + 1 - }; - } - } - - for ( i = n.length - 1; i > 0; i-- ) { - if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && - n[ i - 1 ] == o[ n[i].row - 1 ]) { - - n[ i - 1 ] = { - text: n[ i - 1 ], - row: n[i].row - 1 - }; - o[ n[i].row - 1 ] = { - text: o[ n[i].row - 1 ], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function( o, n ) { - o = o.replace( /\s+$/, "" ); - n = n.replace( /\s+$/, "" ); - - var i, pre, - str = "", - out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), - oSpace = o.match(/\s+/g), - nSpace = n.match(/\s+/g); - - if ( oSpace == null ) { - oSpace = [ " " ]; - } - else { - oSpace.push( " " ); - } - - if ( nSpace == null ) { - nSpace = [ " " ]; - } - else { - nSpace.push( " " ); - } - - if ( out.n.length === 0 ) { - for ( i = 0; i < out.o.length; i++ ) { - str += "" + out.o[i] + oSpace[i] + ""; - } - } - else { - if ( out.n[0].text == null ) { - for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { - str += "" + out.o[n] + oSpace[n] + ""; - } - } - - for ( i = 0; i < out.n.length; i++ ) { - if (out.n[i].text == null) { - str += "" + out.n[i] + nSpace[i] + ""; - } - else { - // `pre` initialized at top of scope - pre = ""; - - for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { - pre += "" + out.o[n] + oSpace[n] + ""; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; -}()); - -// For browser, export only select globals -if ( typeof window !== "undefined" ) { - extend( window, QUnit.constructor.prototype ); - window.QUnit = QUnit; -} - -// For CommonJS environments, export everything -if ( typeof module !== "undefined" && module.exports ) { - module.exports = QUnit; -} - - -// Get a reference to the global object, like window in browsers -}( (function() { - return this; -})() )); diff --git a/test/requirejs/index.html b/test/requirejs/index.html deleted file mode 100755 index 09908f1..0000000 --- a/test/requirejs/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - Finite State Machine Tests - USING REQUIREJS INCLUDE MECHANISM - - - - - - -

      QUnit Test Suite

      -

      -
      -

      -
        -
        test markup
        - - diff --git a/test/requirejs/require.js b/test/requirejs/require.js deleted file mode 100755 index ed535a8..0000000 --- a/test/requirejs/require.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - RequireJS 1.0.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. - Available via the MIT or new BSD license. - see: http://github.com/jrburke/requirejs for details -*/ -var requirejs,require,define; -(function(){function J(a){return N.call(a)==="[object Function]"}function F(a){return N.call(a)==="[object Array]"}function Z(a,c,l){for(var j in c)if(!(j in K)&&(!(j in a)||l))a[j]=c[j];return d}function O(a,c,d){a=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+a);if(d)a.originalError=d;return a}function $(a,c,d){var j,k,s;for(j=0;s=c[j];j++){s=typeof s==="string"?{name:s}:s;k=s.location;if(d&&(!k||k.indexOf("/")!==0&&k.indexOf(":")===-1))k=d+"/"+(k||s.name);a[s.name]={name:s.name,location:k|| -s.name,main:(s.main||"main").replace(ea,"").replace(aa,"")}}}function U(a,c){a.holdReady?a.holdReady(c):c?a.readyWait+=1:a.ready(!0)}function fa(a){function c(b,f){var g,m;if(b&&b.charAt(0)===".")if(f){q.pkgs[f]?f=[f]:(f=f.split("/"),f=f.slice(0,f.length-1));g=b=f.concat(b.split("/"));var a;for(m=0;a=g[m];m++)if(a===".")g.splice(m,1),m-=1;else if(a==="..")if(m===1&&(g[2]===".."||g[0]===".."))break;else m>0&&(g.splice(m-1,2),m-=2);m=q.pkgs[g=b[0]];b=b.join("/");m&&b===g+"/"+m.main&&(b=g)}else b.indexOf("./")=== -0&&(b=b.substring(2));return b}function l(b,f){var g=b?b.indexOf("!"):-1,m=null,a=f?f.name:null,h=b,e,d;g!==-1&&(m=b.substring(0,g),b=b.substring(g+1,b.length));m&&(m=c(m,a));b&&(m?e=(g=n[m])&&g.normalize?g.normalize(b,function(b){return c(b,a)}):c(b,a):(e=c(b,a),d=F[e],d||(d=i.nameToUrl(b,null,f),F[e]=d)));return{prefix:m,name:e,parentMap:f,url:d,originalName:h,fullName:m?m+"!"+(e||""):e}}function j(){var b=!0,f=q.priorityWait,g,a;if(f){for(a=0;g=f[a];a++)if(!r[g]){b=!1;break}b&&delete q.priorityWait}return b} -function k(b,f,g){return function(){var a=ga.call(arguments,0),c;if(g&&J(c=a[a.length-1]))c.__requireJsBuild=!0;a.push(f);return b.apply(null,a)}}function s(b,f,g){f=k(g||i.require,b,f);Z(f,{nameToUrl:k(i.nameToUrl,b),toUrl:k(i.toUrl,b),defined:k(i.requireDefined,b),specified:k(i.requireSpecified,b),isBrowser:d.isBrowser});return f}function p(b){var f,g,a,c=b.callback,h=b.map,e=h.fullName,ba=b.deps;a=b.listeners;if(c&&J(c)){if(q.catchError.define)try{g=d.execCb(e,b.callback,ba,n[e])}catch(j){f=j}else g= -d.execCb(e,b.callback,ba,n[e]);if(e)(c=b.cjsModule)&&c.exports!==void 0&&c.exports!==n[e]?g=n[e]=b.cjsModule.exports:g===void 0&&b.usingExports?g=n[e]:(n[e]=g,G[e]&&(S[e]=!0))}else e&&(g=n[e]=c,G[e]&&(S[e]=!0));if(w[b.id])delete w[b.id],b.isDone=!0,i.waitCount-=1,i.waitCount===0&&(I=[]);delete L[e];if(d.onResourceLoad&&!b.placeholder)d.onResourceLoad(i,h,b.depArray);if(f)return g=(e?l(e).url:"")||f.fileName||f.sourceURL,a=f.moduleTree,f=O("defineerror",'Error evaluating module "'+e+'" at location "'+ -g+'":\n'+f+"\nfileName:"+g+"\nlineNumber: "+(f.lineNumber||f.line),f),f.moduleName=e,f.moduleTree=a,d.onError(f);for(f=0;c=a[f];f++)c(g)}function t(b,f){return function(g){b.depDone[f]||(b.depDone[f]=!0,b.deps[f]=g,b.depCount-=1,b.depCount||p(b))}}function o(b,f){var g=f.map,a=g.fullName,c=g.name,h=M[b]||(M[b]=n[b]),e;if(!f.loading)f.loading=!0,e=function(b){f.callback=function(){return b};p(f);r[f.id]=!0;z()},e.fromText=function(b,f){var g=P;r[b]=!1;i.scriptCount+=1;i.fake[b]=!0;g&&(P=!1);d.exec(f); -g&&(P=!0);i.completeLoad(b)},a in n?e(n[a]):h.load(c,s(g.parentMap,!0,function(b,a){var c=[],e,m;for(e=0;m=b[e];e++)m=l(m,g.parentMap),b[e]=m.fullName,m.prefix||c.push(b[e]);f.moduleDeps=(f.moduleDeps||[]).concat(c);return i.require(b,a)}),e,q)}function x(b){w[b.id]||(w[b.id]=b,I.push(b),i.waitCount+=1)}function C(b){this.listeners.push(b)}function u(b,f){var g=b.fullName,a=b.prefix,c=a?M[a]||(M[a]=n[a]):null,h,e;g&&(h=L[g]);if(!h&&(e=!0,h={id:(a&&!c?N++ +"__p@:":"")+(g||"__r@"+N++),map:b,depCount:0, -depDone:[],depCallbacks:[],deps:[],listeners:[],add:C},A[h.id]=!0,g&&(!a||M[a])))L[g]=h;a&&!c?(g=l(a),a in n&&!n[a]&&(delete n[a],delete Q[g.url]),a=u(g,!0),a.add(function(){var f=l(b.originalName,b.parentMap),f=u(f,!0);h.placeholder=!0;f.add(function(b){h.callback=function(){return b};p(h)})})):e&&f&&(r[h.id]=!1,i.paused.push(h),x(h));return h}function B(b,f,a,c){var b=l(b,c),d=b.name,h=b.fullName,e=u(b),j=e.id,k=e.deps,o;if(h){if(h in n||r[j]===!0||h==="jquery"&&q.jQuery&&q.jQuery!==a().fn.jquery)return; -A[j]=!0;r[j]=!0;h==="jquery"&&a&&V(a())}e.depArray=f;e.callback=a;for(a=0;a0)){if(q.priorityWait)if(j())z();else return;for(h in r)if(!(h in K)&&(c=!0,!r[h]))if(b)a+=h+" ";else if(l=!0,h.indexOf("!")===-1){k=[];break}else(e=L[h]&&L[h].moduleDeps)&&k.push.apply(k,e);if(c||i.waitCount){if(b&&a)return b=O("timeout","Load timeout for modules: "+a),b.requireType="timeout",b.requireModules=a,b.contextName=i.contextName,d.onError(b);if(l&&k.length)for(a= -0;h=w[k[a]];a++)if(h=E(h,{})){y(h,{});break}if(!b&&(l||i.scriptCount)){if((H||ca)&&!W)W=setTimeout(function(){W=0;D()},50)}else{if(i.waitCount){for(a=0;h=I[a];a++)y(h,{});i.paused.length&&z();X<5&&(X+=1,D())}X=0;d.checkReadyState()}}}}var i,z,q={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},catchError:{}},R=[],A={require:!0,exports:!0,module:!0},F={},n={},r={},w={},I=[],Q={},N=0,L={},M={},G={},S={},Y=0;V=function(b){if(!i.jQuery&&(b=b||(typeof jQuery!=="undefined"?jQuery:null))&&!(q.jQuery&&b.fn.jquery!== -q.jQuery)&&("holdReady"in b||"readyWait"in b))if(i.jQuery=b,v(["jquery",[],function(){return jQuery}]),i.scriptCount)U(b,!0),i.jQueryIncremented=!0};z=function(){var b,a,c,l,k,h;i.takeGlobalQueue();Y+=1;if(i.scriptCount<=0)i.scriptCount=0;for(;R.length;)if(b=R.shift(),b[0]===null)return d.onError(O("mismatch","Mismatched anonymous define() module: "+b[b.length-1]));else v(b);if(!q.priorityWait||j())for(;i.paused.length;){k=i.paused;i.pausedCount+=k.length;i.paused=[];for(l=0;b=k[l];l++)a=b.map,c= -a.url,h=a.fullName,a.prefix?o(a.prefix,b):!Q[c]&&!r[h]&&(d.load(i,h,c),c.indexOf("empty:")!==0&&(Q[c]=!0));i.startTime=(new Date).getTime();i.pausedCount-=k.length}Y===1&&D();Y-=1};i={contextName:a,config:q,defQueue:R,waiting:w,waitCount:0,specified:A,loaded:r,urlMap:F,urlFetched:Q,scriptCount:0,defined:n,paused:[],pausedCount:0,plugins:M,needFullExec:G,fake:{},fullExec:S,managerCallbacks:L,makeModuleMap:l,normalize:c,configure:function(b){var a,c,d;b.baseUrl&&b.baseUrl.charAt(b.baseUrl.length-1)!== -"/"&&(b.baseUrl+="/");a=q.paths;d=q.pkgs;Z(q,b,!0);if(b.paths){for(c in b.paths)c in K||(a[c]=b.paths[c]);q.paths=a}if((a=b.packagePaths)||b.packages){if(a)for(c in a)c in K||$(d,a[c],c);b.packages&&$(d,b.packages);q.pkgs=d}if(b.priority)c=i.requireWait,i.requireWait=!1,z(),i.require(b.priority),z(),i.requireWait=c,q.priorityWait=b.priority;if(b.deps||b.callback)i.require(b.deps||[],b.callback)},requireDefined:function(b,a){return l(b,a).fullName in n},requireSpecified:function(b,a){return l(b,a).fullName in -A},require:function(b,c,g){if(typeof b==="string"){if(J(c))return d.onError(O("requireargs","Invalid require call"));if(d.get)return d.get(i,b,c);c=l(b,c);b=c.fullName;return!(b in n)?d.onError(O("notloaded","Module name '"+c.fullName+"' has not been loaded yet for context: "+a)):n[b]}(b&&b.length||c)&&B(null,b,c,g);if(!i.requireWait)for(;!i.scriptCount&&i.paused.length;)z();return i.require},takeGlobalQueue:function(){T.length&&(ia.apply(i.defQueue,[i.defQueue.length-1,0].concat(T)),T=[])},completeLoad:function(b){var a; -for(i.takeGlobalQueue();R.length;)if(a=R.shift(),a[0]===null){a[0]=b;break}else if(a[0]===b)break;else v(a),a=null;a?v(a):v([b,[],b==="jquery"&&typeof jQuery!=="undefined"?function(){return jQuery}:null]);d.isAsync&&(i.scriptCount-=1);z();d.isAsync||(i.scriptCount-=1)},toUrl:function(b,a){var c=b.lastIndexOf("."),d=null;c!==-1&&(d=b.substring(c,b.length),b=b.substring(0,c));return i.nameToUrl(b,d,a)},nameToUrl:function(b,a,g){var l,k,h,e,j=i.config,b=c(b,g&&g.fullName);if(d.jsExtRegExp.test(b))a= -b+(a?a:"");else{l=j.paths;k=j.pkgs;g=b.split("/");for(e=g.length;e>0;e--)if(h=g.slice(0,e).join("/"),l[h]){g.splice(0,e,l[h]);break}else if(h=k[h]){b=b===h.name?h.location+"/"+h.main:h.location;g.splice(0,e,b);break}a=g.join("/")+(a||".js");a=(a.charAt(0)==="/"||a.match(/^\w+:/)?"":j.baseUrl)+a}return j.urlArgs?a+((a.indexOf("?")===-1?"?":"&")+j.urlArgs):a}};i.jQueryCheck=V;i.resume=z;return i}function ja(){var a,c,d;if(B&&B.readyState==="interactive")return B;a=document.getElementsByTagName("script"); -for(c=a.length-1;c>-1&&(d=a[c]);c--)if(d.readyState==="interactive")return B=d;return null}var ka=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,la=/require\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/^\.\//,aa=/\.js$/,N=Object.prototype.toString,t=Array.prototype,ga=t.slice,ia=t.splice,H=!!(typeof window!=="undefined"&&navigator&&document),ca=!H&&typeof importScripts!=="undefined",ma=H&&navigator.platform==="PLAYSTATION 3"?/^complete$/:/^(complete|loaded)$/,da=typeof opera!=="undefined"&&opera.toString()==="[object Opera]", -K={},C={},T=[],B=null,X=0,P=!1,ha={require:!0,module:!0,exports:!0},d,t={},I,x,u,D,o,v,E,A,y,V,W;if(typeof define==="undefined"){if(typeof requirejs!=="undefined")if(J(requirejs))return;else t=requirejs,requirejs=void 0;typeof require!=="undefined"&&!J(require)&&(t=require,require=void 0);d=requirejs=function(a,c,d){var j="_",k;!F(a)&&typeof a!=="string"&&(k=a,F(c)?(a=c,c=d):a=[]);if(k&&k.context)j=k.context;d=C[j]||(C[j]=fa(j));k&&d.configure(k);return d.require(a,c)};d.config=function(a){return d(a)}; -require||(require=d);d.toUrl=function(a){return C._.toUrl(a)};d.version="1.0.6";d.jsExtRegExp=/^\/|:|\?|\.js$/;x=d.s={contexts:C,skipAsync:{}};if(d.isAsync=d.isBrowser=H)if(u=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0])u=x.head=D.parentNode;d.onError=function(a){throw a;};d.load=function(a,c,l){d.resourcesReady(!1);a.scriptCount+=1;d.attach(l,a,c);if(a.jQuery&&!a.jQueryIncremented)U(a.jQuery,!0),a.jQueryIncremented=!0};define=function(a,c,d){var j,k; -typeof a!=="string"&&(d=c,c=a,a=null);F(c)||(d=c,c=[]);!c.length&&J(d)&&d.length&&(d.toString().replace(ka,"").replace(la,function(a,d){c.push(d)}),c=(d.length===1?["require"]:["require","exports","module"]).concat(c));if(P&&(j=I||ja()))a||(a=j.getAttribute("data-requiremodule")),k=C[j.getAttribute("data-requirecontext")];(k?k.defQueue:T).push([a,c,d])};define.amd={multiversion:!0,plugins:!0,jQuery:!0};d.exec=function(a){return eval(a)};d.execCb=function(a,c,d,j){return c.apply(j,d)};d.addScriptToDom= -function(a){I=a;D?u.insertBefore(a,D):u.appendChild(a);I=null};d.onScriptLoad=function(a){var c=a.currentTarget||a.srcElement,l;if(a.type==="load"||c&&ma.test(c.readyState))B=null,a=c.getAttribute("data-requirecontext"),l=c.getAttribute("data-requiremodule"),C[a].completeLoad(l),c.detachEvent&&!da?c.detachEvent("onreadystatechange",d.onScriptLoad):c.removeEventListener("load",d.onScriptLoad,!1)};d.attach=function(a,c,l,j,k,o){var p;if(H)return j=j||d.onScriptLoad,p=c&&c.config&&c.config.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml", -"html:script"):document.createElement("script"),p.type=k||c&&c.config.scriptType||"text/javascript",p.charset="utf-8",p.async=!x.skipAsync[a],c&&p.setAttribute("data-requirecontext",c.contextName),p.setAttribute("data-requiremodule",l),p.attachEvent&&!da?(P=!0,o?p.onreadystatechange=function(){if(p.readyState==="loaded")p.onreadystatechange=null,p.attachEvent("onreadystatechange",j),o(p)}:p.attachEvent("onreadystatechange",j)):p.addEventListener("load",j,!1),p.src=a,o||d.addScriptToDom(p),p;else ca&& -(importScripts(a),c.completeLoad(l));return null};if(H){o=document.getElementsByTagName("script");for(A=o.length-1;A>-1&&(v=o[A]);A--){if(!u)u=v.parentNode;if(E=v.getAttribute("data-main")){if(!t.baseUrl)o=E.split("/"),v=o.pop(),o=o.length?o.join("/")+"/":"./",t.baseUrl=o,E=v.replace(aa,"");t.deps=t.deps?t.deps.concat(E):[E];break}}}d.checkReadyState=function(){var a=x.contexts,c;for(c in a)if(!(c in K)&&a[c].waitCount)return;d.resourcesReady(!0)};d.resourcesReady=function(a){var c,l;d.resourcesDone= -a;if(d.resourcesDone)for(l in a=x.contexts,a)if(!(l in K)&&(c=a[l],c.jQueryIncremented))U(c.jQuery,!1),c.jQueryIncremented=!1};d.pageLoaded=function(){if(document.readyState!=="complete")document.readyState="complete"};if(H&&document.addEventListener&&!document.readyState)document.readyState="loading",window.addEventListener("load",d.pageLoaded,!1);d(t);if(d.isAsync&&typeof setTimeout!=="undefined")y=x.contexts[t.context||"_"],y.requireWait=!0,setTimeout(function(){y.requireWait=!1;y.scriptCount|| -y.resume();d.checkReadyState()},0)}})(); diff --git a/test/runner.js b/test/runner.js deleted file mode 100644 index 464fa3b..0000000 --- a/test/runner.js +++ /dev/null @@ -1,22 +0,0 @@ -// -// To run tests via nodejs you must have nodejs and npm installed -// -// > npm install # to install node-qunit -// > node test/runner -// - -var runner = require("qunit"); - -runner.run({ - - code: "./state-machine.js", - - tests: [ - "test/test_basics.js", - "test/test_advanced.js", - "test/test_classes.js", - "test/test_async.js", - "test/test_initialize.js" - ] - -}); diff --git a/test/test_advanced.js b/test/test_advanced.js deleted file mode 100755 index 62cd9cb..0000000 --- a/test/test_advanced.js +++ /dev/null @@ -1,302 +0,0 @@ -//----------------------------------------------------------------------------- - -QUnit.module("advanced"); - -//----------------------------------------------------------------------------- - -test("multiple 'from' states for the same event", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: ['green', 'yellow'], to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: ['yellow', 'red'], to: 'green' }, - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - ok(fsm.can('warn'), "should be able to warn from green state") - ok(fsm.can('panic'), "should be able to panic from green state") - ok(fsm.cannot('calm'), "should NOT be able to calm from green state") - ok(fsm.cannot('clear'), "should NOT be able to clear from green state") - - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from green to red"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from red to green"); - -}); - -//----------------------------------------------------------------------------- - -test("multiple 'to' states for the same event", function() { - - var fsm = StateMachine.create({ - initial: 'hungry', - events: [ - { name: 'eat', from: 'hungry', to: 'satisfied' }, - { name: 'eat', from: 'satisfied', to: 'full' }, - { name: 'eat', from: 'full', to: 'sick' }, - { name: 'rest', from: ['hungry', 'satisfied', 'full', 'sick'], to: 'hungry' }, - ]}); - - equal(fsm.current, 'hungry'); - - ok(fsm.can('eat')); - ok(fsm.can('rest')); - - fsm.eat(); - equal(fsm.current, 'satisfied'); - - fsm.eat(); - equal(fsm.current, 'full'); - - fsm.eat(); - equal(fsm.current, 'sick'); - - fsm.rest(); - equal(fsm.current, 'hungry'); - -}); - -//----------------------------------------------------------------------------- - -test("no-op transitions (github issue #5) with multiple from states", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: ['green', 'yellow'], to: 'red' }, - { name: 'noop', from: ['green', 'yellow'] }, // NOTE: 'to' not specified - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: ['yellow', 'red'], to: 'green' }, - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - ok(fsm.can('warn'), "should be able to warn from green state") - ok(fsm.can('panic'), "should be able to panic from green state") - ok(fsm.can('noop'), "should be able to noop from green state") - ok(fsm.cannot('calm'), "should NOT be able to calm from green state") - ok(fsm.cannot('clear'), "should NOT be able to clear from green state") - - fsm.noop(); equal(fsm.current, 'green', "noop event should not transition"); - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - - ok(fsm.cannot('warn'), "should NOT be able to warn from yellow state") - ok(fsm.can('panic'), "should be able to panic from yellow state") - ok(fsm.can('noop'), "should be able to noop from yellow state") - ok(fsm.cannot('calm'), "should NOT be able to calm from yellow state") - ok(fsm.can('clear'), "should be able to clear from yellow state") - - fsm.noop(); equal(fsm.current, 'yellow', "noop event should not transition"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - - ok(fsm.cannot('warn'), "should NOT be able to warn from red state") - ok(fsm.cannot('panic'), "should NOT be able to panic from red state") - ok(fsm.cannot('noop'), "should NOT be able to noop from red state") - ok(fsm.can('calm'), "should be able to calm from red state") - ok(fsm.can('clear'), "should be able to clear from red state") - -}); - -//----------------------------------------------------------------------------- - -test("callbacks are called when appropriate for multiple 'from' and 'to' transitions", function() { - - var called = []; - - var fsm = StateMachine.create({ - initial: 'hungry', - events: [ - { name: 'eat', from: 'hungry', to: 'satisfied' }, - { name: 'eat', from: 'satisfied', to: 'full' }, - { name: 'eat', from: 'full', to: 'sick' }, - { name: 'rest', from: ['hungry', 'satisfied', 'full', 'sick'], to: 'hungry' }, - ], - callbacks: { - - // generic callbacks - onbeforeevent: function(event,from,to) { called.push('onbefore(' + event + ')'); }, - onafterevent: function(event,from,to) { called.push('onafter(' + event + ')'); }, - onleavestate: function(event,from,to) { called.push('onleave(' + from + ')'); }, - onenterstate: function(event,from,to) { called.push('onenter(' + to + ')'); }, - onchangestate: function(event,from,to) { called.push('onchange(' + from + ',' + to + ')'); }, - - // specific state callbacks - onenterhungry: function() { called.push('onenterhungry'); }, - onleavehungry: function() { called.push('onleavehungry'); }, - onentersatisfied: function() { called.push('onentersatisfied'); }, - onleavesatisfied: function() { called.push('onleavesatisfied'); }, - onenterfull: function() { called.push('onenterfull'); }, - onleavefull: function() { called.push('onleavefull'); }, - onentersick: function() { called.push('onentersick'); }, - onleavesick: function() { called.push('onleavesick'); }, - - // specific event callbacks - onbeforeeat: function() { called.push('onbeforeeat'); }, - onaftereat: function() { called.push('onaftereat'); }, - onbeforerest: function() { called.push('onbeforerest'); }, - onafterrest: function() { called.push('onafterrest'); } - } - }); - - called = []; - fsm.eat(); - deepEqual(called, [ - 'onbeforeeat', - 'onbefore(eat)', - 'onleavehungry', - 'onleave(hungry)', - 'onentersatisfied', - 'onenter(satisfied)', - 'onchange(hungry,satisfied)', - 'onaftereat', - 'onafter(eat)' - ]); - - called = []; - fsm.eat(); - deepEqual(called, [ - 'onbeforeeat', - 'onbefore(eat)', - 'onleavesatisfied', - 'onleave(satisfied)', - 'onenterfull', - 'onenter(full)', - 'onchange(satisfied,full)', - 'onaftereat', - 'onafter(eat)', - ]); - - called = []; - fsm.eat(); - deepEqual(called, [ - 'onbeforeeat', - 'onbefore(eat)', - 'onleavefull', - 'onleave(full)', - 'onentersick', - 'onenter(sick)', - 'onchange(full,sick)', - 'onaftereat', - 'onafter(eat)' - ]); - - called = []; - fsm.rest(); - deepEqual(called, [ - 'onbeforerest', - 'onbefore(rest)', - 'onleavesick', - 'onleave(sick)', - 'onenterhungry', - 'onenter(hungry)', - 'onchange(sick,hungry)', - 'onafterrest', - 'onafter(rest)' - ]); - -}); - -//----------------------------------------------------------------------------- - -test("callbacks are called when appropriate for prototype based state machine", function() { - - var myFSM = function() { - this.called = []; - this.startup(); - }; - - myFSM.prototype = { - - // generic callbacks - onbeforeevent: function(event,from,to) { this.called.push('onbefore(' + event + ')'); }, - onafterevent: function(event,from,to) { this.called.push('onafter(' + event + ')'); }, - onleavestate: function(event,from,to) { this.called.push('onleave(' + from + ')'); }, - onenterstate: function(event,from,to) { this.called.push('onenter(' + to + ')'); }, - onchangestate: function(event,from,to) { this.called.push('onchange(' + from + ',' + to + ')'); }, - - // specific state callbacks - onenternone: function() { this.called.push('onenternone'); }, - onleavenone: function() { this.called.push('onleavenone'); }, - onentergreen: function() { this.called.push('onentergreen'); }, - onleavegreen: function() { this.called.push('onleavegreen'); }, - onenteryellow : function() { this.called.push('onenteryellow'); }, - onleaveyellow: function() { this.called.push('onleaveyellow'); }, - onenterred: function() { this.called.push('onenterred'); }, - onleavered: function() { this.called.push('onleavered'); }, - - // specific event callbacks - onbeforestartup: function() { this.called.push('onbeforestartup'); }, - onafterstartup: function() { this.called.push('onafterstartup'); }, - onbeforewarn: function() { this.called.push('onbeforewarn'); }, - onafterwarn: function() { this.called.push('onafterwarn'); }, - onbeforepanic: function() { this.called.push('onbeforepanic'); }, - onafterpanic: function() { this.called.push('onafterpanic'); }, - onbeforeclear: function() { this.called.push('onbeforeclear'); }, - onafterclear: function() { this.called.push('onafterclear'); } - }; - - StateMachine.create({ - target: myFSM.prototype, - events: [ - { name: 'startup', from: 'none', to: 'green' }, - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'clear', from: 'yellow', to: 'green' } - ] - }); - - var a = new myFSM(); - var b = new myFSM(); - - equal(a.current, 'green', 'start with correct state'); - equal(b.current, 'green', 'start with correct state'); - - deepEqual(a.called, ['onbeforestartup', 'onbefore(startup)', 'onleavenone', 'onleave(none)', 'onentergreen', 'onenter(green)', 'onchange(none,green)', 'onafterstartup', 'onafter(startup)']); - deepEqual(b.called, ['onbeforestartup', 'onbefore(startup)', 'onleavenone', 'onleave(none)', 'onentergreen', 'onenter(green)', 'onchange(none,green)', 'onafterstartup', 'onafter(startup)']); - - a.called = []; - b.called = []; - - a.warn(); - - equal(a.current, 'yellow', 'maintain independent current state'); - equal(b.current, 'green', 'maintain independent current state'); - - deepEqual(a.called, ['onbeforewarn', 'onbefore(warn)', 'onleavegreen', 'onleave(green)', 'onenteryellow', 'onenter(yellow)', 'onchange(green,yellow)', 'onafterwarn', 'onafter(warn)']); - deepEqual(b.called, []); - -}); - - - -//----------------------------------------------------------------------------- - -test("double wildcard transition does not change current state", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: ['green', 'yellow'], to: 'red' }, - { name: 'noop', from: ['green', 'yellow'] }, // NOTE: 'to' not specified - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: ['yellow', 'red'], to: 'green' }, - { name: 'lightup', from: '*' }, // Note: "double wildcard" - { name: 'lightup', from: 'green', to: 'yellow' } - ]}); - - equal(fsm.current, 'green', "start with correct state"); - - fsm.lightup(); equal(fsm.current, 'yellow', "lightup event should switch green to yellow"); - fsm.lightup(); equal(fsm.current, 'yellow', "lightup event should have no effect effect in other state than green"); - -}); \ No newline at end of file diff --git a/test/test_async.js b/test/test_async.js deleted file mode 100644 index 17fc6a5..0000000 --- a/test/test_async.js +++ /dev/null @@ -1,408 +0,0 @@ -//----------------------------------------------------------------------------- - -QUnit.module("async"); - -//----------------------------------------------------------------------------- - -test("state transitions", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { return StateMachine.ASYNC; }, - onleaveyellow: function() { return StateMachine.ASYNC; }, - onleavered: function() { return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'red', "should still be red because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - -}); - -//----------------------------------------------------------------------------- - -test("state transitions with delays", function() { - - stop(); // doing async stuff - dont run next qunit test until I call start() below - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { return StateMachine.ASYNC; }, - onleaveyellow: function() { return StateMachine.ASYNC; }, - onleavered: function() { return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - setTimeout(function() { - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - setTimeout(function() { - fsm.transition(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'red', "should still be red because we haven't transitioned yet"); - setTimeout(function() { - fsm.transition(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - setTimeout(function() { - fsm.transition(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - start(); - }, 10); - }, 10); - }, 10); - }, 10); - -}); - -//----------------------------------------------------------------------------- - -test("state transition fired during onleavestate callback - immediate", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { this.transition(); return StateMachine.ASYNC; }, - onleaveyellow: function() { this.transition(); return StateMachine.ASYNC; }, - onleavered: function() { this.transition(); return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - -}); - -//----------------------------------------------------------------------------- - -test("state transition fired during onleavestate callback - with delay", function() { - - stop(); // doing async stuff - dont run next qunit test until I call start() below - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'panic', from: 'green', to: 'red' } - ], - callbacks: { - onleavegreen: function() { setTimeout(function() { fsm.transition(); }, 10); return StateMachine.ASYNC; }, - onenterred: function() { - equal(fsm.current, 'red', "panic event should transition from green to red"); - start(); - } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - fsm.panic(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - -}); - -//----------------------------------------------------------------------------- - -test("state transition fired during onleavestate callback - but forgot to return ASYNC!", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { this.transition(); /* return StateMachine.ASYNC; */ }, - onleaveyellow: function() { this.transition(); /* return StateMachine.ASYNC; */ }, - onleavered: function() { this.transition(); /* return StateMachine.ASYNC; */ } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - -}); - -//----------------------------------------------------------------------------- - -test("state transitions sometimes synchronous and sometimes asynchronous", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ] - }); - - // default behavior is synchronous - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - - // but add callbacks that return ASYNC and it magically becomes asynchronous - - fsm.onleavegreen = function() { return StateMachine.ASYNC; } - fsm.onleaveyellow = function() { return StateMachine.ASYNC; } - fsm.onleavered = function() { return StateMachine.ASYNC; } - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'red', "should still be red because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - - // this allows you to make on-the-fly decisions about whether async or not ... - - fsm.onleavegreen = function(event, from, to, async) { - if (async) { - setTimeout(function() { - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - start(); // move on to next test - }, 10); - return StateMachine.ASYNC; - } - } - fsm.onleaveyellow = fsm.onleavered = null; - - fsm.warn(false); equal(fsm.current, 'yellow', "expected synchronous transition from green to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - fsm.warn(true); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - - stop(); // doing async stuff - dont run next qunit test until I call start() in callback above - -}); - -//----------------------------------------------------------------------------- - - -test("state transition fired without completing previous transition", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { return StateMachine.ASYNC; }, - onleaveyellow: function() { return StateMachine.ASYNC; }, - onleavered: function() { return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - - throws(fsm.calm.bind(fsm), /event calm inappropriate because previous transition did not complete/); - -}); - -//----------------------------------------------------------------------------- - -test("state transition can be cancelled (github issue #22)", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { return StateMachine.ASYNC; }, - onleaveyellow: function() { return StateMachine.ASYNC; }, - onleavered: function() { return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - fsm.warn(); equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - fsm.transition(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - equal(fsm.can('panic'), false, "but cannot panic a 2nd time because a transition is still pending") - - throws(fsm.panic.bind(fsm), /event panic inappropriate because previous transition did not complete/); - - fsm.transition.cancel(); - - equal(fsm.current, 'yellow', "should still be yellow because we cancelled the async transition"); - equal(fsm.can('panic'), true, "can now panic again because we cancelled previous async transition"); - - fsm.panic(); - fsm.transition(); - - equal(fsm.current, 'red', "should finally be red now that we completed the async transition"); - -}); - -//----------------------------------------------------------------------------- - -test("callbacks are ordered correctly", function() { - - var called = []; - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' }, - ], - callbacks: { - - // generic callbacks - onbeforeevent: function(event,from,to) { called.push('onbefore(' + event + ')'); }, - onafterevent: function(event,from,to) { called.push('onafter(' + event + ')'); }, - onleavestate: function(event,from,to) { called.push('onleave(' + from + ')'); }, - onenterstate: function(event,from,to) { called.push('onenter(' + to + ')'); }, - onchangestate: function(event,from,to) { called.push('onchange(' + from + ',' + to + ')'); }, - - // specific state callbacks - onentergreen: function() { called.push('onentergreen'); }, - onenteryellow: function() { called.push('onenteryellow'); }, - onenterred: function() { called.push('onenterred'); }, - onleavegreen: function() { called.push('onleavegreen'); return StateMachine.ASYNC; }, - onleaveyellow: function() { called.push('onleaveyellow'); return StateMachine.ASYNC; }, - onleavered: function() { called.push('onleavered'); return StateMachine.ASYNC; }, - - // specific event callbacks - onbeforewarn: function() { called.push('onbeforewarn'); }, - onbeforepanic: function() { called.push('onbeforepanic'); }, - onbeforecalm: function() { called.push('onbeforecalm'); }, - onbeforeclear: function() { called.push('onbeforeclear'); }, - onafterwarn: function() { called.push('onafterwarn'); }, - onafterpanic: function() { called.push('onafterpanic'); }, - onaftercalm: function() { called.push('onaftercalm'); }, - onafterclear: function() { called.push('onafterclear'); } - } - }); - - called = []; - fsm.warn(); deepEqual(called, ['onbeforewarn', 'onbefore(warn)', 'onleavegreen', 'onleave(green)']); - fsm.transition(); deepEqual(called, ['onbeforewarn', 'onbefore(warn)', 'onleavegreen', 'onleave(green)', 'onenteryellow', 'onenter(yellow)', 'onchange(green,yellow)', 'onafterwarn', 'onafter(warn)']); - - called = []; - fsm.panic(); deepEqual(called, ['onbeforepanic', 'onbefore(panic)', 'onleaveyellow', 'onleave(yellow)']); - fsm.transition(); deepEqual(called, ['onbeforepanic', 'onbefore(panic)', 'onleaveyellow', 'onleave(yellow)', 'onenterred', 'onenter(red)', 'onchange(yellow,red)', 'onafterpanic', 'onafter(panic)']); - - called = []; - fsm.calm(); deepEqual(called, ['onbeforecalm', 'onbefore(calm)', 'onleavered', 'onleave(red)']); - fsm.transition(); deepEqual(called, ['onbeforecalm', 'onbefore(calm)', 'onleavered', 'onleave(red)', 'onenteryellow', 'onenter(yellow)', 'onchange(red,yellow)', 'onaftercalm', 'onafter(calm)']); - - called = []; - fsm.clear(); deepEqual(called, ['onbeforeclear', 'onbefore(clear)', 'onleaveyellow', 'onleave(yellow)']); - fsm.transition(); deepEqual(called, ['onbeforeclear', 'onbefore(clear)', 'onleaveyellow', 'onleave(yellow)', 'onentergreen', 'onenter(green)', 'onchange(yellow,green)', 'onafterclear', 'onafter(clear)']); - -}); - -//----------------------------------------------------------------------------- - -test("cannot fire event during existing transition", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - onleavegreen: function() { return StateMachine.ASYNC; }, - onleaveyellow: function() { return StateMachine.ASYNC; }, - onleavered: function() { return StateMachine.ASYNC; } - } - }); - - equal(fsm.current, 'green', "initial state should be green"); - equal(fsm.can('warn'), true, "should be able to warn"); - equal(fsm.can('panic'), false, "should NOT be able to panic"); - equal(fsm.can('calm'), false, "should NOT be able to calm"); - equal(fsm.can('clear'), false, "should NOT be able to clear"); - - fsm.warn(); - - equal(fsm.current, 'green', "should still be green because we haven't transitioned yet"); - equal(fsm.can('warn'), false, "should NOT be able to warn - during transition"); - equal(fsm.can('panic'), false, "should NOT be able to panic - during transition"); - equal(fsm.can('calm'), false, "should NOT be able to calm - during transition"); - equal(fsm.can('clear'), false, "should NOT be able to clear - during transition"); - - fsm.transition(); - - equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - equal(fsm.can('warn'), false, "should NOT be able to warn"); - equal(fsm.can('panic'), true, "should be able to panic"); - equal(fsm.can('calm'), false, "should NOT be able to calm"); - equal(fsm.can('clear'), true, "should be able to clear"); - - fsm.panic(); - - equal(fsm.current, 'yellow', "should still be yellow because we haven't transitioned yet"); - equal(fsm.can('warn'), false, "should NOT be able to warn - during transition"); - equal(fsm.can('panic'), false, "should NOT be able to panic - during transition"); - equal(fsm.can('calm'), false, "should NOT be able to calm - during transition"); - equal(fsm.can('clear'), false, "should NOT be able to clear - during transition"); - - fsm.transition(); - - equal(fsm.current, 'red', "panic event should transition from yellow to red"); - equal(fsm.can('warn'), false, "should NOT be able to warn"); - equal(fsm.can('panic'), false, "should NOT be able to panic"); - equal(fsm.can('calm'), true, "should be able to calm"); - equal(fsm.can('clear'), false, "should NOT be able to clear"); - -}); - -//----------------------------------------------------------------------------- - - diff --git a/test/test_basics.js b/test/test_basics.js deleted file mode 100644 index 209479c..0000000 --- a/test/test_basics.js +++ /dev/null @@ -1,733 +0,0 @@ -//----------------------------------------------------------------------------- - -QUnit.module("basic"); - -//----------------------------------------------------------------------------- - -test("standalone state machine", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - fsm.panic(); equal(fsm.current, 'red', "panic event should transition from yellow to red"); - fsm.calm(); equal(fsm.current, 'yellow', "calm event should transition from red to yellow"); - fsm.clear(); equal(fsm.current, 'green', "clear event should transition from yellow to green"); - -}); - -//----------------------------------------------------------------------------- - -test("targeted state machine", function() { - - StateMachine.create({ - target: this, - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); - - equal(this.current, 'green', "initial state should be green"); - - this.warn(); equal(this.current, 'yellow', "warn event should transition from green to yellow"); - this.panic(); equal(this.current, 'red', "panic event should transition from yellow to red"); - this.calm(); equal(this.current, 'yellow', "calm event should transition from red to yellow"); - this.clear(); equal(this.current, 'green', "clear event should transition from yellow to green"); -}); - -//----------------------------------------------------------------------------- - -test("can & cannot", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - ok(fsm.can('warn'), "should be able to warn from green state") - ok(fsm.cannot('panic'), "should NOT be able to panic from green state") - ok(fsm.cannot('calm'), "should NOT be able to calm from green state") - - fsm.warn(); - equal(fsm.current, 'yellow', "current state should be yellow"); - ok(fsm.cannot('warn'), "should NOT be able to warn from yellow state") - ok(fsm.can('panic'), "should be able to panic from yellow state") - ok(fsm.cannot('calm'), "should NOT be able to calm from yellow state") - - fsm.panic(); - equal(fsm.current, 'red', "current state should be red"); - ok(fsm.cannot('warn'), "should NOT be able to warn from red state") - ok(fsm.cannot('panic'), "should NOT be able to panic from red state") - ok(fsm.can('calm'), "should be able to calm from red state") - - equal(fsm.can('jibber'), false, "unknown event should not crash") - equal(fsm.cannot('jabber'), true, "unknown event should not crash") - -}); - -//----------------------------------------------------------------------------- - -test("is", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - equal(fsm.is('green'), true, 'current state should match'); - equal(fsm.is('yellow'), false, 'current state should NOT match'); - equal(fsm.is(['green', 'red']), true, 'current state should match when included in array'); - equal(fsm.is(['yellow', 'red']), false, 'current state should NOT match when not included in array'); - - fsm.warn(); - - equal(fsm.current, 'yellow', "current state should be yellow"); - - equal(fsm.is('green'), false, 'current state should NOT match'); - equal(fsm.is('yellow'), true, 'current state should match'); - equal(fsm.is(['green', 'red']), false, 'current state should NOT match when not included in array'); - equal(fsm.is(['yellow', 'red']), true, 'current state should match when included in array'); - -}); - -//----------------------------------------------------------------------------- - -test("states", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' }, - { name: 'finish', from: 'green', to: 'done' }, - ]}); - - deepEqual(fsm.states(), [ 'done', 'green', 'none', 'red', 'yellow' ]); - -}); - -//----------------------------------------------------------------------------- - -test("transitions", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' }, - { name: 'finish', from: 'green', to: 'done' }, - ]}); - - equal(fsm.current, 'green', 'current state should be yellow'); - deepEqual(fsm.transitions(), ['warn', 'finish'], 'current transition(s) should be yellow'); - - fsm.warn(); - equal(fsm.current, 'yellow', 'current state should be yellow'); - deepEqual(fsm.transitions(), ['panic', 'clear'], 'current transition(s) should be panic and clear'); - - fsm.panic(); - equal(fsm.current, 'red', 'current state should be red'); - deepEqual(fsm.transitions(), ['calm'], 'current transition(s) should be calm'); - - fsm.calm(); - equal(fsm.current, 'yellow', 'current state should be yellow'); - deepEqual(fsm.transitions(), ['panic', 'clear'], 'current transion(s) should be panic and clear'); - - fsm.clear(); - equal(fsm.current, 'green', 'current state should be green'); - deepEqual(fsm.transitions(), ['warn', 'finish'], 'current transion(s) should be warn'); - - fsm.finish(); - equal(fsm.current, 'done', 'current state should be done'); - deepEqual(fsm.transitions(), [], 'current transition(s) should be empty'); - -}); - -//----------------------------------------------------------------------------- - -test("transitions with multiple from states", function() { - - var fsm = StateMachine.create({ - events: [ - { name: 'start', from: 'none', to: 'green' }, - { name: 'warn', from: ['green', 'red'], to: 'yellow' }, - { name: 'panic', from: ['green', 'yellow'], to: 'red' }, - { name: 'clear', from: ['red', 'yellow'], to: 'green' } - ] - }); - - equal(fsm.current, 'none', 'current state should be none'); - deepEqual(fsm.transitions(), ['start'], 'current transition(s) should be start'); - - fsm.start(); - equal(fsm.current, 'green', 'current state should be green'); - deepEqual(fsm.transitions(), ['warn', 'panic'], 'current transition(s) should be warn and panic'); - - fsm.warn(); - equal(fsm.current, 'yellow', 'current state should be yellow'); - deepEqual(fsm.transitions(), ['panic', 'clear'], 'current transition(s) should be panic and clear'); - - fsm.panic(); - equal(fsm.current, 'red', 'current state should be red'); - deepEqual(fsm.transitions(), ['warn', 'clear'], 'current transition(s) should be warn and clear'); - - fsm.clear(); - equal(fsm.current, 'green', 'current state should be green'); - deepEqual(fsm.transitions(), ['warn', 'panic'], 'current transition(s) should be warn and panic'); - -}); - -//----------------------------------------------------------------------------- - -test("isFinished", function() { - - var fsm = StateMachine.create({ - initial: 'green', terminal: 'red', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' } - ]}); - - equal(fsm.current, 'green'); - equal(fsm.isFinished(), false); - - fsm.warn(); - equal(fsm.current, 'yellow'); - equal(fsm.isFinished(), false); - - fsm.panic(); - equal(fsm.current, 'red'); - equal(fsm.isFinished(), true); - -}); - -//----------------------------------------------------------------------------- - -test("isFinished - without specifying terminal state", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' } - ]}); - - equal(fsm.current, 'green'); - equal(fsm.isFinished(), false); - - fsm.warn(); - equal(fsm.current, 'yellow'); - equal(fsm.isFinished(), false); - - fsm.panic(); - equal(fsm.current, 'red'); - equal(fsm.isFinished(), false); - -}); -//----------------------------------------------------------------------------- - -test("inappropriate events", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - throws(fsm.panic.bind(fsm), /event panic inappropriate in current state green/); - throws(fsm.calm.bind(fsm), /event calm inappropriate in current state green/); - - fsm.warn(); - equal(fsm.current, 'yellow', "current state should be yellow"); - throws(fsm.warn.bind(fsm), /event warn inappropriate in current state yellow/); - throws(fsm.calm.bind(fsm), /event calm inappropriate in current state yellow/); - - fsm.panic(); - equal(fsm.current, 'red', "current state should be red"); - throws(fsm.warn.bind(fsm), /event warn inappropriate in current state red/); - throws(fsm.panic.bind(fsm), /event panic inappropriate in current state red/); - -}); - -//----------------------------------------------------------------------------- - -test("inappropriate event handling can be customized", function() { - - var fsm = StateMachine.create({ - error: function(name, from, to, args, error, msg) { return msg; }, // return error message instead of throwing an exception - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' } - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - equal(fsm.panic(), 'event panic inappropriate in current state green'); - equal(fsm.calm(), 'event calm inappropriate in current state green'); - - fsm.warn(); - equal(fsm.current, 'yellow', "current state should be yellow"); - equal(fsm.warn(), 'event warn inappropriate in current state yellow'); - equal(fsm.calm(), 'event calm inappropriate in current state yellow'); - - fsm.panic(); - equal(fsm.current, 'red', "current state should be red"); - equal(fsm.warn(), 'event warn inappropriate in current state red'); - equal(fsm.panic(), 'event panic inappropriate in current state red'); - -}); - -//----------------------------------------------------------------------------- - -test("event is cancelable", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' } - ]}); - - equal(fsm.current, 'green', 'initial state should be green'); - - fsm.onbeforewarn = function() { return false; } - fsm.warn(); - - equal(fsm.current, 'green', 'state should STAY green when event is cancelled'); - -}); - -//----------------------------------------------------------------------------- - -test("callbacks are ordered correctly", function() { - - var called = []; - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - - // generic callbacks - onbeforeevent: function(event,frmo,to) { called.push('onbefore(' + event + ')'); }, - onafterevent: function(event,frmo,to) { called.push('onafter(' + event + ')'); }, - onleavestate: function(event,from,to) { called.push('onleave(' + from + ')'); }, - onenterstate: function(event,from,to) { called.push('onenter(' + to + ')'); }, - onchangestate: function(event,from,to) { called.push('onchange(' + from + ',' + to + ')'); }, - - // specific state callbacks - onentergreen: function() { called.push('onentergreen'); }, - onenteryellow: function() { called.push('onenteryellow'); }, - onenterred: function() { called.push('onenterred'); }, - onleavegreen: function() { called.push('onleavegreen'); }, - onleaveyellow: function() { called.push('onleaveyellow'); }, - onleavered: function() { called.push('onleavered'); }, - - // specific event callbacks - onbeforewarn: function() { called.push('onbeforewarn'); }, - onbeforepanic: function() { called.push('onbeforepanic'); }, - onbeforecalm: function() { called.push('onbeforecalm'); }, - onbeforeclear: function() { called.push('onbeforeclear'); }, - onafterwarn: function() { called.push('onafterwarn'); }, - onafterpanic: function() { called.push('onafterpanic'); }, - onaftercalm: function() { called.push('onaftercalm'); }, - onafterclear: function() { called.push('onafterclear'); }, - - } - }); - - called = []; - fsm.warn(); - deepEqual(called, [ - 'onbeforewarn', - 'onbefore(warn)', - 'onleavegreen', - 'onleave(green)', - 'onenteryellow', - 'onenter(yellow)', - 'onchange(green,yellow)', - 'onafterwarn', - 'onafter(warn)' - ]); - - called = []; - fsm.panic(); - deepEqual(called, [ - 'onbeforepanic', - 'onbefore(panic)', - 'onleaveyellow', - 'onleave(yellow)', - 'onenterred', - 'onenter(red)', - 'onchange(yellow,red)', - 'onafterpanic', - 'onafter(panic)' - ]); - - called = []; - fsm.calm(); - deepEqual(called, [ - 'onbeforecalm', - 'onbefore(calm)', - 'onleavered', - 'onleave(red)', - 'onenteryellow', - 'onenter(yellow)', - 'onchange(red,yellow)', - 'onaftercalm', - 'onafter(calm)' - ]); - - called = []; - fsm.clear(); - deepEqual(called, [ - 'onbeforeclear', - 'onbefore(clear)', - 'onleaveyellow', - 'onleave(yellow)', - 'onentergreen', - 'onenter(green)', - 'onchange(yellow,green)', - 'onafterclear', - 'onafter(clear)' - ]); - -}); - -//----------------------------------------------------------------------------- - -test("callbacks are ordered correctly - for same state transition", function() { - - var called = []; - - var fsm = StateMachine.create({ - initial: 'waiting', - events: [ - { name: 'data', from: ['waiting', 'receipt'], to: 'receipt' }, - { name: 'nothing', from: ['waiting', 'receipt'], to: 'waiting' }, - { name: 'error', from: ['waiting', 'receipt'], to: 'error' } // bad practice to have event name same as state name - but I'll let it slide just this once - ], - callbacks: { - - // generic callbacks - onbeforeevent: function(event,frmo,to) { called.push('onbefore(' + event + ')'); }, - onafterevent: function(event,frmo,to) { called.push('onafter(' + event + ')'); }, - onleavestate: function(event,from,to) { called.push('onleave(' + from + ')'); }, - onenterstate: function(event,from,to) { called.push('onenter(' + to + ')'); }, - onchangestate: function(event,from,to) { called.push('onchange(' + from + ',' + to + ')'); }, - - // specific state callbacks - onenterwaiting: function() { called.push('onenterwaiting'); }, - onenterreceipt: function() { called.push('onenterreceipt'); }, - onentererror: function() { called.push('onentererror'); }, - onleavewaiting: function() { called.push('onleavewaiting'); }, - onleavereceipt: function() { called.push('onleavereceipt'); }, - onleaveerror: function() { called.push('onleaveerror'); }, - - // specific event callbacks - onbeforedata: function() { called.push('onbeforedata'); }, - onbeforenothing: function() { called.push('onbeforenothing'); }, - onbeforeerror: function() { called.push('onbeforeerror'); }, - onafterdata: function() { called.push('onafterdata'); }, - onafternothing: function() { called.push('onafternothing'); }, - onaftereerror: function() { called.push('onaftererror'); }, - } - }); - - called = []; - fsm.data(); - deepEqual(called, [ - 'onbeforedata', - 'onbefore(data)', - 'onleavewaiting', - 'onleave(waiting)', - 'onenterreceipt', - 'onenter(receipt)', - 'onchange(waiting,receipt)', - 'onafterdata', - 'onafter(data)' - ]); - - called = []; - fsm.data(); // same-state transition - deepEqual(called, [ // so NO enter/leave/change state callbacks are fired - 'onbeforedata', - 'onbefore(data)', - 'onafterdata', - 'onafter(data)' - ]); - - called = []; - fsm.data(); // same-state transition - deepEqual(called, [ // so NO enter/leave/change state callbacks are fired - 'onbeforedata', - 'onbefore(data)', - 'onafterdata', - 'onafter(data)' - ]); - - called = []; - fsm.nothing(); - deepEqual(called, [ - 'onbeforenothing', - 'onbefore(nothing)', - 'onleavereceipt', - 'onleave(receipt)', - 'onenterwaiting', - 'onenter(waiting)', - 'onchange(receipt,waiting)', - 'onafternothing', - 'onafter(nothing)' - ]); - -}); - -//----------------------------------------------------------------------------- - -test("callback arguments are correct", function() { - - var expected = { event: 'startup', from: 'none', to: 'green' }; // first expected callback - - var verify_expected = function(event,from,to,a,b,c) { - equal(event, expected.event) - equal(from, expected.from) - equal(to, expected.to) - equal(a, expected.a) - equal(b, expected.b) - equal(c, expected.c) - }; - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ], - callbacks: { - - // generic callbacks - onbeforeevent: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onafterevent: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onleavestate: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onenterstate: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onchangestate: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - - // specific state callbacks - onentergreen: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onenteryellow: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onenterred: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onleavegreen: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onleaveyellow: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onleavered: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - - // specific event callbacks - onbeforewarn: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onbeforepanic: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onbeforecalm: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onbeforeclear: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onafterwarn: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onafterpanic: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onaftercalm: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); }, - onafterclear: function(event,from,to,a,b,c) { verify_expected(event,from,to,a,b,c); } - } - }); - - expected = { event: 'warn', from: 'green', to: 'yellow', a: 1, b: 2, c: 3 }; - fsm.warn(1,2,3); - - expected = { event: 'panic', from: 'yellow', to: 'red', a: 4, b: 5, c: 6 }; - fsm.panic(4,5,6); - - expected = { event: 'calm', from: 'red', to: 'yellow', a: 'foo', b: 'bar', c: null }; - fsm.calm('foo', 'bar'); - - expected = { event: 'clear', from: 'yellow', to: 'green', a: null, b: null, c: null }; - fsm.clear(); - -}); - -//----------------------------------------------------------------------------- - -test("exceptions in caller-provided callbacks are not swallowed (github issue #17)", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' } - ], - callbacks: { - onenteryellow: function() { throw 'oops'; } - }}); - - equal(fsm.current, 'green', "initial state should be green"); - - throws(fsm.warn.bind(fsm), /oops/); -}); - -//----------------------------------------------------------------------------- - -test("no-op transitions (github issue #5)", function() { - - var fsm = StateMachine.create({ - initial: 'green', - events: [ - { name: 'noop', from: 'green', /* no-op */ }, - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'calm', from: 'red', to: 'yellow' }, - { name: 'clear', from: 'yellow', to: 'green' } - ]}); - - equal(fsm.current, 'green', "initial state should be green"); - - ok(fsm.can('noop'), "should be able to noop from green state") - ok(fsm.can('warn'), "should be able to warn from green state") - - fsm.noop(); equal(fsm.current, 'green', "noop event should not cause a transition (there is no 'to' specified)"); - fsm.warn(); equal(fsm.current, 'yellow', "warn event should transition from green to yellow"); - - ok(fsm.cannot('noop'), "should NOT be able to noop from yellow state") - ok(fsm.cannot('warn'), "should NOT be able to warn from yellow state") - -}); - -//----------------------------------------------------------------------------- - -test("wildcard 'from' allows event from any state (github issue #11)", function() { - - var fsm = StateMachine.create({ - initial: 'stopped', - events: [ - { name: 'prepare', from: 'stopped', to: 'ready' }, - { name: 'start', from: 'ready', to: 'running' }, - { name: 'resume', from: 'paused', to: 'running' }, - { name: 'pause', from: 'running', to: 'paused' }, - { name: 'stop', from: '*', to: 'stopped' } - ]}); - - equal(fsm.current, 'stopped', "initial state should be stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from ready to stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.start(); equal(fsm.current, 'running', "start event should transition from ready to running"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from running to stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.start(); equal(fsm.current, 'running', "start event should transition from ready to running"); - fsm.pause(); equal(fsm.current, 'paused', "pause event should transition from running to paused"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from paused to stopped"); - - deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard event (stop) is included in available transitions") - fsm.prepare(); deepEqual(fsm.transitions(), ["start", "stop"], "ensure wildcard event (stop) is included in available transitions") - fsm.start(); deepEqual(fsm.transitions(), ["pause", "stop"], "ensure wildcard event (stop) is included in available transitions") - fsm.stop(); deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard event (stop) is included in available transitions") - -}); - -//----------------------------------------------------------------------------- - -test("missing 'from' allows event from any state (github issue #11) ", function() { - - var fsm = StateMachine.create({ - initial: 'stopped', - events: [ - { name: 'prepare', from: 'stopped', to: 'ready' }, - { name: 'start', from: 'ready', to: 'running' }, - { name: 'resume', from: 'paused', to: 'running' }, - { name: 'pause', from: 'running', to: 'paused' }, - { name: 'stop', /* any from state */ to: 'stopped' } - ]}); - - equal(fsm.current, 'stopped', "initial state should be stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from ready to stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.start(); equal(fsm.current, 'running', "start event should transition from ready to running"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from running to stopped"); - - fsm.prepare(); equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - fsm.start(); equal(fsm.current, 'running', "start event should transition from ready to running"); - fsm.pause(); equal(fsm.current, 'paused', "pause event should transition from running to paused"); - fsm.stop(); equal(fsm.current, 'stopped', "stop event should transition from paused to stopped"); - -}); - -//----------------------------------------------------------------------------- - -test("event return values (github issue #12) ", function() { - - var fsm = StateMachine.create({ - initial: 'stopped', - events: [ - { name: 'prepare', from: 'stopped', to: 'ready' }, - { name: 'fake', from: 'ready', to: 'running' }, - { name: 'start', from: 'ready', to: 'running' } - ], - callbacks: { - onbeforefake: function(event,from,to,a,b,c) { return false; }, // this event will be cancelled - onleaveready: function(event,from,to,a,b,c) { return StateMachine.ASYNC; } // this state transition is ASYNC - } - }); - - equal(fsm.current, 'stopped', "initial state should be stopped"); - - equal(fsm.prepare(), StateMachine.Result.SUCCEEDED, "expected event to have SUCCEEDED"); - equal(fsm.current, 'ready', "prepare event should transition from stopped to ready"); - - equal(fsm.fake(), StateMachine.Result.CANCELLED, "expected event to have been CANCELLED"); - equal(fsm.current, 'ready', "cancelled event should not cause a transition"); - - equal(fsm.start(), StateMachine.Result.PENDING, "expected event to cause a PENDING asynchronous transition"); - equal(fsm.current, 'ready', "async transition hasn't happened yet"); - - equal(fsm.transition(), StateMachine.Result.SUCCEEDED, "expected async transition to have SUCCEEDED"); - equal(fsm.current, 'running', "async transition should now be complete"); - -}); - diff --git a/test/test_classes.js b/test/test_classes.js deleted file mode 100644 index 4c6dc2b..0000000 --- a/test/test_classes.js +++ /dev/null @@ -1,92 +0,0 @@ -//----------------------------------------------------------------------------- - -QUnit.module("classes"); - -//----------------------------------------------------------------------------- - -test("prototype based state machine", function() { - - var myFSM = function() { - this.counter = 42; - this.startup(); - }; - - myFSM.prototype = { - onwarn: function() { this.counter++; } - } - - StateMachine.create({ - target: myFSM.prototype, - events: [ - { name: 'startup', from: 'none', to: 'green' }, - { name: 'warn', from: 'green', to: 'yellow' }, - { name: 'panic', from: 'yellow', to: 'red' }, - { name: 'clear', from: 'yellow', to: 'green' } - ] - }); - - var a = new myFSM(); - var b = new myFSM(); - - equal(a.current, 'green', 'start with correct state'); - equal(b.current, 'green', 'start with correct state'); - - equal(a.counter, 42, 'start with correct counter'); - equal(b.counter, 42, 'start with correct counter'); - - a.warn(); - - equal(a.current, 'yellow', 'maintain independent current state'); - equal(b.current, 'green', 'maintain independent current state'); - - equal(a.counter, 43, 'counter for (a) should have incremented'); - equal(b.counter, 42, 'counter for (b) should remain untouched'); - - ok(a.hasOwnProperty('current'), "each instance should have its own current state"); - ok(b.hasOwnProperty('current'), "each instance should have its own current state"); - ok(!a.hasOwnProperty('warn'), "each instance should NOT have its own event methods"); - ok(!b.hasOwnProperty('warn'), "each instance should NOT have its own event methods"); - ok(a.warn === b.warn, "each instance should share event methods"); - ok(a.warn === a.__proto__.warn, "each instance event methods come from its shared prototype"); - ok(b.warn === b.__proto__.warn, "each instance event methods come from its shared prototype"); - -}); - -//----------------------------------------------------------------------------- - -test("github issue 19", function() { - - var Foo = function() { - this.counter = 7; - this.initFSM(); - }; - - Foo.prototype.onenterready = function() { this.counter++; }; - Foo.prototype.onenterrunning = function() { this.counter++; }; - - StateMachine.create({ - target : Foo.prototype, - initial: { state: 'ready', event: 'initFSM', defer: true }, // unfortunately, trying to apply an IMMEDIATE initial state wont work on prototype based FSM, it MUST be deferred and called in the constructor for each instance - events : [{name: 'execute', from: 'ready', to: 'running'}, - {name: 'abort', from: 'running', to: 'ready'}] - }); - - var foo = new Foo(); - var bar = new Foo(); - - equal(foo.current, 'ready', 'start with correct state'); - equal(bar.current, 'ready', 'start with correct state'); - - equal(foo.counter, 8, 'start with correct counter 7 (from constructor) + 1 (from onenterready)'); - equal(bar.counter, 8, 'start with correct counter 7 (from constructor) + 1 (from onenterready)'); - - foo.execute(); // transition foo, but NOT bar - - equal(foo.current, 'running', 'changed state'); - equal(bar.current, 'ready', 'state remains the same'); - - equal(foo.counter, 9, 'incremented counter during onenterrunning'); - equal(bar.counter, 8, 'counter remains the same'); - -}); - diff --git a/test/test_initialize.js b/test/test_initialize.js deleted file mode 100644 index ae2e2a0..0000000 --- a/test/test_initialize.js +++ /dev/null @@ -1,122 +0,0 @@ -//----------------------------------------------------------------------------- - -QUnit.module("special initialization options", { - - setup: function() { - this.called = []; - this.onbeforeevent = function(event,from,to) { this.called.push('onbefore(' + event + ')'); }, - this.onafterevent = function(event,from,to) { this.called.push('onafter(' + event + ')'); }, - this.onleavestate = function(event,from,to) { this.called.push('onleave(' + from + ')'); }, - this.onenterstate = function(event,from,to) { this.called.push('onenter(' + to + ')'); }, - this.onchangestate = function(event,from,to) { this.called.push('onchange(' + from + ',' + to + ')'); }; - this.onbeforeinit = function() { this.called.push("onbeforeinit"); }; - this.onafterinit = function() { this.called.push("onafterinit"); }; - this.onbeforestartup = function() { this.called.push("onbeforestartup"); }; - this.onafterstartup = function() { this.called.push("onafterstartup"); }; - this.onbeforepanic = function() { this.called.push("onbeforepanic"); }; - this.onafterpanic = function() { this.called.push("onafterpanic"); }; - this.onbeforecalm = function() { this.called.push("onbeforecalm"); }; - this.onaftercalm = function() { this.called.push("onaftercalm"); }; - this.onenternone = function() { this.called.push("onenternone"); }; - this.onentergreen = function() { this.called.push("onentergreen"); }; - this.onenterred = function() { this.called.push("onenterred"); }; - this.onleavenone = function() { this.called.push("onleavenone"); }; - this.onleavegreen = function() { this.called.push("onleavegreen"); }; - this.onleavered = function() { this.called.push("onleavered"); }; - } - -}); - -//----------------------------------------------------------------------------- - -test("initial state defaults to 'none'", function() { - StateMachine.create({ - target: this, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' } - ]}); - equal(this.current, 'none'); - deepEqual(this.called, []); -}); - -//----------------------------------------------------------------------------- - -test("initial state can be specified", function() { - StateMachine.create({ - target: this, - initial: 'green', - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' } - ]}); - equal(this.current, 'green'); - deepEqual(this.called, [ - "onbeforestartup", - "onbefore(startup)", - "onleavenone", - "onleave(none)", - "onentergreen", - "onenter(green)", - "onchange(none,green)", - "onafterstartup", - "onafter(startup)" - ]); -}); - -//----------------------------------------------------------------------------- - -test("startup event name can be specified", function() { - StateMachine.create({ - target: this, - initial: { state: 'green', event: 'init' }, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' } - ]}); - equal(this.current, 'green'); - deepEqual(this.called, [ - "onbeforeinit", - "onbefore(init)", - "onleavenone", - "onleave(none)", - "onentergreen", - "onenter(green)", - "onchange(none,green)", - "onafterinit", - "onafter(init)" - ]); -}); - -//----------------------------------------------------------------------------- - -test("startup event can be deferred", function() { - StateMachine.create({ - target: this, - initial: { state: 'green', event: 'init', defer: true }, - events: [ - { name: 'panic', from: 'green', to: 'red' }, - { name: 'calm', from: 'red', to: 'green' } - ]}); - equal(this.current, 'none'); - deepEqual(this.called, []); - - this.init(); - - equal(this.current, 'green'); - deepEqual(this.called, [ - "onbeforeinit", - "onbefore(init)", - "onleavenone", - "onleave(none)", - "onentergreen", - "onenter(green)", - "onchange(none,green)", - "onafterinit", - "onafter(init)" - ]); -}); - -//----------------------------------------------------------------------------- - - diff --git a/test/transitions.js b/test/transitions.js new file mode 100644 index 0000000..9f37304 --- /dev/null +++ b/test/transitions.js @@ -0,0 +1,223 @@ +import test from 'ava' +import StateMachine from '../src/app' +import LifecycleLogger from './helpers/lifecycle_logger' + +//----------------------------------------------------------------------------- + +test('basic transition from state to state', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step1', from: 'A', to: 'B' }, + { name: 'step2', from: 'B', to: 'C' }, + { name: 'step3', from: 'C', to: 'D' } + ] + }); + + t.is(fsm.state, 'A') + + fsm.step1(); t.is(fsm.state, 'B') + fsm.step2(); t.is(fsm.state, 'C') + fsm.step3(); t.is(fsm.state, 'D') + +}) + +//----------------------------------------------------------------------------- + +test('multiple transitions with same name', t => { + + var fsm = new StateMachine({ + init: 'hungry', + transitions: [ + { name: 'eat', from: 'hungry', to: 'satisfied' }, + { name: 'eat', from: 'satisfied', to: 'full' }, + { name: 'eat', from: 'full', to: 'sick' }, + { name: 'rest', from: '*', to: 'hungry' } + ] + }); + + t.is(fsm.state, 'hungry') + t.is(fsm.can('eat'), true) + t.is(fsm.can('rest'), true) + + fsm.eat() + + t.is(fsm.state, 'satisfied') + t.is(fsm.can('eat'), true) + t.is(fsm.can('rest'), true) + + fsm.eat() + + t.is(fsm.state, 'full') + t.is(fsm.can('eat'), true) + t.is(fsm.can('rest'), true) + + fsm.eat() + + t.is(fsm.state, 'sick') + t.is(fsm.can('eat'), false) + t.is(fsm.can('rest'), true) + + fsm.rest() + + t.is(fsm.state, 'hungry') + t.is(fsm.can('eat'), true) + t.is(fsm.can('rest'), true) + +}) + +//----------------------------------------------------------------------------- + +test('transitions with multiple from states', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'start', from: 'none', to: 'green' }, + { name: 'warn', from: ['green', 'red'], to: 'yellow' }, + { name: 'panic', from: ['green', 'yellow'], to: 'red' }, + { name: 'clear', from: ['red', 'yellow'], to: 'green' } + ] + }); + + t.deepEqual(fsm.allStates(), [ 'none', 'green', 'yellow', 'red' ]) + t.deepEqual(fsm.allTransitions(), [ 'start', 'warn', 'panic', 'clear' ]) + + t.is(fsm.state, 'none') + t.is(fsm.can('start'), true) + t.is(fsm.can('warn'), false) + t.is(fsm.can('panic'), false) + t.is(fsm.can('clear'), false) + t.deepEqual(fsm.transitions(), ['start']) + + fsm.start() + t.is(fsm.state, 'green') + t.is(fsm.can('start'), false) + t.is(fsm.can('warn'), true) + t.is(fsm.can('panic'), true) + t.is(fsm.can('clear'), false) + t.deepEqual(fsm.transitions(), ['warn', 'panic']) + + fsm.warn() + t.is(fsm.state, 'yellow') + t.is(fsm.can('start'), false) + t.is(fsm.can('warn'), false) + t.is(fsm.can('panic'), true) + t.is(fsm.can('clear'), true) + t.deepEqual(fsm.transitions(), ['panic', 'clear']) + + fsm.panic() + t.is(fsm.state, 'red') + t.is(fsm.can('start'), false) + t.is(fsm.can('warn'), true) + t.is(fsm.can('panic'), false) + t.is(fsm.can('clear'), true) + t.deepEqual(fsm.transitions(), ['warn', 'clear']) + + fsm.clear() + t.is(fsm.state, 'green') + t.is(fsm.can('start'), false) + t.is(fsm.can('warn'), true) + t.is(fsm.can('panic'), true) + t.is(fsm.can('clear'), false) + t.deepEqual(fsm.transitions(), ['warn', 'panic']) + +}) + +//------------------------------------------------------------------------------------------------- + +test("transition methods with dash or underscore are camelized", t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'do-with-dash', from: 'A', to: 'B' }, + { name: 'do_with_underscore', from: 'B', to: 'C' }, + { name: 'doAlreadyCamelized', from: 'C', to: 'D' } + ] + }); + + t.is(fsm.state, 'A') + fsm.doWithDash(); t.is(fsm.state, 'B') + fsm.doWithUnderscore(); t.is(fsm.state, 'C') + fsm.doAlreadyCamelized(); t.is(fsm.state, 'D') + +}) + +//------------------------------------------------------------------------------------------------- + +test('conditional transitions', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: '*', to: function(n) { return this.skip(n) } }, + ], + methods: { + skip: function(amount) { + var code = this.state.charCodeAt(0); + return String.fromCharCode(code + (amount || 1)); + }, + onBeforeTransition: logger, + onBeforeInit: logger, + onBeforeStep: logger, + onLeaveState: logger, + onLeaveNone: logger, + onLeaveA: logger, + onLeaveB: logger, + onLeaveG: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onEnterA: logger, + onEnterB: logger, + onEnterG: logger, + onAfterTransition: logger, + onAfterInit: logger, + onAfterStep: logger + } + }); + + t.is(fsm.state, 'A') + + t.deepEqual(fsm.allStates(), [ 'none', 'A' ]); + + fsm.step(); t.is(fsm.state, 'B'); t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B' ]) + fsm.step(5); t.is(fsm.state, 'G'); t.deepEqual(fsm.allStates(), [ 'none', 'A', 'B', 'G' ]) + + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onBeforeInit', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveState', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onLeaveNone', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onTransition', transition: 'init', from: 'none', to: 'A', current: 'none' }, + { event: 'onEnterState', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onEnterA', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterTransition', transition: 'init', from: 'none', to: 'A', current: 'A' }, + { event: 'onAfterInit', transition: 'init', from: 'none', to: 'A', current: 'A' }, + + { event: 'onBeforeTransition', transition: 'step', from: 'A', to: 'B', current: 'A' }, + { event: 'onBeforeStep', transition: 'step', from: 'A', to: 'B', current: 'A' }, + { event: 'onLeaveState', transition: 'step', from: 'A', to: 'B', current: 'A' }, + { event: 'onLeaveA', transition: 'step', from: 'A', to: 'B', current: 'A' }, + { event: 'onTransition', transition: 'step', from: 'A', to: 'B', current: 'A' }, + { event: 'onEnterState', transition: 'step', from: 'A', to: 'B', current: 'B' }, + { event: 'onEnterB', transition: 'step', from: 'A', to: 'B', current: 'B' }, + { event: 'onAfterTransition', transition: 'step', from: 'A', to: 'B', current: 'B' }, + { event: 'onAfterStep', transition: 'step', from: 'A', to: 'B', current: 'B' }, + + { event: 'onBeforeTransition', transition: 'step', from: 'B', to: 'G', current: 'B', args: [ 5 ] }, + { event: 'onBeforeStep', transition: 'step', from: 'B', to: 'G', current: 'B', args: [ 5 ] }, + { event: 'onLeaveState', transition: 'step', from: 'B', to: 'G', current: 'B', args: [ 5 ] }, + { event: 'onLeaveB', transition: 'step', from: 'B', to: 'G', current: 'B', args: [ 5 ] }, + { event: 'onTransition', transition: 'step', from: 'B', to: 'G', current: 'B', args: [ 5 ] }, + { event: 'onEnterState', transition: 'step', from: 'B', to: 'G', current: 'G', args: [ 5 ] }, + { event: 'onEnterG', transition: 'step', from: 'B', to: 'G', current: 'G', args: [ 5 ] }, + { event: 'onAfterTransition', transition: 'step', from: 'B', to: 'G', current: 'G', args: [ 5 ] }, + { event: 'onAfterStep', transition: 'step', from: 'B', to: 'G', current: 'G', args: [ 5 ] }, + ]) + +}) + +//------------------------------------------------------------------------------------------------- diff --git a/test/util/camelize.js b/test/util/camelize.js new file mode 100644 index 0000000..9e3bb04 --- /dev/null +++ b/test/util/camelize.js @@ -0,0 +1,14 @@ +import test from 'ava'; +import camelize from '../../src/util/camelize'; + +test('camelize', t => { + t.is(camelize(""), ""); + t.is(camelize("word"), "word"); + t.is(camelize("Word"), "Word"); + t.is(camelize("WORD"), "WORD"); + t.is(camelize("word-with-dash"), "wordWithDash"); + t.is(camelize("word_with_underscore"), "wordWithUnderscore"); + t.is(camelize("word--with--double--dash"), "wordWithDoubleDash"); + t.is(camelize("word_WITH_mixed_CASE"), "wordWITHMixedCASE"); + t.is(camelize("alreadyCamelized"), "alreadyCamelized"); +}); diff --git a/test/util/mixin.js b/test/util/mixin.js new file mode 100644 index 0000000..0fb3561 --- /dev/null +++ b/test/util/mixin.js @@ -0,0 +1,65 @@ +import test from 'ava'; +import mixin from '../../src/util/mixin'; + +//------------------------------------------------------------------------------------------------- + +test('mixin', t => { + + var a = { first: 'Jake', key: 'a' }, + b = { last: 'Gordon', key: 'b' }; + + t.deepEqual(mixin({}, a), { first: 'Jake', key: 'a' }); + t.deepEqual(mixin({}, b), { last: 'Gordon', key: 'b' }); + t.deepEqual(mixin({}, a, b), { first: 'Jake', last: 'Gordon', key: 'b' }); + t.deepEqual(mixin({}, b, a), { first: 'Jake', last: 'Gordon', key: 'a' }); + +}); + +//------------------------------------------------------------------------------------------------- + +test('mixin only mixes in owned properties', t => { + + var MyClass = function(name) { this.name = name } + + MyClass.prototype = { + answer: 42 + } + + var a = new MyClass('a'), + b = new MyClass('b'); + + t.is(a.name, 'a'); + t.is(a.answer, 42); + t.is(b.name, 'b'); + t.is(b.answer, 42); + + t.is(a.hasOwnProperty('name'), true); + t.is(a.hasOwnProperty('answer'), false); + t.is(b.hasOwnProperty('name'), true); + t.is(b.hasOwnProperty('answer'), false); + + t.deepEqual(mixin({}, a), { name: 'a' }); + t.deepEqual(mixin({}, b), { name: 'b' }); + t.deepEqual(mixin({}, a, b), { name: 'b' }); + t.deepEqual(mixin({}, b, a), { name: 'a' }); + + b.answer = 99; + + t.is(a.name, 'a'); + t.is(a.answer, 42); + t.is(b.name, 'b'); + t.is(b.answer, 99); + + t.is(a.hasOwnProperty('name'), true); + t.is(a.hasOwnProperty('answer'), false); + t.is(b.hasOwnProperty('name'), true); + t.is(b.hasOwnProperty('answer'), true); + + t.deepEqual(mixin({}, a), { name: 'a' }); + t.deepEqual(mixin({}, b), { name: 'b', answer: 99 }); + t.deepEqual(mixin({}, a, b), { name: 'b', answer: 99 }); + t.deepEqual(mixin({}, b, a), { name: 'a', answer: 99 }); + +}); + +//------------------------------------------------------------------------------------------------- diff --git a/test/wildcards.js b/test/wildcards.js new file mode 100644 index 0000000..a97b2af --- /dev/null +++ b/test/wildcards.js @@ -0,0 +1,212 @@ +import test from 'ava' +import StateMachine from '../src/app' + +//----------------------------------------------------------------------------- + +test('wildcard :from allows transition from any state', t => { + + var fsm = new StateMachine({ + init: 'stopped', + transitions: [ + { name: 'prepare', from: 'stopped', to: 'ready' }, + { name: 'start', from: 'ready', to: 'running' }, + { name: 'resume', from: 'paused', to: 'running' }, + { name: 'pause', from: 'running', to: 'paused' }, + { name: 'stop', from: '*', to: 'stopped' } + ]}); + + t.is(fsm.state, 'stopped', "initial state should be stopped"); + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.stop(); t.is(fsm.state, 'stopped') + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.start(); t.is(fsm.state, 'running') + fsm.stop(); t.is(fsm.state, 'stopped') + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.start(); t.is(fsm.state, 'running') + fsm.pause(); t.is(fsm.state, 'paused') + fsm.stop(); t.is(fsm.state, 'stopped') + fsm.stop(); t.is(fsm.state, 'stopped') + + t.deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard transition (stop) is included in available transitions") + fsm.prepare(); t.deepEqual(fsm.transitions(), ["start", "stop"], "ensure wildcard transition (stop) is included in available transitions") + fsm.start(); t.deepEqual(fsm.transitions(), ["pause", "stop"], "ensure wildcard transition (stop) is included in available transitions") + fsm.stop(); t.deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure wildcard transition (stop) is included in available transitions") + +}) + +//----------------------------------------------------------------------------- + +test('missing :from allows transition from any state', t => { + + var fsm = new StateMachine({ + init: 'stopped', + transitions: [ + { name: 'prepare', from: 'stopped', to: 'ready' }, + { name: 'start', from: 'ready', to: 'running' }, + { name: 'resume', from: 'paused', to: 'running' }, + { name: 'pause', from: 'running', to: 'paused' }, + { name: 'stop', /* any from state */ to: 'stopped' } + ]}); + + t.is(fsm.state, 'stopped', "initial state should be stopped") + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.stop(); t.is(fsm.state, 'stopped') + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.start(); t.is(fsm.state, 'running') + fsm.stop(); t.is(fsm.state, 'stopped') + + fsm.prepare(); t.is(fsm.state, 'ready') + fsm.start(); t.is(fsm.state, 'running') + fsm.pause(); t.is(fsm.state, 'paused') + fsm.stop(); t.is(fsm.state, 'stopped') + + t.deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure missing :from transition (stop) is included in available transitions") + fsm.prepare(); t.deepEqual(fsm.transitions(), ["start", "stop"], "ensure missing :from transition (stop) is included in available transitions") + fsm.start(); t.deepEqual(fsm.transitions(), ["pause", "stop"], "ensure missing :from transition (stop) is included in available transitions") + fsm.stop(); t.deepEqual(fsm.transitions(), ["prepare", "stop"], "ensure missing :from transition (stop) is included in available transitions") + +}) + +//----------------------------------------------------------------------------- + +test('wildcard :from allows transition to a state that is never declared in any other :from transition ', t => { + + var fsm = new StateMachine({ + transitions: [ + { name: 'step', from: 'none', to: 'mystery' }, // NOTE: 'mystery' is only ever declared in :to, never :from + { name: 'other', from: '*', to: 'complete' } + ] + }); + + t.is(fsm.state, 'none') + t.is(fsm.can('step'), true) + t.is(fsm.can('other'), true) + + fsm.step() + + t.is(fsm.state, 'mystery') + t.is(fsm.can('step'), false) + t.is(fsm.can('other'), true) + +}) + +//----------------------------------------------------------------------------- + +test('wildcard :to allows no-op transitions', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'stayA', from: 'A', to: '*' }, + { name: 'stayB', from: 'B', to: '*' }, + { name: 'noop', from: '*', to: '*' }, + { name: 'step', from: 'A', to: 'B' } + ] + }); + + t.is(fsm.state, 'A') + t.is(fsm.can('noop'), true) + t.is(fsm.can('step'), true) + t.is(fsm.can('stayA'), true) + t.is(fsm.can('stayB'), false) + + fsm.stayA(); t.is(fsm.state, 'A') + fsm.noop(); t.is(fsm.state, 'A') + + fsm.step(); + + t.is(fsm.state, 'B') + t.is(fsm.can('noop'), true) + t.is(fsm.can('step'), false) + t.is(fsm.can('stayA'), false) + t.is(fsm.can('stayB'), true) + + fsm.stayB(); t.is(fsm.state, 'B') + fsm.noop(); t.is(fsm.state, 'B') + +}) + +//----------------------------------------------------------------------------- + +test('missing :to allows no-op transitions', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'stayA', from: 'A' /* no-op */ }, + { name: 'stayB', from: 'B' /* no-op */ }, + { name: 'noop', from: '*' /* no-op */ }, + { name: 'step', from: 'A', to: 'B' } + ] + }); + + t.is(fsm.state, 'A') + t.is(fsm.can('noop'), true) + t.is(fsm.can('step'), true) + t.is(fsm.can('stayA'), true) + t.is(fsm.can('stayB'), false) + + fsm.stayA(); t.is(fsm.state, 'A') + fsm.noop(); t.is(fsm.state, 'A') + + fsm.step(); + + t.is(fsm.state, 'B') + t.is(fsm.can('noop'), true) + t.is(fsm.can('step'), false) + t.is(fsm.can('stayA'), false) + t.is(fsm.can('stayB'), true) + + fsm.stayB(); t.is(fsm.state, 'B') + fsm.noop(); t.is(fsm.state, 'B') + +}) + +//----------------------------------------------------------------------------- + +test('no-op transitions with multiple from states', t => { + + var fsm = new StateMachine({ + init: 'A', + transitions: [ + { name: 'step', from: 'A', to: 'B' }, + { name: 'noop1', from: ['A', 'B'] /* no-op */ }, + { name: 'noop2', from: '*' /* no-op */ }, + { name: 'noop3', from: ['A', 'B'], to: '*' }, + { name: 'noop4', from: '*', to: '*' } + ] + }); + + t.is(fsm.state, 'A') + t.is(fsm.can('step'), true) + t.is(fsm.can('noop1'), true) + t.is(fsm.can('noop2'), true) + t.is(fsm.can('noop3'), true) + t.is(fsm.can('noop4'), true) + + fsm.noop1(); t.is(fsm.state, 'A') + fsm.noop2(); t.is(fsm.state, 'A') + fsm.noop3(); t.is(fsm.state, 'A') + fsm.noop4(); t.is(fsm.state, 'A') + + fsm.step(); + t.is(fsm.state, 'B') + t.is(fsm.can('step'), false) + t.is(fsm.can('noop1'), true) + t.is(fsm.can('noop2'), true) + t.is(fsm.can('noop3'), true) + t.is(fsm.can('noop4'), true) + + fsm.noop1(); t.is(fsm.state, 'B') + fsm.noop2(); t.is(fsm.state, 'B') + fsm.noop3(); t.is(fsm.state, 'B') + fsm.noop4(); t.is(fsm.state, 'B') + +}) + +//----------------------------------------------------------------------------- diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..497dba2 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,43 @@ +module.exports = function(env) { + + 'use strict' + + const webpack = require('webpack'), + glob = require('glob'), + path = require('path'), + pascalize = require('pascal-case'), + source = 'src', + output = 'lib', + config = []; + + config.push({ + name: 'state-machine', + library: 'StateMachine', + entry: 'app' + }) + + glob.sync("src/plugin/*.js").forEach(function(plugin) { + const name = path.basename(plugin, '.js'); + config.push({ + library: pascalize('state-machine-' + name), + entry: 'plugin/' + name, + name: name + }) + }); + + return config.map(function(cfg) { + return { + entry: cfg.entry, + resolve: { + modules: [ source ] + }, + output: { + filename: path.join(output, cfg.name + '.js'), + library: cfg.library, + libraryTarget: 'umd', + umdNamedDefine: true + } + } + }); + +} From 73c0ee4c28be8737c793f7c8f5396396b1b8e67f Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 7 Jan 2017 12:14:04 -0800 Subject: [PATCH 36/53] added npm & build badges to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index acdf35a..bd46ea3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Javascript State Machine +[![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) +[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) + A library for finite state machines. ![matter state machine](examples/matter.png) From d7470a73e23d2ab9a281f7feed42bbbed3ce20f8 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 7 Jan 2017 12:17:35 -0800 Subject: [PATCH 37/53] added 'use strict' to test/helpers/lifecycle_logger.js --- test/helpers/lifecycle_logger.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/helpers/lifecycle_logger.js b/test/helpers/lifecycle_logger.js index c74d229..8c47b3f 100644 --- a/test/helpers/lifecycle_logger.js +++ b/test/helpers/lifecycle_logger.js @@ -1,6 +1,8 @@ module.exports = function() { + 'use strict' + let entries = [], logger = function(lifecycle) { var entry = { From b10fcb1b3c9e36f7019f3355517802e23ac95a17 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 7 Jan 2017 12:20:20 -0800 Subject: [PATCH 38/53] ensure tests pass in node v4 --- test/helpers/lifecycle_logger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/lifecycle_logger.js b/test/helpers/lifecycle_logger.js index 8c47b3f..fc9eb34 100644 --- a/test/helpers/lifecycle_logger.js +++ b/test/helpers/lifecycle_logger.js @@ -3,7 +3,7 @@ module.exports = function() { 'use strict' - let entries = [], + var entries = [], logger = function(lifecycle) { var entry = { event: lifecycle.event, From 604952845071caa8ef68e6877f80ea180544c3c3 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Tue, 10 Jan 2017 09:49:35 -0800 Subject: [PATCH 39/53] added note to README to indicate this is for v3.0.0-rc.1 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index bd46ea3..493a709 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ # Javascript State Machine +
        +> **IMPORTANT**: This is documentation for pre-release version **3.0.0-rc.1** + +[![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=v3)](https://travis-ci.org/jakesgordon/javascript-state-machine) + + A library for finite state machines. From e60a8966ae0bf35d728040c31e3de73047ef3765 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Tue, 10 Jan 2017 09:52:39 -0800 Subject: [PATCH 40/53] install instructions should use explicit pre-release version (for now) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 493a709..20c3a9b 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ In a browser: Using npm: ```shell - npm install --save-dev javascript-state-machine + npm install --save-dev javascript-state-machine@3.0.0-rc.1 # note explicit pre-release version ``` In Node.js: From efb57ea1c1489860c79bb03533677a1406a3e954 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Tue, 10 Jan 2017 09:56:37 -0800 Subject: [PATCH 41/53] ensure using v3.0.0-rc.1 throughout --- RELEASE_NOTES.md | 4 ++-- dist/state-machine.js | 2 +- dist/state-machine.min.js | 2 +- lib/state-machine.js | 2 +- package.json | 2 +- src/app.js | 2 +- test/basics.js | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ca0b628..5d64d17 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,5 @@ -Version 3.0.0 (ETA - January 2017) ----------------------------------- +Version 3.0.0-rc.1 (January 10 2017) +------------------------------------ **IMPORTANT NOTE**: this version includes **breaking changes** that will require code updates. diff --git a/dist/state-machine.js b/dist/state-machine.js index 6ac51b3..ac1c3d6 100644 --- a/dist/state-machine.js +++ b/dist/state-machine.js @@ -623,7 +623,7 @@ function build(target, config) { //----------------------------------------------------------------------------------------------- -StateMachine.version = '3.0.0'; +StateMachine.version = '3.0.0-rc.1'; StateMachine.factory = factory; StateMachine.apply = apply; StateMachine.defaults = { diff --git a/dist/state-machine.min.js b/dist/state-machine.min.js index ddf671a..0120acd 100644 --- a/dist/state-machine.min.js +++ b/dist/state-machine.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachine",[],n):"object"==typeof exports?exports.StateMachine=n():t.StateMachine=n()}(this,function(){return function(t){function n(e){if(i[e])return i[e].exports;var s=i[e]={i:e,l:!1,exports:{}};return t[e].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var i={};return n.m=t,n.c=i,n.i=function(t){return t},n.d=function(t,i,e){n.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(i,"a",i),i},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=6)}([function(t,n,i){"use strict";t.exports=function(t,n){var i,e,s;for(i=1;i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i { - t.is(StateMachine.version, '3.0.0'); + t.is(StateMachine.version, '3.0.0-rc.1'); }); //------------------------------------------------------------------------------------------------- From c0333e624a81ad8c43248009648fb31d9ddfd7c8 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Tue, 10 Jan 2017 10:35:12 -0800 Subject: [PATCH 42/53] add link to v3 documentation from the v2 readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2b71e5e..6a26653 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) [![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) +> **NOTE**: for a a sneak preview of what's coming next, [read the documentation for v3.0.0-rc.1](https://github.com/jakesgordon/javascript-state-machine/tree/v3) + A standalone library for finite state machines. # Download From a7e5a2a659498b8a5a2fe0d85be25b0849d5a2a1 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Tue, 10 Jan 2017 12:12:00 -0800 Subject: [PATCH 43/53] add (undocumented) config flag to opt in to be notified of enter/leave lifecycle events even if the transition does NOT change state --- .ackrc | 4 ++ dist/state-machine-visualize.js | 4 +- dist/state-machine-visualize.min.js | 2 +- dist/state-machine.js | 4 +- dist/state-machine.min.js | 2 +- lib/state-machine.js | 4 +- lib/visualize.js | 4 +- src/config.js | 2 +- src/jsm.js | 2 +- src/plugin/visualize.js | 4 +- test/transitions.js | 88 +++++++++++++++++++++++++++++ 11 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 .ackrc diff --git a/.ackrc b/.ackrc new file mode 100644 index 0000000..df1e9a8 --- /dev/null +++ b/.ackrc @@ -0,0 +1,4 @@ +--ignore-dir=coverage +--ignore-dir=node_modules +--ignore-dir=.nyc_output + diff --git a/dist/state-machine-visualize.js b/dist/state-machine-visualize.js index 531bf03..6cfdd7e 100644 --- a/dist/state-machine-visualize.js +++ b/dist/state-machine-visualize.js @@ -167,12 +167,12 @@ dotcfg.states = function(config, options) { dotcfg.transitions = function(config, options) { var n, max, transition, init = config.init, - transitions = config.source.transitions || [], // easier to visualize using the ORIGINAL transition declarations rather than our run-time mapping + transitions = config.options.transitions || [], // easier to visualize using the ORIGINAL transition declarations rather than our run-time mapping output = []; if (options.init && init.active) dotcfg.transition(init.name, init.from, init.to, init.dot, config, options, output) for (n = 0, max = transitions.length ; n < max ; n++) { - transition = config.source.transitions[n] + transition = config.options.transitions[n] dotcfg.transition(transition.name, transition.from, transition.to, transition.dot, config, options, output) } return output diff --git a/dist/state-machine-visualize.min.js b/dist/state-machine-visualize.min.js index 28a9d5a..6e5e296 100644 --- a/dist/state-machine-visualize.min.js +++ b/dist/state-machine-visualize.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachineVisualize",[],n):"object"==typeof exports?exports.StateMachineVisualize=n():t.StateMachineVisualize=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=1)}([function(t,n,e){"use strict";t.exports=function(t,n){var e,r,o;for(e=1;e0&&(u.states=s),a&&a.length>0&&(u.transitions=a),u}function i(t){return" "+t+" "}function s(t){return'"'+t+'"'}function a(t){t=t||{};var n,e,r=t.name||"fsm",o=t.states||[],i=t.transitions||[],u=t.rankdir,f=[];for(f.push("digraph "+s(r)+" {"),u&&f.push(" rankdir="+u+";"),n=0,e=o.length;n "+s(t.to)+a.edge.attr(t)+";"},a.edge.attr=function(t){var n,e,r,o=Object.keys(t).sort(),i=[];for(n=0,e=o.length;n0?" [ "+i.join(" ; ")+" ]":""},r.dotcfg=o,r.dotify=a,t.exports=r}])}); \ No newline at end of file +!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachineVisualize",[],n):"object"==typeof exports?exports.StateMachineVisualize=n():t.StateMachineVisualize=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=1)}([function(t,n,e){"use strict";t.exports=function(t,n){var e,r,o;for(e=1;e0&&(u.states=s),a&&a.length>0&&(u.transitions=a),u}function i(t){return" "+t+" "}function s(t){return'"'+t+'"'}function a(t){t=t||{};var n,e,r=t.name||"fsm",o=t.states||[],i=t.transitions||[],u=t.rankdir,f=[];for(f.push("digraph "+s(r)+" {"),u&&f.push(" rankdir="+u+";"),n=0,e=o.length;n "+s(t.to)+a.edge.attr(t)+";"},a.edge.attr=function(t){var n,e,r,o=Object.keys(t).sort(),i=[];for(n=0,e=o.length;n0?" [ "+i.join(" ; ")+" ]":""},r.dotcfg=o,r.dotify=a,t.exports=r}])}); \ No newline at end of file diff --git a/dist/state-machine.js b/dist/state-machine.js index ac1c3d6..152edfa 100644 --- a/dist/state-machine.js +++ b/dist/state-machine.js @@ -177,7 +177,7 @@ function Config(options, StateMachine) { options = options || {}; - this.source = options; // preserving original options helps with visualize plugin + this.options = options; // preserving original options can be useful (e.g visualize plugin) this.defaults = StateMachine.defaults; this.states = []; this.transitions = []; @@ -404,7 +404,7 @@ mixin(JSM.prototype, { transit: function(transition, from, to, args) { var lifecycle = this.config.lifecycle, - changed = from !== to; + changed = this.config.options.observeUnchangedState || (from !== to); if (!to) return this.context.onInvalidTransition(transition, from, to); diff --git a/dist/state-machine.min.js b/dist/state-machine.min.js index 0120acd..38f2d60 100644 --- a/dist/state-machine.min.js +++ b/dist/state-machine.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachine",[],n):"object"==typeof exports?exports.StateMachine=n():t.StateMachine=n()}(this,function(){return function(t){function n(e){if(i[e])return i[e].exports;var s=i[e]={i:e,l:!1,exports:{}};return t[e].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var i={};return n.m=t,n.c=i,n.i=function(t){return t},n.d=function(t,i,e){n.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(i,"a",i),i},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=6)}([function(t,n,i){"use strict";t.exports=function(t,n){var i,e,s;for(i=1;i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=this.config.options.observeUnchangedState||n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i { //------------------------------------------------------------------------------------------------- +test("transitions that dont change state, dont trigger enter/leave lifecycle events", t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + transitions: [ + { name: 'noop', from: 'none', to: 'none' } + ], + methods: { + onBeforeTransition: logger, + onBeforeNoop: logger, + onLeaveState: logger, + onLeaveNone: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onNone: logger, + onAfterTransition: logger, + onAfterNoop: logger, + onNoop: logger + } + }) + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, []) + + fsm.noop() + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onBeforeNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + +test("transitions that dont change state, can be configured to trigger enter/leave lifecycle events", t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + observeUnchangedState: true, + transitions: [ + { name: 'noop', from: 'none', to: 'none' } + ], + methods: { + onBeforeTransition: logger, + onBeforeNoop: logger, + onLeaveState: logger, + onLeaveNone: logger, + onTransition: logger, + onEnterState: logger, + onEnterNone: logger, + onNone: logger, + onAfterTransition: logger, + onAfterNoop: logger, + onNoop: logger + } + }) + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, []) + + fsm.noop() + + t.is(fsm.state, 'none') + t.deepEqual(logger.log, [ + { event: 'onBeforeTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onBeforeNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onLeaveState', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onLeaveNone', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onEnterState', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onEnterNone', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onNone', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterTransition', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onAfterNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' }, + { event: 'onNoop', transition: 'noop', from: 'none', to: 'none', current: 'none' } + ]) + +}) + +//------------------------------------------------------------------------------------------------- + test("transition methods with dash or underscore are camelized", t => { var fsm = new StateMachine({ From c1bf918223a545399de42ab185cb7b1c18c5e064 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 10 Jun 2017 11:28:12 -0700 Subject: [PATCH 44/53] Fixed issue #107 - lifecycle event name breaks for all uppercase state/transition. --- package-lock.json | 4644 +++++++++++++++++++++++++++++++++++++++++ src/config.js | 22 +- src/plugin/history.js | 10 +- src/util/camelize.js | 30 +- test/lifecycle.js | 50 + test/util/camelize.js | 8 +- 6 files changed, 4741 insertions(+), 23 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ce5765a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4644 @@ +{ + "name": "javascript-state-machine", + "version": "3.0.0-rc.1", + "lockfileVersion": 1, + "dependencies": { + "acorn": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true + }, + "ansi-align": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", + "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true + }, + "arr-exclude": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/arr-exclude/-/arr-exclude-1.0.0.tgz", + "integrity": "sha1-38fC5VKicHI8zaBM8xKMjL/lxjE=", + "dev": true + }, + "arr-flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "dev": true + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true + }, + "async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.1.tgz", + "integrity": "sha1-YqVrJ5yYoR0JhwlqAcw+6463u9c=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "auto-bind": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-0.1.0.tgz", + "integrity": "sha1-einvyMI4jT1XjgL8LfUxyB/8HuE=", + "dev": true + }, + "ava": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-0.17.0.tgz", + "integrity": "sha1-NZ4qiWFoAe8Dkpw88QqdT45FHQI=", + "dev": true + }, + "ava-files": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ava-files/-/ava-files-0.2.0.tgz", + "integrity": "sha1-x7i24uDOpjtXpuJ+DbFFx8Gc/iA=", + "dev": true + }, + "ava-init": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ava-init/-/ava-init-0.1.6.tgz", + "integrity": "sha1-7xntCyS2vzWdrW+63xoF2DY5XJE=", + "dev": true + }, + "babel-code-frame": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "dev": true + }, + "babel-core": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", + "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", + "dev": true + }, + "babel-generator": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", + "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", + "dev": true + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true + }, + "babel-helper-define-map": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", + "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", + "dev": true + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true + }, + "babel-helper-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", + "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", + "dev": true + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true + }, + "babel-plugin-ava-throws-helper": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-ava-throws-helper/-/babel-plugin-ava-throws-helper-0.1.0.tgz", + "integrity": "sha1-lREHcIoSIIAmv4ykzvGKh7ybDP4=", + "dev": true + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true + }, + "babel-plugin-detective": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-detective/-/babel-plugin-detective-2.0.0.tgz", + "integrity": "sha1-bmQug8IqM1J5dU6+LXVNJjX0nxM=", + "dev": true + }, + "babel-plugin-espower": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", + "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", + "dev": true + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", + "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", + "dev": true + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", + "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", + "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", + "dev": true + }, + "babel-plugin-transform-regenerator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "dev": true + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true + }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "dev": true + }, + "babel-preset-es2015-node4": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015-node4/-/babel-preset-es2015-node4-2.1.1.tgz", + "integrity": "sha1-4x8pCFm1hhnIz6JB0bC8kA+UHNs=", + "dev": true + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true + }, + "babel-register": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", + "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", + "dev": true + }, + "babel-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "dev": true + }, + "babel-template": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", + "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", + "dev": true + }, + "babel-traverse": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", + "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", + "dev": true + }, + "babel-types": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", + "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", + "dev": true + }, + "babylon": { + "version": "6.17.3", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.3.tgz", + "integrity": "sha512-mq0x3HCAGGmQyZXviOVe5TRsw37Ijy3D43jCqt/9WVf+onx2dUgW3PosnqCbScAFhRO9DGs8nxoMzU0iiosMqQ==", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "base64-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", + "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=", + "dev": true + }, + "big.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", + "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=", + "dev": true + }, + "binary-extensions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", + "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", + "dev": true + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "dev": true + }, + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "boxen": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", + "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", + "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "dev": true + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true + }, + "buf-compare": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", + "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", + "dev": true + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "caching-transform": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", + "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", + "dev": true + }, + "call-matcher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", + "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", + "dev": true + }, + "call-signature": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true + }, + "ci-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", + "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", + "dev": true + }, + "cipher-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", + "integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=", + "dev": true + }, + "clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true + }, + "cli-spinners": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "co-with-promise": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", + "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", + "dev": true, + "dependencies": { + "pinkie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", + "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", + "dev": true + }, + "pinkie-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", + "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", + "dev": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "common-path-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", + "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "configstore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", + "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "core-assert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", + "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", + "dev": true + }, + "core-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true + }, + "crypto-browserify": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", + "integrity": "sha1-NlKgkGq5sqfgw85mpAjpV6JIVSI=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "date-time": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-0.1.1.tgz", + "integrity": "sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc=", + "dev": true + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true + }, + "eastasianwidth": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.1.1.tgz", + "integrity": "sha1-RNZW3p2kFWlEZzNTZfsxR7hXK3w=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "empower-core": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz", + "integrity": "sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ=", + "dev": true + }, + "enhanced-resolve": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz", + "integrity": "sha1-n0tib1dyRe3PSyrYPYbhf09CHew=", + "dev": true + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "espower-location-detector": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "dev": true + }, + "espurify": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", + "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", + "dev": true + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", + "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "dev": true + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true + }, + "filled-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", + "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=", + "dev": true + }, + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true + }, + "fn-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", + "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true + }, + "fs-sync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-sync/-/fs-sync-1.0.4.tgz", + "integrity": "sha1-L5Tq3jGGLsCp8zocJUbfsaPz0a4=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.1.tgz", + "integrity": "sha1-8Z/Sj0Pur3YWgOUZogPE0LPTGv8=", + "dev": true, + "optional": true, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.11.0", + "bundled": true, + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "deep-extend": { + "version": "0.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "extend": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.10", + "bundled": true, + "dev": true + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.3", + "bundled": true, + "dev": true, + "optional": true + }, + "generate-function": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "generate-object-property": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "getpass": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.1", + "bundled": true, + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "2.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-my-json-valid": { + "version": "2.15.0", + "bundled": true, + "dev": true, + "optional": true + }, + "is-property": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonpointer": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "optional": true + }, + "mime-db": { + "version": "1.26.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.14", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true + }, + "ms": { + "version": "0.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.33", + "bundled": true, + "dev": true, + "optional": true + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npmlog": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.3.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.2", + "bundled": true, + "dev": true, + "optional": true + }, + "request": { + "version": "2.79.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rimraf": { + "version": "2.5.4", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "optional": true + }, + "sshpk": { + "version": "1.10.2", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "supports-color": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "tar-pack": { + "version": "3.3.0", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "once": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "2.1.5", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true + }, + "tunnel-agent": { + "version": "0.4.3", + "bundled": true, + "dev": true, + "optional": true + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-port": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", + "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true + }, + "got": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", + "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true + }, + "hash.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", + "integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true + }, + "hosted-git-info": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", + "dev": true + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.17.tgz", + "integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0=", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "interpret": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "irregular-plurals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true + }, + "is-error": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", + "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true + }, + "is-generator-fn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-url": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", + "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true + }, + "js-tokens": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-loader": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz", + "integrity": "sha1-i6oTZaYy9Yo8RtIBdfxgAsluN94=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true + }, + "last-line-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", + "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", + "dev": true + }, + "latest-version": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", + "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lazy-req": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", + "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "lru-cache": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.0.tgz", + "integrity": "sha512-aHGs865JXz6bkB4AHL+3AhyvTFKL3iZamKVWjIUKnXOXyasJvqPK8WAjOnAQKQZVpeXDVz19u1DD0r/12bWAdQ==", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "matcher": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-0.1.2.tgz", + "integrity": "sha1-7yDL3mTCTFDMYa9bg+4LG4/wAQE=", + "dev": true + }, + "max-timeout": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/max-timeout/-/max-timeout-1.0.0.tgz", + "integrity": "sha1-to9povmeC0dv1Msj4gWcp1BxXh8=", + "dev": true + }, + "md5-hex": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", + "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", + "dev": true + }, + "md5-o-matic": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", + "dev": true + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true + }, + "miller-rabin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", + "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true + }, + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true + }, + "nan": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", + "dev": true, + "optional": true + }, + "no-case": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.1.tgz", + "integrity": "sha1-euuhxzpSGEJlVUt9wDuvcg34AIE=", + "dev": true + }, + "node-libs-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", + "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "dev": true, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "node-status-codes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", + "dev": true + }, + "normalize-package-data": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nyc": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-10.3.2.tgz", + "integrity": "sha1-8n9NkfKp2zbCT1dP9cbv/wIz3kY=", + "dev": true, + "dependencies": { + "align-text": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "arr-flatten": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "babel-code-frame": { + "version": "6.22.0", + "bundled": true, + "dev": true + }, + "babel-generator": { + "version": "6.24.1", + "bundled": true, + "dev": true + }, + "babel-messages": { + "version": "6.23.0", + "bundled": true, + "dev": true + }, + "babel-runtime": { + "version": "6.23.0", + "bundled": true, + "dev": true + }, + "babel-template": { + "version": "6.24.1", + "bundled": true, + "dev": true + }, + "babel-traverse": { + "version": "6.24.1", + "bundled": true, + "dev": true + }, + "babel-types": { + "version": "6.24.1", + "bundled": true, + "dev": true + }, + "babylon": { + "version": "6.17.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true + }, + "braces": { + "version": "1.8.5", + "bundled": true, + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "center-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "bundled": true, + "dev": true + }, + "core-js": { + "version": "2.4.1", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true + }, + "debug": { + "version": "2.6.6", + "bundled": true, + "dev": true + }, + "debug-log": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "esutils": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "bundled": true, + "dev": true + }, + "expand-range": { + "version": "1.8.2", + "bundled": true, + "dev": true + }, + "extglob": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "filename-regex": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "bundled": true, + "dev": true + }, + "find-cache-dir": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "for-in": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "for-own": { + "version": "0.1.5", + "bundled": true, + "dev": true + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "glob": { + "version": "7.1.1", + "bundled": true, + "dev": true + }, + "glob-base": { + "version": "0.3.0", + "bundled": true, + "dev": true + }, + "glob-parent": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "globals": { + "version": "9.17.0", + "bundled": true, + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.8", + "bundled": true, + "dev": true, + "dependencies": { + "source-map": { + "version": "0.4.4", + "bundled": true, + "dev": true + } + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.4.2", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invariant": { + "version": "2.2.2", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-buffer": { + "version": "1.1.5", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-dotfile": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "bundled": true, + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "is-number": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "istanbul-lib-instrument": { + "version": "1.7.1", + "bundled": true, + "dev": true + }, + "istanbul-lib-report": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "bundled": true, + "dev": true + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "istanbul-reports": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "js-tokens": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "3.2.0", + "bundled": true, + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "lodash": { + "version": "4.17.4", + "bundled": true, + "dev": true + }, + "longest": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.0.2", + "bundled": true, + "dev": true + }, + "md5-hex": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "md5-o-matic": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "merge-source-map": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true + }, + "ms": { + "version": "0.7.3", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.3.8", + "bundled": true, + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "bundled": true, + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "bundled": true, + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "pify": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "preserve": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "randomatic": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "regenerator-runtime": { + "version": "0.10.5", + "bundled": true, + "dev": true + }, + "regex-cache": { + "version": "0.4.3", + "bundled": true, + "dev": true + }, + "remove-trailing-separator": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true, + "dev": true + }, + "repeating": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "right-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "source-map": { + "version": "0.5.6", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "dependencies": { + "signal-exit": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "uglify-js": { + "version": "2.8.22", + "bundled": true, + "dev": true, + "optional": true, + "dependencies": { + "yargs": { + "version": "3.10.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "which": { + "version": "1.2.14", + "bundled": true, + "dev": true + }, + "which-module": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "window-size": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "1.3.4", + "bundled": true, + "dev": true + }, + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "3.2.0", + "bundled": true, + "dev": true + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true + }, + "observable-to-promise": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.4.0.tgz", + "integrity": "sha1-KK/nFkUwjy1B1x9HrT/s4aN35Ss=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "option-chain": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-0.1.1.tgz", + "integrity": "sha1-6bgR4AbxwPVIAvKClb/Ilw+Nz70=", + "dev": true + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "dev": true + }, + "package-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", + "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", + "dev": true + }, + "package-json": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", + "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true + }, + "parse-ms": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", + "dev": true + }, + "pascal-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", + "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", + "integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true + }, + "pkg-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-1.1.3.tgz", + "integrity": "sha1-N45W1v0T6Iv7b0ol33qD+qvduls=", + "dev": true + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true + }, + "power-assert-context-formatter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz", + "integrity": "sha1-7bo1LT7YpgMRTWZyZazOYNaJzN8=", + "dev": true + }, + "power-assert-context-traversal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-context-traversal/-/power-assert-context-traversal-1.1.1.tgz", + "integrity": "sha1-iMq8oNE7Y1nwfT0+ivppkmRXftk=", + "dev": true + }, + "power-assert-renderer-assertion": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.1.1.tgz", + "integrity": "sha1-y/wOd+AIao+Wrz8djme57n4ozpg=", + "dev": true + }, + "power-assert-renderer-base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-renderer-base/-/power-assert-renderer-base-1.1.1.tgz", + "integrity": "sha1-lqZQxv0F7hvB9mtUrWFELIs/Y+s=", + "dev": true + }, + "power-assert-renderer-diagram": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.1.2.tgz", + "integrity": "sha1-ZV+PcRk1qbbVQbhjJ2VHF8Y3qYY=", + "dev": true + }, + "power-assert-renderer-succinct": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-renderer-succinct/-/power-assert-renderer-succinct-1.1.1.tgz", + "integrity": "sha1-wqRosjgiq9b4Diq6UyI0ewnfR24=", + "dev": true + }, + "power-assert-util-string-width": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/power-assert-util-string-width/-/power-assert-util-string-width-1.1.1.tgz", + "integrity": "sha1-vmWet5N/3S5smncmjar2S9W3xZI=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "dev": true, + "dependencies": { + "plur": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", + "dev": true + } + } + }, + "private": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "dependencies": { + "safe-buffer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz", + "integrity": "sha512-aSLEDudu6OoRr/2rU609gRmnYboRLxgDG1z9o2Q0os7236FwvcqIOO8r8U5JUEwivZOhDaKlFO4SbPTJYyBEyQ==", + "dev": true + } + } + }, + "rc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "read-all-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true + }, + "readable-stream": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.11.tgz", + "integrity": "sha512-h+8+r3MKEhkiVrwdKL8aWs1oc1VvBu33ueshOvS26RsZQ3Amhx/oO3TKe4lApSV9ueY6as8EAh7mtuFjdlhg9Q==", + "dev": true + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true + }, + "regenerate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", + "dev": true + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + }, + "regenerator-transform": { + "version": "0.9.11", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "dev": true + }, + "regex-cache": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true + }, + "registry-auth-token": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "dev": true + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", + "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-precompiled": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", + "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "dev": true + }, + "resolve-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", + "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true + }, + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true + }, + "source-list-map": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz", + "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + }, + "source-map-support": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", + "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "stack-utils": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-0.4.0.tgz", + "integrity": "sha1-lAy4L8z6hOj/Lz/fKT/ngBa+zNE=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true + }, + "stream-http": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.1.tgz", + "integrity": "sha1-VGpRdBrVprB+njGwsQRBqRffUoo=", + "dev": true + }, + "string_decoder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true + }, + "stringifier": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz", + "integrity": "sha1-3vGDQvaTPbDy2/yaoCF1tEjBeVk=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/symbol/-/symbol-0.2.3.tgz", + "integrity": "sha1-O5hzuKkB5Hxu/iFSajrDcu8ou8c=", + "dev": true + }, + "symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true + }, + "tapable": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.6.tgz", + "integrity": "sha1-IGvo4YiGC1FEJTdebxrom/sB/Y0=", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "the-argv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz", + "integrity": "sha1-AIRwUAVzDdhNt1UlPJMa45jblSI=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + }, + "time-require": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", + "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", + "dev": true, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true + }, + "parse-ms": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", + "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "dev": true + }, + "pretty-ms": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", + "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "dev": true + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "timed-out": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", + "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", + "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/type-name/-/type-name-2.0.2.tgz", + "integrity": "sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q=", + "dev": true + }, + "uglify-js": { + "version": "2.8.28", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.28.tgz", + "integrity": "sha512-WqKNbmNJKzIdIEQu/U2ytgGBbhCy2PVks94GoetczOAJ/zCgVu2CuO7gguI5KPFGPtUtI1dmPQl6h0D4cPzypA==", + "dev": true + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", + "dev": true + }, + "unique-temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", + "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", + "dev": true + }, + "unzip-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", + "dev": true + }, + "update-notifier": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", + "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "upper-case-first": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", + "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true + }, + "watchpack": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz", + "integrity": "sha1-fYaTkHsozmAT5/NhCqKhrPB9rYc=", + "dev": true + }, + "webpack": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.6.1.tgz", + "integrity": "sha1-LgRX8KuxrF3zqxBsacZy8jZ4Xwc=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true + } + } + }, + "webpack-sources": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", + "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=", + "dev": true + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "widest-line": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "dev": true + }, + "write-json-file": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-1.2.0.tgz", + "integrity": "sha1-LV3+lqvDyIkFfJOXGqQAXvtUgTQ=", + "dev": true + }, + "write-pkg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-1.0.0.tgz", + "integrity": "sha1-rriqnU14jh2JPfsIVJaLVDqRn1c=", + "dev": true + }, + "xdg-basedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + } + } +} diff --git a/src/config.js b/src/config.js index 72e8a2c..21601df 100644 --- a/src/config.js +++ b/src/config.js @@ -42,9 +42,9 @@ mixin(Config.prototype, { }, addStateLifecycleNames: function(name) { - this.lifecycle.onEnter[name] = camelize('on-enter-' + name); - this.lifecycle.onLeave[name] = camelize('on-leave-' + name); - this.lifecycle.on[name] = camelize('on-' + name); + this.lifecycle.onEnter[name] = camelize.prepended('onEnter', name); + this.lifecycle.onLeave[name] = camelize.prepended('onLeave', name); + this.lifecycle.on[name] = camelize.prepended('on', name); }, addTransition: function(name) { @@ -55,9 +55,9 @@ mixin(Config.prototype, { }, addTransitionLifecycleNames: function(name) { - this.lifecycle.onBefore[name] = camelize('on-before-' + name); - this.lifecycle.onAfter[name] = camelize('on-after-' + name); - this.lifecycle.on[name] = camelize('on-' + name); + this.lifecycle.onBefore[name] = camelize.prepended('onBefore', name); + this.lifecycle.onAfter[name] = camelize.prepended('onAfter', name); + this.lifecycle.on[name] = camelize.prepended('on', name); }, mapTransition: function(transition) { @@ -74,11 +74,11 @@ mixin(Config.prototype, { configureLifecycle: function() { return { - onBefore: { transition: camelize('on-before-transition') }, - onAfter: { transition: camelize('on-after-transition') }, - onEnter: { state: camelize('on-enter-state') }, - onLeave: { state: camelize('on-leave-state') }, - on: { transition: camelize('on-transition') } + onBefore: { transition: 'onBeforeTransition' }, + onAfter: { transition: 'onAfterTransition' }, + onEnter: { state: 'onEnterState' }, + onLeave: { state: 'onLeaveState' }, + on: { transition: 'onTransition' } }; }, diff --git a/src/plugin/history.js b/src/plugin/history.js index ccfcd98..46799c0 100644 --- a/src/plugin/history.js +++ b/src/plugin/history.js @@ -10,11 +10,11 @@ module.exports = function(options) { options = options || {}; var past = camelize(options.name || options.past || 'history'), future = camelize( options.future || 'future'), - clear = camelize('clear-' + past), - back = camelize(past + '-back'), - forward = camelize(past + '-forward'), - canBack = camelize('can-' + back), - canForward = camelize('can-' + forward), + clear = camelize.prepended('clear', past), + back = camelize.prepended(past, 'back'), + forward = camelize.prepended(past, 'forward'), + canBack = camelize.prepended('can', back), + canForward = camelize.prepended('can', forward), max = options.max; var plugin = { diff --git a/src/util/camelize.js b/src/util/camelize.js index 87c7540..b2645fd 100644 --- a/src/util/camelize.js +++ b/src/util/camelize.js @@ -1,9 +1,33 @@ 'use strict' -module.exports = function(label) { - var n, word, words = label.split(/[_-]/), result = words[0]; +//------------------------------------------------------------------------------------------------- + +function camelize(label) { + + if (label.length === 0) + return label; + + var n, result, word, words = label.split(/[_-]/); + + // single word with first character already lowercase, return untouched + if ((words.length === 1) && (words[0][0].toLowerCase() === words[0][0])) + return label; + + result = words[0].toLowerCase(); for(n = 1 ; n < words.length ; n++) { - result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1).toLowerCase(); } + return result; } + +//------------------------------------------------------------------------------------------------- + +camelize.prepended = function(prepend, label) { + label = camelize(label); + return prepend + label[0].toUpperCase() + label.substring(1); +} + +//------------------------------------------------------------------------------------------------- + +module.exports = camelize; diff --git a/test/lifecycle.js b/test/lifecycle.js index 4375d65..281efe3 100644 --- a/test/lifecycle.js +++ b/test/lifecycle.js @@ -227,6 +227,56 @@ test('lifecycle events with dash or underscore are camelized', t => { //------------------------------------------------------------------------------------------------- +test('lifecycle event names that are all uppercase are camelized', t => { + + var logger = new LifecycleLogger(), + fsm = new StateMachine({ + init: 'FIRST', + transitions: [ + { name: 'GO', from: 'FIRST', to: 'SECOND_STATE' }, + { name: 'DO_IT', from: 'SECOND_STATE', to: 'FIRST' } + ], + methods: { + onBeforeGo: logger, + onBeforeDoIt: logger, + onLeaveFirst: logger, + onLeaveSecondState: logger, + onEnterFirst: logger, + onEnterSecondState: logger, + onAfterGo: logger, + onAfterDoIt: logger + } + }); + + t.is(fsm.state, 'FIRST') + t.deepEqual(logger.log, [ + { event: 'onEnterFirst', transition: 'init', from: 'none', to: 'FIRST', current: 'FIRST' }, + ]) + + logger.clear() + fsm.go() + t.is(fsm.state, 'SECOND_STATE') + t.deepEqual(logger.log, [ + { event: 'onBeforeGo', transition: 'GO', from: 'FIRST', to: 'SECOND_STATE', current: 'FIRST' }, + { event: 'onLeaveFirst', transition: 'GO', from: 'FIRST', to: 'SECOND_STATE', current: 'FIRST' }, + { event: 'onEnterSecondState', transition: 'GO', from: 'FIRST', to: 'SECOND_STATE', current: 'SECOND_STATE' }, + { event: 'onAfterGo', transition: 'GO', from: 'FIRST', to: 'SECOND_STATE', current: 'SECOND_STATE' } + ]) + + logger.clear(); + fsm.doIt(); + t.is(fsm.state, 'FIRST') + t.deepEqual(logger.log, [ + { event: 'onBeforeDoIt', transition: 'DO_IT', from: 'SECOND_STATE', to: 'FIRST', current: 'SECOND_STATE' }, + { event: 'onLeaveSecondState', transition: 'DO_IT', from: 'SECOND_STATE', to: 'FIRST', current: 'SECOND_STATE' }, + { event: 'onEnterFirst', transition: 'DO_IT', from: 'SECOND_STATE', to: 'FIRST', current: 'FIRST' }, + { event: 'onAfterDoIt', transition: 'DO_IT', from: 'SECOND_STATE', to: 'FIRST', current: 'FIRST' } + ]) + +}); + +//------------------------------------------------------------------------------------------------- + test('lifecycle events receive arbitrary transition arguments', t => { var logger = new LifecycleLogger(), diff --git a/test/util/camelize.js b/test/util/camelize.js index 9e3bb04..84318a2 100644 --- a/test/util/camelize.js +++ b/test/util/camelize.js @@ -4,11 +4,11 @@ import camelize from '../../src/util/camelize'; test('camelize', t => { t.is(camelize(""), ""); t.is(camelize("word"), "word"); - t.is(camelize("Word"), "Word"); - t.is(camelize("WORD"), "WORD"); + t.is(camelize("Word"), "word"); + t.is(camelize("WORD"), "word"); t.is(camelize("word-with-dash"), "wordWithDash"); t.is(camelize("word_with_underscore"), "wordWithUnderscore"); t.is(camelize("word--with--double--dash"), "wordWithDoubleDash"); - t.is(camelize("word_WITH_mixed_CASE"), "wordWITHMixedCASE"); - t.is(camelize("alreadyCamelized"), "alreadyCamelized"); + t.is(camelize("word_WITH_mixed_CASE"), "wordWithMixedCase"); + t.is(camelize("alreadyCamelizedString"), "alreadyCamelizedString"); }); From 9143d575f6bb77e8969678651cd43169db7b63b3 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 10 Jun 2017 14:18:58 -0700 Subject: [PATCH 45/53] fix issue #106 - forward resolved async value to end of lifecycle --- .gitignore | 1 + src/jsm.js | 8 ++++---- test/lifecycle.js | 19 ++++++++++--------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1fd04da..89d2c73 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules coverage .nyc_output +*.swp diff --git a/src/jsm.js b/src/jsm.js index 6288f1f..b6b56f4 100644 --- a/src/jsm.js +++ b/src/jsm.js @@ -131,9 +131,9 @@ mixin(JSM.prototype, { return [ event, result, true ] }, - observeEvents: function(events, args, previousEvent) { + observeEvents: function(events, args, previousEvent, previousResult) { if (events.length === 0) { - return this.endTransit(true); + return this.endTransit(previousResult === undefined ? true : previousResult); } var event = events[0][0], @@ -146,7 +146,7 @@ mixin(JSM.prototype, { if (observers.length === 0) { events.shift(); - return this.observeEvents(events, args, event); + return this.observeEvents(events, args, event, previousResult); } else { var observer = observers.shift(), @@ -159,7 +159,7 @@ mixin(JSM.prototype, { return this.endTransit(false); } else { - return this.observeEvents(events, args, event); + return this.observeEvents(events, args, event, result); } } }, diff --git a/test/lifecycle.js b/test/lifecycle.js index 281efe3..e793a57 100644 --- a/test/lifecycle.js +++ b/test/lifecycle.js @@ -490,7 +490,7 @@ test('lifecycle events can be deferred using a promise', t => { var logger = new LifecycleLogger(), start = Date.now(), - pause = function(ms) { return new Promise(function(resolve, reject) { setTimeout(resolve, ms); }); }, + pause = function(ms) { return new Promise(function(resolve, reject) { setTimeout(function() { resolve('resolved') }, ms); }); }, fsm = new StateMachine({ transitions: [ { name: 'step', from: 'none', to: 'complete' } @@ -506,11 +506,11 @@ test('lifecycle events can be deferred using a promise', t => { onLeaveNone: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, onLeaveComplete: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, onAfterTransition: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); }, - onAfterStep: function(lifecycle, a, b) { logger(lifecycle, a, b); return done(); } + onAfterStep: function(lifecycle, a, b) { logger(lifecycle, a, b); return pause(100); } } }); - function done() { + function done(answer) { var duration = Date.now() - start; t.is(fsm.state, 'complete') t.is(duration > 600, true) @@ -525,10 +525,12 @@ test('lifecycle events can be deferred using a promise', t => { { event: 'onAfterTransition', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, { event: 'onAfterStep', transition: 'step', from: 'none', to: 'complete', current: 'complete', args: [ 'additional', 'arguments' ] }, ]) + t.is(answer, 'resolved'); resolveTest() } fsm.step('additional', 'arguments') + .then(done); }); }); @@ -542,15 +544,12 @@ test('lifecycle events can be cancelled using a promise', t => { start = Date.now(), pause = function(ms) { return new Promise(function(resolve, reject) { - setTimeout(resolve, ms); + setTimeout(function() { resolve('resolved') }, ms); }); }, cancel = function(ms) { return new Promise(function(resolve, reject) { - setTimeout(function() { - reject(); - done(); - }, ms); + setTimeout(function() { reject('rejected'); }, ms); }); }, fsm = new StateMachine({ @@ -572,7 +571,7 @@ test('lifecycle events can be cancelled using a promise', t => { } }); - function done() { + function done(answer) { var duration = Date.now() - start; t.is(fsm.state, 'none'); t.is(duration > 300, true); @@ -583,10 +582,12 @@ test('lifecycle events can be cancelled using a promise', t => { { event: 'onLeaveNone', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] }, { event: 'onTransition', transition: 'step', from: 'none', to: 'complete', current: 'none', args: [ 'additional', 'arguments' ] } ]); + t.is(answer, 'rejected'); resolveTest(); } fsm.step('additional', 'arguments') + .then(done) }) }) From 186130856cbbd777f2646bdfaaefcf6fcef85a26 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 10 Jun 2017 14:24:53 -0700 Subject: [PATCH 46/53] Issue #106 - a rejected async lifecycle event should throw an exception --- src/jsm.js | 3 ++- test/lifecycle.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/jsm.js b/src/jsm.js index b6b56f4..f83c8de 100644 --- a/src/jsm.js +++ b/src/jsm.js @@ -108,6 +108,7 @@ mixin(JSM.prototype, { beginTransit: function() { this.pending = true; }, endTransit: function(result) { this.pending = false; return result; }, + failTransit: function(result) { this.pending = false; throw result; }, doTransit: function(lifecycle) { this.state = lifecycle.to; }, observe: function(args) { @@ -153,7 +154,7 @@ mixin(JSM.prototype, { result = observer[event].apply(observer, args); if (result && typeof result.then === 'function') { return result.then(this.observeEvents.bind(this, events, args, event)) - .catch(this.endTransit.bind(this)) + .catch(this.failTransit.bind(this)) } else if (result === false) { return this.endTransit(false); diff --git a/test/lifecycle.js b/test/lifecycle.js index e793a57..347ebf4 100644 --- a/test/lifecycle.js +++ b/test/lifecycle.js @@ -587,7 +587,8 @@ test('lifecycle events can be cancelled using a promise', t => { } fsm.step('additional', 'arguments') - .then(done) + .then(function() { done('promise was rejected so this should never happen'); }) + .catch(done) }) }) From e09614a51f2a64724bb151da6462bcb34fdb9883 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 10 Jun 2017 14:42:55 -0700 Subject: [PATCH 47/53] first 3.x release (3.0.1) --- README.md | 2 +- RELEASE_NOTES.md | 9 ++ dist/state-machine-history.js | 80 +++++++++----- dist/state-machine-history.min.js | 2 +- dist/state-machine-visualize.js | 40 +++---- dist/state-machine-visualize.min.js | 2 +- dist/state-machine.js | 157 ++++++++++++++++------------ dist/state-machine.min.js | 2 +- lib/history.js | 80 +++++++++----- lib/state-machine.js | 157 ++++++++++++++++------------ lib/visualize.js | 40 +++---- package-lock.json | 2 +- package.json | 2 +- src/app.js | 2 +- test/basics.js | 2 +- 15 files changed, 343 insertions(+), 236 deletions(-) diff --git a/README.md b/README.md index b94ec4b..bd46ea3 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ In a browser: Using npm: ```shell - npm install --save-dev javascript-state-machine@3.0.0-rc.1 # note explicit pre-release version + npm install --save-dev javascript-state-machine ``` In Node.js: diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 5d64d17..6ada814 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,12 @@ +Version 3.0.1 (June 10th 2017) +------------------------------ + + * First 3.x release - see 3.0.0-rc.1 release notes below + + * fix issue #109 - rejection from async lifecycle method does not reject transitions promise + * fix issue #106 - async transition: forward resolved value + * fix issue #107 - lifecycle event name breaks for all uppercase + Version 3.0.0-rc.1 (January 10 2017) ------------------------------------ diff --git a/dist/state-machine-history.js b/dist/state-machine-history.js index d604994..19f7c4f 100644 --- a/dist/state-machine-history.js +++ b/dist/state-machine-history.js @@ -11,41 +11,41 @@ return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; - +/******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { - +/******/ /******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) +/******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; - +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; - +/******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - +/******/ /******/ // Flag the module as loaded /******/ module.l = true; - +/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } - - +/******/ +/******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; - +/******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; - +/******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; - +/******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { @@ -56,7 +56,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ }); /******/ } /******/ }; - +/******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? @@ -65,36 +65,60 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; - +/******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - +/******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; - +/******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 1); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = function(label) { - var n, word, words = label.split(/[_-]/), result = words[0]; +//------------------------------------------------------------------------------------------------- + +function camelize(label) { + + if (label.length === 0) + return label; + + var n, result, word, words = label.split(/[_-]/); + + // single word with first character already lowercase, return untouched + if ((words.length === 1) && (words[0][0].toLowerCase() === words[0][0])) + return label; + + result = words[0].toLowerCase(); for(n = 1 ; n < words.length ; n++) { - result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1).toLowerCase(); } + return result; } +//------------------------------------------------------------------------------------------------- + +camelize.prepended = function(prepend, label) { + label = camelize(label); + return prepend + label[0].toUpperCase() + label.substring(1); +} + +//------------------------------------------------------------------------------------------------- + +module.exports = camelize; + -/***/ }, +/***/ }), /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -109,11 +133,11 @@ module.exports = function(options) { options = options || {}; var past = camelize(options.name || options.past || 'history'), future = camelize( options.future || 'future'), - clear = camelize('clear-' + past), - back = camelize(past + '-back'), - forward = camelize(past + '-forward'), - canBack = camelize('can-' + back), - canForward = camelize('can-' + forward), + clear = camelize.prepended('clear', past), + back = camelize.prepended(past, 'back'), + forward = camelize.prepended(past, 'forward'), + canBack = camelize.prepended('can', back), + canForward = camelize.prepended('can', forward), max = options.max; var plugin = { @@ -182,6 +206,6 @@ module.exports = function(options) { options = options || {}; } -/***/ } +/***/ }) /******/ ]); }); \ No newline at end of file diff --git a/dist/state-machine-history.min.js b/dist/state-machine-history.min.js index c186024..9c7fb3f 100644 --- a/dist/state-machine-history.min.js +++ b/dist/state-machine-history.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("StateMachineHistory",[],e):"object"==typeof exports?exports.StateMachineHistory=e():t.StateMachineHistory=e()}(this,function(){return 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.i=function(t){return t},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=1)}([function(t,e,n){"use strict";t.exports=function(t){var e,n=t.split(/[_-]/),r=n[0];for(e=1;ef&&t[e].shift(),r.transition!==i&&r.transition!==s&&(t[n].length=0))},methods:{},properties:{}};return a.methods[o]=function(){this[e].length=0,this[n].length=0},a.properties[u]={get:function(){return this[e].length>1}},a.properties[c]={get:function(){return this[n].length>0}},a.methods[i]=function(){if(!this[u])throw Error("no history");var t=this[e].pop(),r=this[e].pop();this[n].push(t),this._fsm.transit(i,t,r,[])},a.methods[s]=function(){if(!this[c])throw Error("no history");var t=this.state,e=this[n].pop();this._fsm.transit(s,t,e,[])},a}}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("StateMachineHistory",[],e):"object"==typeof exports?exports.StateMachineHistory=e():t.StateMachineHistory=e()}(this,function(){return 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.i=function(t){return t},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=1)}([function(t,e,n){"use strict";function r(t){if(0===t.length)return t;var e,n,r=t.split(/[_-]/);if(1===r.length&&r[0][0].toLowerCase()===r[0][0])return t;for(n=r[0].toLowerCase(),e=1;ec&&t[e].shift(),r.transition!==i&&r.transition!==s&&(t[n].length=0))},methods:{},properties:{}};return f.methods[o]=function(){this[e].length=0,this[n].length=0},f.properties[u]={get:function(){return this[e].length>1}},f.properties[p]={get:function(){return this[n].length>0}},f.methods[i]=function(){if(!this[u])throw Error("no history");var t=this[e].pop(),r=this[e].pop();this[n].push(t),this._fsm.transit(i,t,r,[])},f.methods[s]=function(){if(!this[p])throw Error("no history");var t=this.state,e=this[n].pop();this._fsm.transit(s,t,e,[])},f}}])}); \ No newline at end of file diff --git a/dist/state-machine-visualize.js b/dist/state-machine-visualize.js index 6cfdd7e..9c18e13 100644 --- a/dist/state-machine-visualize.js +++ b/dist/state-machine-visualize.js @@ -11,41 +11,41 @@ return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; - +/******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { - +/******/ /******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) +/******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; - +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; - +/******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - +/******/ /******/ // Flag the module as loaded /******/ module.l = true; - +/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } - - +/******/ +/******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; - +/******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; - +/******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; - +/******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { @@ -56,7 +56,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ }); /******/ } /******/ }; - +/******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? @@ -65,20 +65,20 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; - +/******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - +/******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; - +/******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 1); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -96,9 +96,9 @@ module.exports = function(target, sources) { } -/***/ }, +/***/ }), /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -264,6 +264,6 @@ module.exports = visualize; //------------------------------------------------------------------------------------------------- -/***/ } +/***/ }) /******/ ]); }); \ No newline at end of file diff --git a/dist/state-machine-visualize.min.js b/dist/state-machine-visualize.min.js index 6e5e296..e517d3b 100644 --- a/dist/state-machine-visualize.min.js +++ b/dist/state-machine-visualize.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachineVisualize",[],n):"object"==typeof exports?exports.StateMachineVisualize=n():t.StateMachineVisualize=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=1)}([function(t,n,e){"use strict";t.exports=function(t,n){var e,r,o;for(e=1;e0&&(u.states=s),a&&a.length>0&&(u.transitions=a),u}function i(t){return" "+t+" "}function s(t){return'"'+t+'"'}function a(t){t=t||{};var n,e,r=t.name||"fsm",o=t.states||[],i=t.transitions||[],u=t.rankdir,f=[];for(f.push("digraph "+s(r)+" {"),u&&f.push(" rankdir="+u+";"),n=0,e=o.length;n "+s(t.to)+a.edge.attr(t)+";"},a.edge.attr=function(t){var n,e,r,o=Object.keys(t).sort(),i=[];for(n=0,e=o.length;n0?" [ "+i.join(" ; ")+" ]":""},r.dotcfg=o,r.dotify=a,t.exports=r}])}); \ No newline at end of file +!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachineVisualize",[],n):"object"==typeof exports?exports.StateMachineVisualize=n():t.StateMachineVisualize=n()}(this,function(){return function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};return n.m=t,n.c=e,n.i=function(t){return t},n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=1)}([function(t,n,e){"use strict";t.exports=function(t,n){var e,r,o;for(e=1;e0&&(u.states=s),a&&a.length>0&&(u.transitions=a),u}function i(t){return" "+t+" "}function s(t){return'"'+t+'"'}function a(t){t=t||{};var n,e,r=t.name||"fsm",o=t.states||[],i=t.transitions||[],u=t.rankdir,f=[];for(f.push("digraph "+s(r)+" {"),u&&f.push(" rankdir="+u+";"),n=0,e=o.length;n "+s(t.to)+a.edge.attr(t)+";"},a.edge.attr=function(t){var n,e,r,o=Object.keys(t).sort(),i=[];for(n=0,e=o.length;n0?" [ "+i.join(" ; ")+" ]":""},r.dotcfg=o,r.dotify=a,t.exports=r}])}); \ No newline at end of file diff --git a/dist/state-machine.js b/dist/state-machine.js index 152edfa..b8b9e37 100644 --- a/dist/state-machine.js +++ b/dist/state-machine.js @@ -11,41 +11,41 @@ return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; - +/******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { - +/******/ /******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) +/******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; - +/******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; - +/******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - +/******/ /******/ // Flag the module as loaded /******/ module.l = true; - +/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } - - +/******/ +/******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; - +/******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; - +/******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; - +/******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { @@ -56,7 +56,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ }); /******/ } /******/ }; - +/******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? @@ -65,20 +65,20 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; - +/******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - +/******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; - +/******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 6); +/******/ return __webpack_require__(__webpack_require__.s = 5); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -96,9 +96,9 @@ module.exports = function(target, sources) { } -/***/ }, +/***/ }), /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -143,25 +143,49 @@ module.exports = { //------------------------------------------------------------------------------------------------- -/***/ }, +/***/ }), /* 2 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = function(label) { - var n, word, words = label.split(/[_-]/), result = words[0]; +//------------------------------------------------------------------------------------------------- + +function camelize(label) { + + if (label.length === 0) + return label; + + var n, result, word, words = label.split(/[_-]/); + + // single word with first character already lowercase, return untouched + if ((words.length === 1) && (words[0][0].toLowerCase() === words[0][0])) + return label; + + result = words[0].toLowerCase(); for(n = 1 ; n < words.length ; n++) { - result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1); + result = result + words[n].charAt(0).toUpperCase() + words[n].substring(1).toLowerCase(); } + return result; } +//------------------------------------------------------------------------------------------------- + +camelize.prepended = function(prepend, label) { + label = camelize(label); + return prepend + label[0].toUpperCase() + label.substring(1); +} + +//------------------------------------------------------------------------------------------------- + +module.exports = camelize; -/***/ }, + +/***/ }), /* 3 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -208,9 +232,9 @@ mixin(Config.prototype, { }, addStateLifecycleNames: function(name) { - this.lifecycle.onEnter[name] = camelize('on-enter-' + name); - this.lifecycle.onLeave[name] = camelize('on-leave-' + name); - this.lifecycle.on[name] = camelize('on-' + name); + this.lifecycle.onEnter[name] = camelize.prepended('onEnter', name); + this.lifecycle.onLeave[name] = camelize.prepended('onLeave', name); + this.lifecycle.on[name] = camelize.prepended('on', name); }, addTransition: function(name) { @@ -221,9 +245,9 @@ mixin(Config.prototype, { }, addTransitionLifecycleNames: function(name) { - this.lifecycle.onBefore[name] = camelize('on-before-' + name); - this.lifecycle.onAfter[name] = camelize('on-after-' + name); - this.lifecycle.on[name] = camelize('on-' + name); + this.lifecycle.onBefore[name] = camelize.prepended('onBefore', name); + this.lifecycle.onAfter[name] = camelize.prepended('onAfter', name); + this.lifecycle.on[name] = camelize.prepended('on', name); }, mapTransition: function(transition) { @@ -240,11 +264,11 @@ mixin(Config.prototype, { configureLifecycle: function() { return { - onBefore: { transition: camelize('on-before-transition') }, - onAfter: { transition: camelize('on-after-transition') }, - onEnter: { state: camelize('on-enter-state') }, - onLeave: { state: camelize('on-leave-state') }, - on: { transition: camelize('on-transition') } + onBefore: { transition: 'onBeforeTransition' }, + onAfter: { transition: 'onAfterTransition' }, + onEnter: { state: 'onEnterState' }, + onLeave: { state: 'onLeaveState' }, + on: { transition: 'onTransition' } }; }, @@ -327,13 +351,13 @@ module.exports = Config; //------------------------------------------------------------------------------------------------- -/***/ }, +/***/ }), /* 4 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { var mixin = __webpack_require__(0), - Exception = __webpack_require__(5), + Exception = __webpack_require__(6), plugin = __webpack_require__(1), UNOBSERVED = [ null, [] ]; @@ -441,6 +465,7 @@ mixin(JSM.prototype, { beginTransit: function() { this.pending = true; }, endTransit: function(result) { this.pending = false; return result; }, + failTransit: function(result) { this.pending = false; throw result; }, doTransit: function(lifecycle) { this.state = lifecycle.to; }, observe: function(args) { @@ -464,9 +489,9 @@ mixin(JSM.prototype, { return [ event, result, true ] }, - observeEvents: function(events, args, previousEvent) { + observeEvents: function(events, args, previousEvent, previousResult) { if (events.length === 0) { - return this.endTransit(true); + return this.endTransit(previousResult === undefined ? true : previousResult); } var event = events[0][0], @@ -479,20 +504,20 @@ mixin(JSM.prototype, { if (observers.length === 0) { events.shift(); - return this.observeEvents(events, args, event); + return this.observeEvents(events, args, event, previousResult); } else { var observer = observers.shift(), result = observer[event].apply(observer, args); if (result && typeof result.then === 'function') { return result.then(this.observeEvents.bind(this, events, args, event)) - .catch(this.endTransit.bind(this)) + .catch(this.failTransit.bind(this)) } else if (result === false) { return this.endTransit(false); } else { - return this.observeEvents(events, args, event); + return this.observeEvents(events, args, event, result); } } }, @@ -514,25 +539,9 @@ module.exports = JSM; //------------------------------------------------------------------------------------------------- -/***/ }, +/***/ }), /* 5 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = function(message, transition, from, to, current) { - this.message = message; - this.transition = transition; - this.from = from; - this.to = to; - this.current = current; -} - - -/***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -623,7 +632,7 @@ function build(target, config) { //----------------------------------------------------------------------------------------------- -StateMachine.version = '3.0.0-rc.1'; +StateMachine.version = '3.0.1'; StateMachine.factory = factory; StateMachine.apply = apply; StateMachine.defaults = { @@ -639,6 +648,22 @@ StateMachine.defaults = { module.exports = StateMachine; -/***/ } +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function(message, transition, from, to, current) { + this.message = message; + this.transition = transition; + this.from = from; + this.to = to; + this.current = current; +} + + +/***/ }) /******/ ]); }); \ No newline at end of file diff --git a/dist/state-machine.min.js b/dist/state-machine.min.js index 38f2d60..b9439bc 100644 --- a/dist/state-machine.min.js +++ b/dist/state-machine.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachine",[],n):"object"==typeof exports?exports.StateMachine=n():t.StateMachine=n()}(this,function(){return function(t){function n(e){if(i[e])return i[e].exports;var s=i[e]={i:e,l:!1,exports:{}};return t[e].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var i={};return n.m=t,n.c=i,n.i=function(t){return t},n.d=function(t,i,e){n.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(i,"a",i),i},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=6)}([function(t,n,i){"use strict";t.exports=function(t,n){var i,e,s;for(i=1;i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=this.config.options.observeUnchangedState||n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=this.config.options.observeUnchangedState||n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},failTransit:function(t){throw this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i { - t.is(StateMachine.version, '3.0.0-rc.1'); + t.is(StateMachine.version, '3.0.1'); }); //------------------------------------------------------------------------------------------------- From 93258af7b8fb0a4cd6fff0b478abadfb28d8492a Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sat, 10 Jun 2017 15:58:16 -0700 Subject: [PATCH 48/53] added link to plasso purchase page for commercial license --- docs/commercial-license.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/commercial-license.md b/docs/commercial-license.md index af8b6cd..3dbf474 100644 --- a/docs/commercial-license.md +++ b/docs/commercial-license.md @@ -16,9 +16,10 @@ licensed versions. The commercial license allows for commercial use and provides ## PURCHASE NOW -A commercial license purchasing page will be available soon. +A commercial license can be [purchased here](https://plasso.com/s/TrSu29woZU). You will receive +your license details via email within 48 hours of purchase. -Please email [jake@codeincomplete.com](mailto:jake@codeincomplete.com) for more details. +Please contact [jake@codeincomplete.com](mailto:jake@codeincomplete.com) if you have any questions. ## Commercial License Summary From e05b94f5c3357407c56de98d923dadc8e871f2f1 Mon Sep 17 00:00:00 2001 From: Conor Gilsenan Date: Tue, 24 Oct 2017 13:02:17 -0400 Subject: [PATCH 49/53] Typo vaporise/vaporize The demo errors because the state name is misspelled. --- docs/states-and-transitions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/states-and-transitions.md b/docs/states-and-transitions.md index 3e28413..0581379 100644 --- a/docs/states-and-transitions.md +++ b/docs/states-and-transitions.md @@ -29,7 +29,7 @@ A state machine consists of a set of **states**, e.g: fsm.state; // 'solid' fsm.melt(); fsm.state; // 'liquid' - fsm.vaporise(); + fsm.vaporize(); fsm.state; // 'gas' ``` From 7ae0a4e02e30a2627b357e8e44fbf0c6a871bcb7 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Mon, 2 Apr 2018 09:33:15 -0700 Subject: [PATCH 50/53] Update commercial-license.md --- docs/commercial-license.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/commercial-license.md b/docs/commercial-license.md index 3dbf474..0b4a3cb 100644 --- a/docs/commercial-license.md +++ b/docs/commercial-license.md @@ -16,8 +16,7 @@ licensed versions. The commercial license allows for commercial use and provides ## PURCHASE NOW -A commercial license can be [purchased here](https://plasso.com/s/TrSu29woZU). You will receive -your license details via email within 48 hours of purchase. +A commercial license ~~can be purchased here~~ is no longer available. Please contact [jake@codeincomplete.com](mailto:jake@codeincomplete.com) if you have any questions. From bfee5d404e49e23e22a969375e4e030c0baea291 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 12 Jul 2018 07:28:44 -0700 Subject: [PATCH 51/53] remove commercial license option and go back to MIT license --- LICENSE | 24 +- README.md | 5 +- RELEASE_NOTES.md | 5 + docs/commercial-license.md | 180 --- package-lock.json | 2914 +++++++++++++++++++++++++++++++----- package.json | 4 +- 6 files changed, 2543 insertions(+), 589 deletions(-) delete mode 100644 docs/commercial-license.md diff --git a/LICENSE b/LICENSE index f4b0142..b01dd40 100644 --- a/LICENSE +++ b/LICENSE @@ -1,10 +1,20 @@ -Copyright (c) Jake Gordon +Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017, 2018, Jake Gordon and contributors -"javascript-state-machine" is dual-licensed: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - * "javascript-state-machine" is available as an Open Source project licensed under the terms - of the LGPLv3 license. Please see - for license text. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - * "javascript-state-machine" is also available under a commercial license (with support). Please - read docs/commercial-license.md and contact jake@codeincomplete.com for more details. diff --git a/README.md b/README.md index bd46ea3..5cba155 100644 --- a/README.md +++ b/README.md @@ -133,16 +133,13 @@ Read more about You can [Contribute](docs/contributing.md) to this project with issues or pull requests. -You might also want to support this project by purchasing a [commercial license](docs/commercial-license.md). - # Release Notes See [RELEASE NOTES](RELEASE_NOTES.md) file. # License -Dual-licensed under the [LGPL](http://www.gnu.org/licenses/lgpl-3.0.html) for the open source community and also available with support -under a [commercial license](docs/commercial-license.md). +See [MIT LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE) file. # Contact diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6ada814..0527d19 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,8 @@ +Version 3.1.0 (July 12th 2018) +------------------------------ + + * Changed back to MIT license + Version 3.0.1 (June 10th 2017) ------------------------------ diff --git a/docs/commercial-license.md b/docs/commercial-license.md deleted file mode 100644 index 0b4a3cb..0000000 --- a/docs/commercial-license.md +++ /dev/null @@ -1,180 +0,0 @@ -# Javascript State Machine Commercial License - -All `javascript-state-machine` features are available in both the open source and the commercially -licensed versions. The commercial license allows for commercial use and provides priority support. - -| | Open Source | | Commercial License | -|--------------------------|---------------|---|-----------------------------| -| All Existing v2 Features | ✔ | | ✔ | -| Promise-based Async | ✔ | | ✔ | -| Observable Transitions | ✔ | | ✔ | -| Conditional Transitions | ✔ | | ✔ | -| State History | ✔ | | ✔ | -| Support | Github Issues | | **Priority Email (1 year)** | -| License | LGPL | | **Commercial** | -| Price | Free | | **$149** | - -## PURCHASE NOW - -A commercial license ~~can be purchased here~~ is no longer available. - -Please contact [jake@codeincomplete.com](mailto:jake@codeincomplete.com) if you have any questions. - -## Commercial License Summary - - * License does not expire - * Commercial use allowed - * Can be used for unlimited projects - * Can modify source-code but cannot distribute modifications (derivative works) - * Email support provided for 1 year (from time of purchase) - -## Commercial License Example - - - Javascript State Machine - Terms and Conditions. - - 1. Preamble. - - This Agreement, signed on [DATE] (hereinafter: Effective Date) governs the relationship - between [COMPANY], a Business Entity, (hereinafter: Licensee) and - Jake Gordon, a private person (hereinafter: Licensor). This Agreement sets the terms, - rights, restrictions and obligations on using Javascript State Machine - (hereinafter: The Software) created and owned by Licensor, as detailed herein - - 2. License Grant. - - Licensor hereby grants Licensee a Personal, Non-assignable & non-transferable, Perpetual, - Commercial, Royalty free, Including the rights to create but not distribute derivative - works, Non-exclusive license, all with accordance with the terms set forth and other legal - restrictions set forth in 3rd party software used while running Software. - - 2.1. Limited: Licensee may use Software for the purpose of: - - 2.1.1. Running Software on Licensee’s Website[s] and Server[s]; - 2.1.2. Allowing 3rd Parties to run Software on Licensee’s Website[s] and Server[s]; - 2.1.3. Publishing Software’s output to Licensee and 3rd Parties; - 2.1.4. Distribute verbatim copies of Software’s output (including compiled binaries); - 2.1.5. Modify Software to suit Licensee’s needs and specifications. - - 2.2. This license is granted perpetually, as long as you do not materially breach it. - 2.3. Binary Restricted: Licensee may sublicense Software as a part of a larger work - containing more than Software, distributed solely in Object or Binary form under a - personal, non-sublicensable, limited license. Such redistribution shall be limited - to unlimited codebases. - 2.4. Non Assignable & Non-Transferable: Licensee may not assign or transfer his rights - and duties under this license. - 2.5. Commercial, Royalty Free: Licensee may use Software for any purpose, including - paid-services, without any royalties - 2.6. Including the Right to Create Derivative Works: Licensee may create derivative works - based on Software, including amending Software’s source code, modifying it, integrating - it into a larger work or removing portions of Software, as long as no distribution of - the derivative works is made - 2.7. With support & maintenance: Licensor shall provide Licensee support and maintenance as follows - - - 1 year (from time of purchase) email support with 48hr response time - - 3. Term & Termination: The Term of this license shall be until terminated. Licensor may - terminate this Agreement, including Licensee’s license in the case where Licensee: - - 3.1. became insolvent or otherwise entered into any liquidation process; or - 3.2. exported The Software to any jurisdiction where licensor may not enforce his - rights under this agreements in; or - 3.3. Licensee was in breach of any of this license's terms and conditions and such - breach was not cured, immediately upon notification; or - 3.4. Licensee in breach of any of the terms of clause 2 to this license; or - 3.5. Licensee otherwise entered into any arrangement which caused Licensor to be - unable to enforce his rights under this License. - - 4. Payment: In consideration of the License granted under clause 2, Licensee shall pay - Licensor a fee, via Credit-Card, PayPal or any other mean which Licensor may deem - adequate. Failure to perform payment shall construe as material breach of this Agreement. - - 5. Upgrades, Updates and Fixes: Licensor may provide Licensee, from time to time, with - Upgrades, Updates or Fixes, as detailed herein and according to his sole discretion. - Licensee hereby warrants to keep The Software up-to-date and install all relevant - updates and fixes, and may, at his sole discretion, purchase upgrades, according to - the rates set by Licensor. Licensor shall provide any update or Fix free of charge; - however, nothing in this Agreement shall require Licensor to provide Updates or Fixes. - - 5.1. Upgrades: for the purpose of this license, an Upgrade shall be a material amendment - in The Software, which contains new features and or major performance improvements - and shall be marked as a new version number. For example, should Licensee purchase - The Software under version 1.X.X, an upgrade shall commence under number 2.0.0. - 5.2. Updates: for the purpose of this license, an update shall be a minor amendment in The - Software, which may contain new features or minor improvements and shall be marked as - a new sub-version number. For example, should Licensee purchase The Software under - version 1.1.X, an upgrade shall commence under number 1.2.0. - 5.3. Fix: for the purpose of this license, a fix shall be a minor amendment in The - Software, intended to remove bugs or alter minor features which impair the The - Software's functionality. A fix shall be marked as a new sub-sub-version number. - For example, should Licensee purchase Software under version 1.1.1, an upgrade - shall commence under number 1.1.2. - - 6. Support: Software is provided with limited support, as detailed in the Software’s SLA - detailed under the License Grant. Licensor shall provide support via electronic mail - and on regular business days and hours. - - 6.1. Bug Notification: Licensee may provide Licensor of details regarding any bug, - defect or failure in The Software promptly and with no delay from such event; - Licensee shall comply with Licensor's request for information regarding bugs, - defects or failures and furnish him with information, screenshots and try to - reproduce such bugs, defects or failures. - 6.2. Feature Request: Licensee may request additional features in Software, provided, - however, that (i) Licensee shall waive any claim or right in such feature should - feature be developed by Licensor; (ii) Licensee shall be prohibited from developing - the feature, or disclose such feature request, or feature, to any 3rd party directly - competing with Licensor or any 3rd party which may be, following the development - of such feature, in direct competition with Licensor; (iii) Licensee warrants that - feature does not infringe any 3rd party patent, trademark, trade-secret or any - other intellectual property right; and (iv) Licensee developed, envisioned or - created the feature solely by himself. - - 7. Liability: To the extent permitted under Law, The Software is provided under an - AS-IS basis. Licensor shall never, and without any limit, be liable for any damage, - cost, expense or any other payment incurred by Licensee as a result of Software’s - actions, failure, bugs and/or any other interaction between The Software and - Licensee’s end-equipment, computers, other software or any 3rd party, end-equipment, - computer or services. Moreover, Licensor shall never be liable for any defect in - source code written by Licensee when relying on The Software or using The Software’s - source code. - - 8. Warranty: - 8.1. Intellectual Property: Licensor hereby warrants that The Software does not violate - or infringe any 3rd party claims in regards to intellectual property, patents and/or - trademarks and that to the best of its knowledge no legal action has been taken - against it for any infringement or violation of any 3rd party intellectual - property rights. - 8.2. No-Warranty: The Software is provided without any warranty; Licensor hereby - disclaims any warranty that The Software shall be error free, without defects - or code which may cause damage to Licensee’s computers or to Licensee, and - that Software shall be functional. Licensee shall be solely liable to any - damage, defect or loss incurred as a result of operating software and undertake - the risks contained in running The Software on License’s Server[s] and Website[s]. - 8.3. Prior Inspection: Licensee hereby states that he inspected The Software thoroughly - and found it satisfactory and adequate to his needs, that it does not interfere - with his regular operation and that it does meet the standards and scope of his - computer systems and architecture. Licensee found that The Software interacts with - his development, website and server environment and that it does not infringe any of - End User License Agreement of any software Licensee may use in performing his - services. Licensee hereby waives any claims regarding The Software's - incompatibility, performance, results and features, and warrants that he - inspected the The Software. - - 9. No Refunds: Licensee warrants that he inspected The Software according to - clause 7(c) and that it is adequate to his needs. Accordingly, as The Software - is intangible goods, Licensee shall not be, ever, entitled to any refund, rebate, - compensation or restitution for any reason whatsoever, even if The Software - contains material flaws. - - 10. Indemnification: Licensee hereby warrants to hold Licensor harmless and indemnify - Licensor for any lawsuit brought against it in regards to Licensee’s use of The - Software in means that violate, breach or otherwise circumvent this license, - Licensor's intellectual property rights or Licensor's title in The Software. - Licensor shall promptly notify Licensee in case of such legal action and request - Licensee’s consent prior to any settlement in relation to such lawsuit or claim. - - 11. Governing Law, Jurisdiction: Licensee hereby agrees not to initiate class-action - lawsuits against Licensor in relation to this license and to compensate Licensor - for any legal fees, cost or attorney fees should any claim brought by Licensee - against Licensor be denied, in part or in full. - diff --git a/package-lock.json b/package-lock.json index 511a15c..b860621 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,8 @@ { "name": "javascript-state-machine", - "version": "3.0.1", + "version": "3.1.0", "lockfileVersion": 1, + "requires": true, "dependencies": { "acorn": { "version": "5.0.3", @@ -14,6 +15,9 @@ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", "dev": true, + "requires": { + "acorn": "4.0.13" + }, "dependencies": { "acorn": { "version": "4.0.13", @@ -27,7 +31,11 @@ "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } }, "ajv-keywords": { "version": "1.5.1", @@ -39,13 +47,21 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } }, "ansi-align": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2" + } }, "ansi-regex": { "version": "2.1.1", @@ -63,13 +79,20 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", - "dev": true + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11" + } }, "arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true + "dev": true, + "requires": { + "arr-flatten": "1.0.3" + } }, "arr-exclude": { "version": "1.0.0", @@ -99,7 +122,10 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } }, "array-uniq": { "version": "1.0.3", @@ -123,19 +149,30 @@ "version": "4.9.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } }, "assert": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true + "dev": true, + "requires": { + "util": "0.10.3" + } }, "async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/async/-/async-2.4.1.tgz", "integrity": "sha1-YqVrJ5yYoR0JhwlqAcw+6463u9c=", - "dev": true + "dev": true, + "requires": { + "lodash": "4.17.4" + } }, "async-each": { "version": "1.0.1", @@ -153,139 +190,355 @@ "version": "0.17.0", "resolved": "https://registry.npmjs.org/ava/-/ava-0.17.0.tgz", "integrity": "sha1-NZ4qiWFoAe8Dkpw88QqdT45FHQI=", - "dev": true + "dev": true, + "requires": { + "arr-flatten": "1.0.3", + "array-union": "1.0.2", + "array-uniq": "1.0.3", + "arrify": "1.0.1", + "auto-bind": "0.1.0", + "ava-files": "0.2.0", + "ava-init": "0.1.6", + "babel-code-frame": "6.22.0", + "babel-core": "6.25.0", + "babel-plugin-ava-throws-helper": "0.1.0", + "babel-plugin-detective": "2.0.0", + "babel-plugin-espower": "2.3.2", + "babel-plugin-transform-runtime": "6.23.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-es2015-node4": "2.1.1", + "babel-preset-stage-2": "6.24.1", + "babel-runtime": "6.23.0", + "bluebird": "3.5.0", + "caching-transform": "1.0.1", + "chalk": "1.1.3", + "chokidar": "1.7.0", + "clean-yaml-object": "0.1.0", + "cli-cursor": "1.0.2", + "cli-spinners": "0.1.2", + "cli-truncate": "0.2.1", + "co-with-promise": "4.6.0", + "common-path-prefix": "1.0.0", + "convert-source-map": "1.5.0", + "core-assert": "0.2.1", + "currently-unhandled": "0.4.1", + "debug": "2.6.8", + "empower-core": "0.6.2", + "figures": "1.7.0", + "find-cache-dir": "0.1.1", + "fn-name": "2.0.1", + "get-port": "2.1.0", + "has-flag": "2.0.0", + "ignore-by-default": "1.0.1", + "is-ci": "1.0.10", + "is-generator-fn": "1.0.0", + "is-obj": "1.0.1", + "is-observable": "0.2.0", + "is-promise": "2.1.0", + "last-line-stream": "1.0.0", + "lodash.debounce": "4.0.8", + "lodash.difference": "4.5.0", + "lodash.isequal": "4.5.0", + "loud-rejection": "1.6.0", + "matcher": "0.1.2", + "max-timeout": "1.0.0", + "md5-hex": "1.3.0", + "meow": "3.7.0", + "ms": "0.7.3", + "object-assign": "4.1.1", + "observable-to-promise": "0.4.0", + "option-chain": "0.1.1", + "package-hash": "1.2.0", + "pkg-conf": "1.1.3", + "plur": "2.1.2", + "power-assert-context-formatter": "1.1.1", + "power-assert-renderer-assertion": "1.1.1", + "power-assert-renderer-succinct": "1.1.1", + "pretty-ms": "2.1.0", + "repeating": "2.0.1", + "require-precompiled": "0.1.0", + "resolve-cwd": "1.0.0", + "semver": "5.3.0", + "set-immediate-shim": "1.0.1", + "source-map-support": "0.4.15", + "stack-utils": "0.4.0", + "strip-ansi": "3.0.1", + "strip-bom": "2.0.0", + "time-require": "0.1.2", + "unique-temp-dir": "1.0.0", + "update-notifier": "1.0.3" + } }, "ava-files": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ava-files/-/ava-files-0.2.0.tgz", "integrity": "sha1-x7i24uDOpjtXpuJ+DbFFx8Gc/iA=", - "dev": true + "dev": true, + "requires": { + "auto-bind": "0.1.0", + "bluebird": "3.5.0", + "globby": "6.1.0", + "ignore-by-default": "1.0.1", + "lodash.flatten": "4.4.0", + "multimatch": "2.1.0", + "slash": "1.0.0" + } }, "ava-init": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ava-init/-/ava-init-0.1.6.tgz", "integrity": "sha1-7xntCyS2vzWdrW+63xoF2DY5XJE=", - "dev": true + "dev": true, + "requires": { + "arr-exclude": "1.0.0", + "cross-spawn": "4.0.2", + "pinkie-promise": "2.0.1", + "read-pkg-up": "1.0.1", + "the-argv": "1.0.0", + "write-pkg": "1.0.0" + } }, "babel-code-frame": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", - "dev": true + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.1" + } }, "babel-core": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", - "dev": true + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" + } }, "babel-generator": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", - "dev": true + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.6", + "trim-right": "1.0.1" + } }, "babel-helper-bindify-decorators": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-define-map": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", - "dev": true + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } }, "babel-helper-explode-assignable-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-explode-class": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", - "dev": true + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-get-function-arity": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-helper-hoist-variables": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-helper-optimise-call-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-helper-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } }, "babel-helper-remap-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helper-replace-supers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-ava-throws-helper": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-ava-throws-helper/-/babel-plugin-ava-throws-helper-0.1.0.tgz", "integrity": "sha1-lREHcIoSIIAmv4ykzvGKh7ybDP4=", - "dev": true + "dev": true, + "requires": { + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-detective": { "version": "2.0.0", @@ -297,7 +550,16 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", - "dev": true + "dev": true, + "requires": { + "babel-generator": "6.25.0", + "babylon": "6.17.3", + "call-matcher": "1.0.1", + "core-js": "2.4.1", + "espower-location-detector": "1.0.0", + "espurify": "1.7.0", + "estraverse": "4.2.0" + } }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", @@ -351,241 +613,471 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", - "dev": true + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-generators": "6.13.0", + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-class-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "dev": true + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-plugin-transform-decorators": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", - "dev": true + "dev": true, + "requires": { + "babel-helper-explode-class": "6.24.1", + "babel-plugin-syntax-decorators": "6.13.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-block-scoping": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" + } }, "babel-plugin-transform-es2015-classes": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true + "dev": true, + "requires": { + "babel-helper-define-map": "6.24.1", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-computed-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-for-of": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-plugin-transform-es2015-modules-commonjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" + } }, "babel-plugin-transform-es2015-object-super": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-parameters": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-spread": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true + "dev": true, + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true + "dev": true, + "requires": { + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "regexpu-core": "2.0.0" + } }, "babel-plugin-transform-exponentiation-operator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-object-rest-spread": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-regenerator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", - "dev": true + "dev": true, + "requires": { + "regenerator-transform": "0.9.11" + } }, "babel-plugin-transform-runtime": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" + } }, "babel-preset-es2015": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1" + } }, "babel-preset-es2015-node4": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015-node4/-/babel-preset-es2015-node4-2.1.1.tgz", "integrity": "sha1-4x8pCFm1hhnIz6JB0bC8kA+UHNs=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1" + } }, "babel-preset-stage-2": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-decorators": "6.24.1", + "babel-preset-stage-3": "6.24.1" + } }, "babel-preset-stage-3": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", - "dev": true + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-generator-functions": "6.24.1", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-object-rest-spread": "6.23.0" + } }, "babel-register": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true + "dev": true, + "requires": { + "babel-core": "6.25.0", + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" + } }, "babel-runtime": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } }, "babel-template": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "lodash": "4.17.4" + } }, "babel-traverse": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", - "dev": true + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "debug": "2.6.8", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } }, "babel-types": { "version": "6.25.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } }, "babylon": { "version": "6.17.3", @@ -633,19 +1125,39 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=", - "dev": true + "dev": true, + "requires": { + "ansi-align": "1.1.0", + "camelcase": "2.1.1", + "chalk": "1.1.3", + "cli-boxes": "1.0.0", + "filled-array": "1.1.0", + "object-assign": "4.1.1", + "repeating": "2.0.1", + "string-width": "1.0.2", + "widest-line": "1.0.0" + } }, "brace-expansion": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", - "dev": true + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } }, "braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } }, "brorand": { "version": "1.1.0", @@ -657,37 +1169,70 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", - "dev": true + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.3", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.0", + "inherits": "2.0.3" + } }, "browserify-cipher": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", - "dev": true + "dev": true, + "requires": { + "browserify-aes": "1.0.6", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.0" + } }, "browserify-des": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", - "dev": true + "dev": true, + "requires": { + "cipher-base": "1.0.3", + "des.js": "1.0.0", + "inherits": "2.0.3" + } }, "browserify-rsa": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "randombytes": "2.0.5" + } }, "browserify-sign": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } }, "browserify-zlib": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", - "dev": true + "dev": true, + "requires": { + "pako": "0.2.9" + } }, "buf-compare": { "version": "1.0.1", @@ -699,7 +1244,12 @@ "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true + "dev": true, + "requires": { + "base64-js": "1.2.0", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } }, "buffer-xor": { "version": "1.0.3", @@ -723,13 +1273,24 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", - "dev": true + "dev": true, + "requires": { + "md5-hex": "1.3.0", + "mkdirp": "0.5.1", + "write-file-atomic": "1.3.4" + } }, "call-matcher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "deep-equal": "1.0.1", + "espurify": "1.7.0", + "estraverse": "4.2.0" + } }, "call-signature": { "version": "0.0.2", @@ -741,7 +1302,11 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true + "dev": true, + "requires": { + "no-case": "2.3.1", + "upper-case": "1.1.3" + } }, "camelcase": { "version": "2.1.1", @@ -753,7 +1318,11 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } }, "capture-stack-trace": { "version": "1.0.0", @@ -765,19 +1334,41 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true + "dev": true, + "requires": { + "anymatch": "1.3.0", + "async-each": "1.0.1", + "fsevents": "1.1.1", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } }, "ci-info": { "version": "1.0.0", @@ -789,7 +1380,10 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", "integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3" + } }, "clean-yaml-object": { "version": "0.1.0", @@ -807,7 +1401,10 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } }, "cli-spinners": { "version": "0.1.2", @@ -819,13 +1416,22 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "1.0.2" + } }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } }, "co": { "version": "4.6.0", @@ -838,6 +1444,9 @@ "resolved": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", "dev": true, + "requires": { + "pinkie-promise": "1.0.0" + }, "dependencies": { "pinkie": { "version": "1.0.0", @@ -849,7 +1458,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", - "dev": true + "dev": true, + "requires": { + "pinkie": "1.0.0" + } } } }, @@ -881,13 +1493,27 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", - "dev": true + "dev": true, + "requires": { + "dot-prop": "3.0.0", + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "os-tmpdir": "1.0.2", + "osenv": "0.1.4", + "uuid": "2.0.3", + "write-file-atomic": "1.3.4", + "xdg-basedir": "2.0.0" + } }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true + "dev": true, + "requires": { + "date-now": "0.1.4" + } }, "constants-browserify": { "version": "1.0.0", @@ -905,7 +1531,11 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", - "dev": true + "dev": true, + "requires": { + "buf-compare": "1.0.1", + "is-error": "2.2.1" + } }, "core-js": { "version": "2.4.1", @@ -923,43 +1553,83 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "elliptic": "6.4.0" + } }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true + "dev": true, + "requires": { + "capture-stack-trace": "1.0.0" + } }, "create-hash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", - "dev": true + "dev": true, + "requires": { + "cipher-base": "1.0.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.8" + } }, "create-hmac": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", - "dev": true + "dev": true, + "requires": { + "cipher-base": "1.0.3", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.0.1", + "sha.js": "2.4.8" + } }, "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true + "dev": true, + "requires": { + "lru-cache": "4.1.0", + "which": "1.2.14" + } }, "crypto-browserify": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", "integrity": "sha1-NlKgkGq5sqfgw85mpAjpV6JIVSI=", - "dev": true + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.12", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5" + } }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } }, "date-now": { "version": "0.1.4", @@ -978,6 +1648,9 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "dev": true, + "requires": { + "ms": "2.0.0" + }, "dependencies": { "ms": { "version": "2.0.0", @@ -1009,19 +1682,31 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true + "dev": true, + "requires": { + "repeating": "2.0.1" + } }, "diffie-hellman": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "miller-rabin": "4.0.0", + "randombytes": "2.0.5" + } }, "domain-browser": { "version": "1.1.7", @@ -1033,13 +1718,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", - "dev": true + "dev": true, + "requires": { + "is-obj": "1.0.1" + } }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true + "dev": true, + "requires": { + "readable-stream": "2.2.11" + } }, "eastasianwidth": { "version": "0.1.1", @@ -1051,7 +1742,16 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "brorand": "1.1.0", + "hash.js": "1.0.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } }, "emojis-list": { "version": "2.1.0", @@ -1063,25 +1763,41 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz", "integrity": "sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ=", - "dev": true + "dev": true, + "requires": { + "call-signature": "0.0.2", + "core-js": "2.4.1" + } }, "enhanced-resolve": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz", "integrity": "sha1-n0tib1dyRe3PSyrYPYbhf09CHew=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.6" + } }, "errno": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", - "dev": true + "dev": true, + "requires": { + "prr": "0.0.0" + } }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } }, "escape-string-regexp": { "version": "1.0.5", @@ -1093,13 +1809,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", - "dev": true + "dev": true, + "requires": { + "is-url": "1.2.2", + "path-is-absolute": "1.0.1", + "source-map": "0.5.6", + "xtend": "4.0.1" + } }, "espurify": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1" + } }, "estraverse": { "version": "4.2.0", @@ -1123,7 +1848,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", - "dev": true + "dev": true, + "requires": { + "create-hash": "1.1.3" + } }, "exit-hook": { "version": "1.1.1", @@ -1135,25 +1863,38 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } }, "expand-range": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true + "dev": true, + "requires": { + "fill-range": "2.2.3" + } }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } }, "filename-regex": { "version": "2.0.1", @@ -1165,7 +1906,14 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } }, "filled-array": { "version": "1.1.0", @@ -1177,13 +1925,22 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } }, "fn-name": { "version": "2.0.1", @@ -1201,13 +1958,23 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true + "dev": true, + "requires": { + "for-in": "1.0.2" + } }, "fs-sync": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/fs-sync/-/fs-sync-1.0.4.tgz", "integrity": "sha1-L5Tq3jGGLsCp8zocJUbfsaPz0a4=", - "dev": true + "dev": true, + "requires": { + "glob": "7.1.2", + "iconv-lite": "0.4.17", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } }, "fs.realpath": { "version": "1.0.0", @@ -1221,6 +1988,10 @@ "integrity": "sha1-8Z/Sj0Pur3YWgOUZogPE0LPTGv8=", "dev": true, "optional": true, + "requires": { + "nan": "2.6.2", + "node-pre-gyp": "0.6.33" + }, "dependencies": { "abbrev": { "version": "1.1.0", @@ -1249,7 +2020,11 @@ "version": "1.1.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.2" + } }, "asn1": { "version": "0.2.3", @@ -1290,22 +2065,35 @@ "version": "1.0.1", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } }, "block-stream": { "version": "0.0.9", "bundled": true, - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3" + } }, "boom": { "version": "2.10.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "hoek": "2.16.3" + } }, "brace-expansion": { "version": "1.1.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } }, "buffer-shims": { "version": "1.0.0", @@ -1322,7 +2110,14 @@ "version": "1.1.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } }, "code-point-at": { "version": "1.1.0", @@ -1332,13 +2127,19 @@ "combined-stream": { "version": "1.0.5", "bundled": true, - "dev": true + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } }, "commander": { "version": "2.9.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "graceful-readlink": "1.0.1" + } }, "concat-map": { "version": "0.0.1", @@ -1359,13 +2160,19 @@ "version": "2.0.5", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "boom": "2.10.1" + } }, "dashdash": { "version": "1.14.1", "bundled": true, "dev": true, "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, "dependencies": { "assert-plus": { "version": "1.0.0", @@ -1379,7 +2186,10 @@ "version": "2.2.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "ms": "0.7.1" + } }, "deep-extend": { "version": "0.4.1", @@ -1402,7 +2212,10 @@ "version": "0.1.1", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "jsbn": "0.1.1" + } }, "escape-string-regexp": { "version": "1.0.5", @@ -1431,7 +2244,12 @@ "version": "2.1.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.14" + } }, "fs.realpath": { "version": "1.0.0", @@ -1441,19 +2259,40 @@ "fstream": { "version": "1.0.10", "bundled": true, - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.5.4" + } }, "fstream-ignore": { "version": "1.0.5", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "fstream": "1.0.10", + "inherits": "2.0.3", + "minimatch": "3.0.3" + } }, "gauge": { "version": "2.7.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.0" + } }, "generate-function": { "version": "2.0.0", @@ -1465,13 +2304,19 @@ "version": "1.2.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "is-property": "1.0.2" + } }, "getpass": { "version": "0.1.6", "bundled": true, "dev": true, "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, "dependencies": { "assert-plus": { "version": "1.0.0", @@ -1484,7 +2329,15 @@ "glob": { "version": "7.1.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } }, "graceful-fs": { "version": "4.1.11", @@ -1501,13 +2354,22 @@ "version": "2.0.6", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.9.0", + "is-my-json-valid": "2.15.0", + "pinkie-promise": "2.0.1" + } }, "has-ansi": { "version": "2.0.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "has-unicode": { "version": "2.0.1", @@ -1519,7 +2381,13 @@ "version": "3.1.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } }, "hoek": { "version": "2.16.3", @@ -1530,12 +2398,21 @@ "version": "1.1.1", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.3.1", + "sshpk": "1.10.2" + } }, "inflight": { "version": "1.0.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } }, "inherits": { "version": "2.0.3", @@ -1551,13 +2428,22 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } }, "is-my-json-valid": { "version": "2.15.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } }, "is-property": { "version": "1.0.2", @@ -1586,7 +2472,10 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "jsbn": "0.1.1" + } }, "jsbn": { "version": "0.1.1", @@ -1616,7 +2505,12 @@ "version": "1.3.1", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + } }, "mime-db": { "version": "1.26.0", @@ -1626,12 +2520,18 @@ "mime-types": { "version": "2.1.14", "bundled": true, - "dev": true + "dev": true, + "requires": { + "mime-db": "1.26.0" + } }, "minimatch": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "brace-expansion": "1.1.6" + } }, "minimist": { "version": "0.0.8", @@ -1641,7 +2541,10 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "minimist": "0.0.8" + } }, "ms": { "version": "0.7.1", @@ -1653,19 +2556,39 @@ "version": "0.6.33", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.0.2", + "rc": "1.1.7", + "request": "2.79.0", + "rimraf": "2.5.4", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.3.0" + } }, "nopt": { "version": "3.0.6", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "abbrev": "1.1.0" + } }, "npmlog": { "version": "4.0.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "are-we-there-yet": "1.1.2", + "console-control-strings": "1.1.0", + "gauge": "2.7.3", + "set-blocking": "2.0.0" + } }, "number-is-nan": { "version": "1.0.1", @@ -1687,7 +2610,10 @@ "once": { "version": "1.4.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "wrappy": "1.0.2" + } }, "path-is-absolute": { "version": "1.0.1", @@ -1704,7 +2630,10 @@ "version": "2.0.1", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "pinkie": "2.0.4" + } }, "process-nextick-args": { "version": "1.0.7", @@ -1728,6 +2657,12 @@ "bundled": true, "dev": true, "optional": true, + "requires": { + "deep-extend": "0.4.1", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, "dependencies": { "minimist": { "version": "1.2.0", @@ -1741,18 +2676,52 @@ "version": "2.2.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } }, "request": { "version": "2.79.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.0", + "forever-agent": "0.6.1", + "form-data": "2.1.2", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.14", + "oauth-sign": "0.8.2", + "qs": "6.3.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.0.1" + } }, "rimraf": { "version": "2.5.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "glob": "7.1.1" + } }, "semver": { "version": "5.3.0", @@ -1776,13 +2745,27 @@ "version": "1.0.9", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "hoek": "2.16.3" + } }, "sshpk": { "version": "1.10.2", "bundled": true, "dev": true, "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.6", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, "dependencies": { "assert-plus": { "version": "1.0.0", @@ -1792,14 +2775,19 @@ } } }, - "string_decoder": { - "version": "0.10.31", - "bundled": true, - "dev": true - }, "string-width": { "version": "1.0.2", "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, "dev": true }, "stringstream": { @@ -1811,7 +2799,10 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "strip-json-comments": { "version": "2.0.1", @@ -1828,25 +2819,52 @@ "tar": { "version": "2.2.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.10", + "inherits": "2.0.3" + } }, "tar-pack": { "version": "3.3.0", "bundled": true, "dev": true, "optional": true, + "requires": { + "debug": "2.2.0", + "fstream": "1.0.10", + "fstream-ignore": "1.0.5", + "once": "1.3.3", + "readable-stream": "2.1.5", + "rimraf": "2.5.4", + "tar": "2.2.1", + "uid-number": "0.0.6" + }, "dependencies": { "once": { "version": "1.3.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "wrappy": "1.0.2" + } }, "readable-stream": { "version": "2.1.5", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } } } }, @@ -1854,7 +2872,10 @@ "version": "2.3.2", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "punycode": "1.4.1" + } }, "tunnel-agent": { "version": "0.4.3", @@ -1889,13 +2910,19 @@ "version": "1.3.6", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } }, "wide-align": { "version": "1.1.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "string-width": "1.0.2" + } }, "wrappy": { "version": "1.0.2", @@ -1920,7 +2947,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", - "dev": true + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } }, "get-stdin": { "version": "4.0.1", @@ -1932,19 +2962,34 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } }, "glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true + "dev": true, + "requires": { + "is-glob": "2.0.1" + } }, "globals": { "version": "9.18.0", @@ -1956,13 +3001,37 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } }, "got": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", - "dev": true + "dev": true, + "requires": { + "create-error-class": "3.0.2", + "duplexer2": "0.1.4", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "node-status-codes": "1.0.0", + "object-assign": "4.1.1", + "parse-json": "2.2.0", + "pinkie-promise": "2.0.1", + "read-all-stream": "3.1.0", + "readable-stream": "2.2.11", + "timed-out": "3.1.3", + "unzip-response": "1.0.2", + "url-parse-lax": "1.0.0" + } }, "graceful-fs": { "version": "4.1.11", @@ -1974,7 +3043,10 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "has-color": { "version": "0.1.7", @@ -1992,25 +3064,40 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3" + } }, "hash.js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", "integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3" + } }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true + "dev": true, + "requires": { + "hash.js": "1.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } }, "hosted-git-info": { "version": "2.4.2", @@ -2052,7 +3139,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true + "dev": true, + "requires": { + "repeating": "2.0.1" + } }, "indexof": { "version": "0.0.1", @@ -2064,7 +3154,11 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } }, "inherits": { "version": "2.0.3", @@ -2088,7 +3182,10 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } }, "invert-kv": { "version": "1.0.0", @@ -2112,7 +3209,10 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true + "dev": true, + "requires": { + "binary-extensions": "1.8.0" + } }, "is-buffer": { "version": "1.1.5", @@ -2124,13 +3224,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } }, "is-ci": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true + "dev": true, + "requires": { + "ci-info": "1.0.0" + } }, "is-dotfile": { "version": "1.0.3", @@ -2142,7 +3248,10 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } }, "is-error": { "version": "2.2.1", @@ -2166,13 +3275,19 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } }, "is-generator-fn": { "version": "1.0.0", @@ -2184,7 +3299,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } }, "is-npm": { "version": "1.0.0", @@ -2196,7 +3314,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true + "dev": true, + "requires": { + "kind-of": "3.2.2" + } }, "is-obj": { "version": "1.0.1", @@ -2208,7 +3329,10 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", - "dev": true + "dev": true, + "requires": { + "symbol-observable": "0.2.4" + } }, "is-plain-obj": { "version": "1.1.0", @@ -2280,7 +3404,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true + "dev": true, + "requires": { + "isarray": "1.0.0" + } }, "js-tokens": { "version": "3.0.1", @@ -2304,7 +3431,10 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true + "dev": true, + "requires": { + "jsonify": "0.0.0" + } }, "json5": { "version": "0.5.1", @@ -2322,19 +3452,28 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } }, "last-line-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", - "dev": true + "dev": true, + "requires": { + "through2": "2.0.3" + } }, "latest-version": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", - "dev": true + "dev": true, + "requires": { + "package-json": "2.4.0" + } }, "lazy-cache": { "version": "1.0.4", @@ -2352,13 +3491,23 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } }, "loader-runner": { "version": "2.3.0", @@ -2370,7 +3519,13 @@ "version": "0.2.17", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true + "dev": true, + "requires": { + "big.js": "3.1.3", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } }, "lodash": { "version": "4.17.4", @@ -2412,13 +3567,20 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true + "dev": true, + "requires": { + "js-tokens": "3.0.1" + } }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } }, "lower-case": { "version": "1.1.4", @@ -2436,7 +3598,11 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.0.tgz", "integrity": "sha512-aHGs865JXz6bkB4AHL+3AhyvTFKL3iZamKVWjIUKnXOXyasJvqPK8WAjOnAQKQZVpeXDVz19u1DD0r/12bWAdQ==", - "dev": true + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } }, "map-obj": { "version": "1.0.1", @@ -2448,7 +3614,10 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/matcher/-/matcher-0.1.2.tgz", "integrity": "sha1-7yDL3mTCTFDMYa9bg+4LG4/wAQE=", - "dev": true + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } }, "max-timeout": { "version": "1.0.0", @@ -2460,7 +3629,10 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true + "dev": true, + "requires": { + "md5-o-matic": "0.1.1" + } }, "md5-o-matic": { "version": "0.1.1", @@ -2472,13 +3644,29 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true + "dev": true, + "requires": { + "errno": "0.1.4", + "readable-stream": "2.2.11" + } }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.8", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, "dependencies": { "minimist": { "version": "1.2.0", @@ -2492,13 +3680,32 @@ "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + } }, "miller-rabin": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "brorand": "1.1.0" + } }, "minimalistic-assert": { "version": "1.0.0", @@ -2516,7 +3723,10 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } }, "minimist": { "version": "0.0.8", @@ -2528,7 +3738,10 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true + "dev": true, + "requires": { + "minimist": "0.0.8" + } }, "ms": { "version": "0.7.3", @@ -2540,7 +3753,13 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + } }, "nan": { "version": "2.6.2", @@ -2553,13 +3772,41 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.1.tgz", "integrity": "sha1-euuhxzpSGEJlVUt9wDuvcg34AIE=", - "dev": true + "dev": true, + "requires": { + "lower-case": "1.1.4" + } }, "node-libs-browser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.1.4", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.0", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "0.0.1", + "os-browserify": "0.2.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.2.11", + "stream-browserify": "2.0.1", + "stream-http": "2.7.1", + "string_decoder": "0.10.31", + "timers-browserify": "2.0.2", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + }, "dependencies": { "string_decoder": { "version": "0.10.31", @@ -2579,13 +3826,22 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", - "dev": true + "dev": true, + "requires": { + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + } }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.2" + } }, "number-is-nan": { "version": "1.0.1", @@ -2598,11 +3854,45 @@ "resolved": "https://registry.npmjs.org/nyc/-/nyc-10.3.2.tgz", "integrity": "sha1-8n9NkfKp2zbCT1dP9cbv/wIz3kY=", "dev": true, + "requires": { + "archy": "1.0.0", + "arrify": "1.0.1", + "caching-transform": "1.0.1", + "convert-source-map": "1.5.0", + "debug-log": "1.0.1", + "default-require-extensions": "1.0.0", + "find-cache-dir": "0.1.1", + "find-up": "1.1.2", + "foreground-child": "1.5.6", + "glob": "7.1.1", + "istanbul-lib-coverage": "1.1.0", + "istanbul-lib-hook": "1.0.6", + "istanbul-lib-instrument": "1.7.1", + "istanbul-lib-report": "1.1.0", + "istanbul-lib-source-maps": "1.2.0", + "istanbul-reports": "1.1.0", + "md5-hex": "1.3.0", + "merge-source-map": "1.0.3", + "micromatch": "2.3.11", + "mkdirp": "0.5.1", + "resolve-from": "2.0.0", + "rimraf": "2.6.1", + "signal-exit": "3.0.2", + "spawn-wrap": "1.2.4", + "test-exclude": "4.1.0", + "yargs": "7.1.0", + "yargs-parser": "5.0.0" + }, "dependencies": { "align-text": { "version": "0.1.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "kind-of": "3.2.0", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } }, "amdefine": { "version": "1.0.1", @@ -2622,7 +3912,10 @@ "append-transform": { "version": "0.4.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } }, "archy": { "version": "1.0.0", @@ -2632,7 +3925,10 @@ "arr-diff": { "version": "2.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "arr-flatten": "1.0.3" + } }, "arr-flatten": { "version": "1.0.3", @@ -2657,37 +3953,83 @@ "babel-code-frame": { "version": "6.22.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.1" + } }, "babel-generator": { "version": "6.24.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.24.1", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.6", + "trim-right": "1.0.1" + } }, "babel-messages": { "version": "6.23.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0" + } }, "babel-runtime": { "version": "6.23.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" + } }, "babel-template": { "version": "6.24.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-traverse": "6.24.1", + "babel-types": "6.24.1", + "babylon": "6.17.0", + "lodash": "4.17.4" + } }, "babel-traverse": { "version": "6.24.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.24.1", + "babylon": "6.17.0", + "debug": "2.6.6", + "globals": "9.17.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } }, "babel-types": { "version": "6.24.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } }, "babylon": { "version": "6.17.0", @@ -2702,12 +4044,21 @@ "brace-expansion": { "version": "1.1.7", "bundled": true, - "dev": true + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } }, "braces": { "version": "1.8.5", "bundled": true, - "dev": true + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } }, "builtin-modules": { "version": "1.1.1", @@ -2717,7 +4068,12 @@ "caching-transform": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "md5-hex": "1.3.0", + "mkdirp": "0.5.1", + "write-file-atomic": "1.3.4" + } }, "camelcase": { "version": "1.2.1", @@ -2729,18 +4085,34 @@ "version": "0.1.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } }, "chalk": { "version": "1.1.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } }, "cliui": { "version": "2.1.0", "bundled": true, "dev": true, "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, "dependencies": { "wordwrap": { "version": "0.0.2", @@ -2778,12 +4150,19 @@ "cross-spawn": { "version": "4.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "lru-cache": "4.0.2", + "which": "1.2.14" + } }, "debug": { "version": "2.6.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "ms": "0.7.3" + } }, "debug-log": { "version": "1.0.1", @@ -2798,17 +4177,26 @@ "default-require-extensions": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } }, "detect-indent": { "version": "4.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "repeating": "2.0.1" + } }, "error-ex": { "version": "1.3.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } }, "escape-string-regexp": { "version": "1.0.5", @@ -2823,17 +4211,26 @@ "expand-brackets": { "version": "0.1.5", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } }, "expand-range": { "version": "1.8.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "fill-range": "2.2.3" + } }, "extglob": { "version": "0.3.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } }, "filename-regex": { "version": "2.0.1", @@ -2843,17 +4240,33 @@ "fill-range": { "version": "2.2.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.6", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } }, "find-cache-dir": { "version": "0.1.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } }, "find-up": { "version": "1.1.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } }, "for-in": { "version": "1.0.2", @@ -2863,12 +4276,19 @@ "for-own": { "version": "0.1.5", "bundled": true, - "dev": true + "dev": true, + "requires": { + "for-in": "1.0.2" + } }, "foreground-child": { "version": "1.5.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "cross-spawn": "4.0.2", + "signal-exit": "3.0.2" + } }, "fs.realpath": { "version": "1.0.0", @@ -2883,17 +4303,32 @@ "glob": { "version": "7.1.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } }, "glob-base": { "version": "0.3.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } }, "glob-parent": { "version": "2.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-glob": "2.0.1" + } }, "globals": { "version": "9.17.0", @@ -2909,18 +4344,30 @@ "version": "4.0.8", "bundled": true, "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.22" + }, "dependencies": { "source-map": { "version": "0.4.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "amdefine": "1.0.1" + } } } }, "has-ansi": { "version": "2.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "has-flag": { "version": "1.0.0", @@ -2940,7 +4387,11 @@ "inflight": { "version": "1.0.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } }, "inherits": { "version": "2.0.3", @@ -2950,7 +4401,10 @@ "invariant": { "version": "2.2.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } }, "invert-kv": { "version": "1.0.0", @@ -2970,7 +4424,10 @@ "is-builtin-module": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } }, "is-dotfile": { "version": "1.0.2", @@ -2980,7 +4437,10 @@ "is-equal-shallow": { "version": "0.1.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } }, "is-extendable": { "version": "0.1.1", @@ -2995,22 +4455,34 @@ "is-finite": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } }, "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } }, "is-glob": { "version": "2.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } }, "is-number": { "version": "2.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "kind-of": "3.2.0" + } }, "is-posix-bracket": { "version": "0.1.1", @@ -3040,7 +4512,10 @@ "isobject": { "version": "2.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "isarray": "1.0.0" + } }, "istanbul-lib-coverage": { "version": "1.1.0", @@ -3050,34 +4525,65 @@ "istanbul-lib-hook": { "version": "1.0.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "append-transform": "0.4.0" + } }, "istanbul-lib-instrument": { "version": "1.7.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "babel-generator": "6.24.1", + "babel-template": "6.24.1", + "babel-traverse": "6.24.1", + "babel-types": "6.24.1", + "babylon": "6.17.0", + "istanbul-lib-coverage": "1.1.0", + "semver": "5.3.0" + } }, "istanbul-lib-report": { "version": "1.1.0", "bundled": true, "dev": true, + "requires": { + "istanbul-lib-coverage": "1.1.0", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, "dependencies": { "supports-color": { "version": "3.2.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "has-flag": "1.0.0" + } } } }, "istanbul-lib-source-maps": { "version": "1.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "debug": "2.6.6", + "istanbul-lib-coverage": "1.1.0", + "mkdirp": "0.5.1", + "rimraf": "2.6.1", + "source-map": "0.5.6" + } }, "istanbul-reports": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "handlebars": "4.0.8" + } }, "js-tokens": { "version": "3.0.1", @@ -3092,7 +4598,10 @@ "kind-of": { "version": "3.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } }, "lazy-cache": { "version": "1.0.4", @@ -3103,12 +4612,22 @@ "lcid": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } }, "load-json-file": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } }, "lodash": { "version": "4.17.4", @@ -3123,17 +4642,27 @@ "loose-envify": { "version": "1.3.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "js-tokens": "3.0.1" + } }, "lru-cache": { "version": "4.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } }, "md5-hex": { "version": "1.3.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "md5-o-matic": "0.1.1" + } }, "md5-o-matic": { "version": "0.1.1", @@ -3143,17 +4672,38 @@ "merge-source-map": { "version": "1.0.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "source-map": "0.5.6" + } }, "micromatch": { "version": "2.3.11", "bundled": true, - "dev": true + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.0", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" + } }, "minimatch": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } }, "minimist": { "version": "0.0.8", @@ -3163,7 +4713,10 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "minimist": "0.0.8" + } }, "ms": { "version": "0.7.3", @@ -3173,12 +4726,21 @@ "normalize-package-data": { "version": "2.3.8", "bundled": true, - "dev": true + "dev": true, + "requires": { + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + } }, "normalize-path": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "remove-trailing-separator": "1.0.1" + } }, "number-is-nan": { "version": "1.0.1", @@ -3193,17 +4755,28 @@ "object.omit": { "version": "2.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } }, "once": { "version": "1.4.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "wrappy": "1.0.2" + } }, "optimist": { "version": "0.6.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } }, "os-homedir": { "version": "1.0.2", @@ -3213,22 +4786,37 @@ "os-locale": { "version": "1.4.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "lcid": "1.0.0" + } }, "parse-glob": { "version": "3.0.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.2", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } }, "parse-json": { "version": "2.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "error-ex": "1.3.1" + } }, "path-exists": { "version": "2.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } }, "path-is-absolute": { "version": "1.0.1", @@ -3243,7 +4831,12 @@ "path-type": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } }, "pify": { "version": "2.3.0", @@ -3258,12 +4851,18 @@ "pinkie-promise": { "version": "2.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "pinkie": "2.0.4" + } }, "pkg-dir": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "find-up": "1.1.2" + } }, "preserve": { "version": "0.2.0", @@ -3278,17 +4877,30 @@ "randomatic": { "version": "1.1.6", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-number": "2.1.0", + "kind-of": "3.2.0" + } }, "read-pkg": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" + } }, "read-pkg-up": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } }, "regenerator-runtime": { "version": "0.10.5", @@ -3298,7 +4910,11 @@ "regex-cache": { "version": "0.4.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + } }, "remove-trailing-separator": { "version": "1.0.1", @@ -3318,7 +4934,10 @@ "repeating": { "version": "2.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-finite": "1.0.2" + } }, "require-directory": { "version": "2.1.1", @@ -3339,12 +4958,18 @@ "version": "0.1.3", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "align-text": "0.1.4" + } }, "rimraf": { "version": "2.6.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "glob": "7.1.1" + } }, "semver": { "version": "5.3.0", @@ -3375,6 +5000,14 @@ "version": "1.2.4", "bundled": true, "dev": true, + "requires": { + "foreground-child": "1.5.6", + "mkdirp": "0.5.1", + "os-homedir": "1.0.2", + "rimraf": "2.6.1", + "signal-exit": "2.1.2", + "which": "1.2.14" + }, "dependencies": { "signal-exit": { "version": "2.1.2", @@ -3386,7 +5019,10 @@ "spdx-correct": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } }, "spdx-expression-parse": { "version": "1.0.4", @@ -3401,17 +5037,28 @@ "string-width": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } }, "strip-ansi": { "version": "3.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "strip-bom": { "version": "2.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } }, "supports-color": { "version": "2.0.0", @@ -3421,7 +5068,14 @@ "test-exclude": { "version": "4.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } }, "to-fast-properties": { "version": "1.0.3", @@ -3438,12 +5092,23 @@ "bundled": true, "dev": true, "optional": true, + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, "dependencies": { "yargs": { "version": "3.10.0", "bundled": true, "dev": true, - "optional": true + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } } } }, @@ -3456,12 +5121,19 @@ "validate-npm-package-license": { "version": "3.0.1", "bundled": true, - "dev": true + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } }, "which": { "version": "1.2.14", "bundled": true, - "dev": true + "dev": true, + "requires": { + "isexe": "2.0.0" + } }, "which-module": { "version": "1.0.0", @@ -3482,7 +5154,11 @@ "wrap-ansi": { "version": "2.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } }, "wrappy": { "version": "1.0.2", @@ -3492,7 +5168,12 @@ "write-file-atomic": { "version": "1.3.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } }, "y18n": { "version": "3.2.1", @@ -3508,6 +5189,21 @@ "version": "7.1.0", "bundled": true, "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + }, "dependencies": { "camelcase": { "version": "3.0.0", @@ -3517,7 +5213,12 @@ "cliui": { "version": "3.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } } } }, @@ -3525,6 +5226,9 @@ "version": "5.0.0", "bundled": true, "dev": true, + "requires": { + "camelcase": "3.0.0" + }, "dependencies": { "camelcase": { "version": "3.0.0", @@ -3545,19 +5249,30 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } }, "observable-to-promise": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.4.0.tgz", "integrity": "sha1-KK/nFkUwjy1B1x9HrT/s4aN35Ss=", - "dev": true + "dev": true, + "requires": { + "is-observable": "0.2.0", + "symbol-observable": "0.2.4" + } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true + "dev": true, + "requires": { + "wrappy": "1.0.2" + } }, "onetime": { "version": "1.1.0", @@ -3569,7 +5284,10 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-0.1.1.tgz", "integrity": "sha1-6bgR4AbxwPVIAvKClb/Ilw+Nz70=", - "dev": true + "dev": true, + "requires": { + "object-assign": "4.1.1" + } }, "os-browserify": { "version": "0.2.1", @@ -3587,7 +5305,10 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true + "dev": true, + "requires": { + "lcid": "1.0.0" + } }, "os-tmpdir": { "version": "1.0.2", @@ -3599,19 +5320,32 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "dev": true + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } }, "package-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", - "dev": true + "dev": true, + "requires": { + "md5-hex": "1.3.0" + } }, "package-json": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", - "dev": true + "dev": true, + "requires": { + "got": "5.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.3.0" + } }, "pako": { "version": "0.2.9", @@ -3623,19 +5357,35 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", - "dev": true + "dev": true, + "requires": { + "asn1.js": "4.9.1", + "browserify-aes": "1.0.6", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.0", + "pbkdf2": "3.0.12" + } }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true + "dev": true, + "requires": { + "error-ex": "1.3.1" + } }, "parse-ms": { "version": "1.0.1", @@ -3647,7 +5397,11 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", - "dev": true + "dev": true, + "requires": { + "camel-case": "3.0.0", + "upper-case-first": "1.1.2" + } }, "path-browserify": { "version": "0.0.0", @@ -3659,7 +5413,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } }, "path-is-absolute": { "version": "1.0.1", @@ -3671,13 +5428,25 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } }, "pbkdf2": { "version": "3.0.12", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", "integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=", - "dev": true + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.0.1", + "sha.js": "2.4.8" + } }, "pify": { "version": "2.3.0", @@ -3695,43 +5464,70 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true + "dev": true, + "requires": { + "pinkie": "2.0.4" + } }, "pkg-conf": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-1.1.3.tgz", "integrity": "sha1-N45W1v0T6Iv7b0ol33qD+qvduls=", - "dev": true + "dev": true, + "requires": { + "find-up": "1.1.2", + "load-json-file": "1.1.0", + "object-assign": "4.1.1", + "symbol": "0.2.3" + } }, "pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true + "dev": true, + "requires": { + "find-up": "1.1.2" + } }, "plur": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true + "dev": true, + "requires": { + "irregular-plurals": "1.2.0" + } }, "power-assert-context-formatter": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz", "integrity": "sha1-7bo1LT7YpgMRTWZyZazOYNaJzN8=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "power-assert-context-traversal": "1.1.1" + } }, "power-assert-context-traversal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/power-assert-context-traversal/-/power-assert-context-traversal-1.1.1.tgz", "integrity": "sha1-iMq8oNE7Y1nwfT0+ivppkmRXftk=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "estraverse": "4.2.0" + } }, "power-assert-renderer-assertion": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.1.1.tgz", "integrity": "sha1-y/wOd+AIao+Wrz8djme57n4ozpg=", - "dev": true + "dev": true, + "requires": { + "power-assert-renderer-base": "1.1.1", + "power-assert-util-string-width": "1.1.1" + } }, "power-assert-renderer-base": { "version": "1.1.1", @@ -3743,19 +5539,32 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.1.2.tgz", "integrity": "sha1-ZV+PcRk1qbbVQbhjJ2VHF8Y3qYY=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "power-assert-renderer-base": "1.1.1", + "power-assert-util-string-width": "1.1.1", + "stringifier": "1.3.0" + } }, "power-assert-renderer-succinct": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/power-assert-renderer-succinct/-/power-assert-renderer-succinct-1.1.1.tgz", "integrity": "sha1-wqRosjgiq9b4Diq6UyI0ewnfR24=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "power-assert-renderer-diagram": "1.1.2" + } }, "power-assert-util-string-width": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/power-assert-util-string-width/-/power-assert-util-string-width-1.1.1.tgz", "integrity": "sha1-vmWet5N/3S5smncmjar2S9W3xZI=", - "dev": true + "dev": true, + "requires": { + "eastasianwidth": "0.1.1" + } }, "prepend-http": { "version": "1.0.4", @@ -3774,6 +5583,11 @@ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", "dev": true, + "requires": { + "is-finite": "1.0.2", + "parse-ms": "1.0.1", + "plur": "1.0.0" + }, "dependencies": { "plur": { "version": "1.0.0", @@ -3817,7 +5631,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", - "dev": true + "dev": true, + "requires": { + "bn.js": "4.11.6", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } }, "punycode": { "version": "1.4.1", @@ -3842,18 +5663,28 @@ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, "dependencies": { "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "requires": { + "kind-of": "3.2.2" + }, "dependencies": { "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } } } }, @@ -3861,7 +5692,10 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } } } }, @@ -3870,6 +5704,9 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", "dev": true, + "requires": { + "safe-buffer": "5.1.0" + }, "dependencies": { "safe-buffer": { "version": "5.1.0", @@ -3884,6 +5721,12 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", "dev": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, "dependencies": { "minimist": { "version": "1.2.0", @@ -3897,37 +5740,69 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dev": true + "dev": true, + "requires": { + "pinkie-promise": "2.0.1", + "readable-stream": "2.2.11" + } }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" + } }, "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } }, "readable-stream": { "version": "2.2.11", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.11.tgz", "integrity": "sha512-h+8+r3MKEhkiVrwdKL8aWs1oc1VvBu33ueshOvS26RsZQ3Amhx/oO3TKe4lApSV9ueY6as8EAh7mtuFjdlhg9Q==", - "dev": true + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.0.1", + "string_decoder": "1.0.2", + "util-deprecate": "1.0.2" + } }, "readdirp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.2.11", + "set-immediate-shim": "1.0.1" + } }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } }, "regenerate": { "version": "1.3.2", @@ -3945,31 +5820,52 @@ "version": "0.9.11", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", - "dev": true + "dev": true, + "requires": { + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "private": "0.1.7" + } }, "regex-cache": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", - "dev": true + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" + } }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true + "dev": true, + "requires": { + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } }, "registry-auth-token": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", - "dev": true + "dev": true, + "requires": { + "rc": "1.2.1", + "safe-buffer": "5.0.1" + } }, "registry-url": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true + "dev": true, + "requires": { + "rc": "1.2.1" + } }, "regjsgen": { "version": "0.2.0", @@ -3982,6 +5878,9 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, + "requires": { + "jsesc": "0.5.0" + }, "dependencies": { "jsesc": { "version": "0.5.0", @@ -4013,7 +5912,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true + "dev": true, + "requires": { + "is-finite": "1.0.2" + } }, "require-directory": { "version": "2.1.1", @@ -4037,7 +5939,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", - "dev": true + "dev": true, + "requires": { + "resolve-from": "2.0.0" + } }, "resolve-from": { "version": "2.0.0", @@ -4049,25 +5954,39 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true + "dev": true, + "requires": { + "align-text": "0.1.4" + } }, "rimraf": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true + "dev": true, + "requires": { + "glob": "7.1.2" + } }, "ripemd160": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", - "dev": true + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } }, "safe-buffer": { "version": "5.0.1", @@ -4085,7 +6004,10 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true + "dev": true, + "requires": { + "semver": "5.3.0" + } }, "set-blocking": { "version": "2.0.0", @@ -4109,7 +6031,10 @@ "version": "2.4.8", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3" + } }, "signal-exit": { "version": "3.0.2", @@ -4139,7 +6064,10 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } }, "source-list-map": { "version": "1.1.2", @@ -4157,13 +6085,19 @@ "version": "0.4.15", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", - "dev": true + "dev": true, + "requires": { + "source-map": "0.5.6" + } }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } }, "spdx-expression-parse": { "version": "1.0.4", @@ -4187,49 +6121,82 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "dev": true + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.2.11" + } }, "stream-http": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.1.tgz", "integrity": "sha1-VGpRdBrVprB+njGwsQRBqRffUoo=", - "dev": true - }, - "string_decoder": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", - "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", - "dev": true + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.2.11", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } }, "stringifier": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz", "integrity": "sha1-3vGDQvaTPbDy2/yaoCF1tEjBeVk=", - "dev": true + "dev": true, + "requires": { + "core-js": "2.4.1", + "traverse": "0.6.6", + "type-name": "2.0.2" + } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } }, "strip-json-comments": { "version": "2.0.1", @@ -4277,13 +6244,23 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true + "dev": true, + "requires": { + "readable-stream": "2.2.11", + "xtend": "4.0.1" + } }, "time-require": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", "dev": true, + "requires": { + "chalk": "0.4.0", + "date-time": "0.1.1", + "pretty-ms": "0.2.2", + "text-table": "0.2.0" + }, "dependencies": { "ansi-styles": { "version": "1.0.0", @@ -4295,7 +6272,12 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } }, "parse-ms": { "version": "0.1.2", @@ -4307,7 +6289,10 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", - "dev": true + "dev": true, + "requires": { + "parse-ms": "0.1.2" + } }, "strip-ansi": { "version": "0.1.1", @@ -4327,7 +6312,10 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=", - "dev": true + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } }, "to-arraybuffer": { "version": "1.0.1", @@ -4375,7 +6363,12 @@ "version": "2.8.28", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.28.tgz", "integrity": "sha512-WqKNbmNJKzIdIEQu/U2ytgGBbhCy2PVks94GoetczOAJ/zCgVu2CuO7gguI5KPFGPtUtI1dmPQl6h0D4cPzypA==", - "dev": true + "dev": true, + "requires": { + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + } }, "uglify-to-browserify": { "version": "1.0.2", @@ -4394,7 +6387,12 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", - "dev": true + "dev": true, + "requires": { + "mkdirp": "0.5.1", + "os-tmpdir": "1.0.2", + "uid2": "0.0.3" + } }, "unzip-response": { "version": "1.0.2", @@ -4406,7 +6404,17 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=", - "dev": true + "dev": true, + "requires": { + "boxen": "0.6.0", + "chalk": "1.1.3", + "configstore": "2.1.0", + "is-npm": "1.0.0", + "latest-version": "2.0.0", + "lazy-req": "1.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "2.0.0" + } }, "upper-case": { "version": "1.1.3", @@ -4418,13 +6426,20 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", - "dev": true + "dev": true, + "requires": { + "upper-case": "1.1.3" + } }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, "dependencies": { "punycode": { "version": "1.3.2", @@ -4438,13 +6453,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true + "dev": true, + "requires": { + "prepend-http": "1.0.4" + } }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, + "requires": { + "inherits": "2.0.1" + }, "dependencies": { "inherits": { "version": "2.0.1", @@ -4470,25 +6491,60 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } }, "vm-browserify": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true + "dev": true, + "requires": { + "indexof": "0.0.1" + } }, "watchpack": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz", "integrity": "sha1-fYaTkHsozmAT5/NhCqKhrPB9rYc=", - "dev": true + "dev": true, + "requires": { + "async": "2.4.1", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + } }, "webpack": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.6.1.tgz", "integrity": "sha1-LgRX8KuxrF3zqxBsacZy8jZ4Xwc=", "dev": true, + "requires": { + "acorn": "5.0.3", + "acorn-dynamic-import": "2.0.2", + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "async": "2.4.1", + "enhanced-resolve": "3.1.0", + "interpret": "1.0.3", + "json-loader": "0.5.4", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "0.2.17", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.0.0", + "source-map": "0.5.6", + "supports-color": "3.2.3", + "tapable": "0.2.6", + "uglify-js": "2.8.28", + "watchpack": "1.3.1", + "webpack-sources": "0.2.3", + "yargs": "6.6.0" + }, "dependencies": { "camelcase": { "version": "3.0.0", @@ -4500,7 +6556,12 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } }, "has-flag": { "version": "1.0.0", @@ -4512,13 +6573,31 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true + "dev": true, + "requires": { + "has-flag": "1.0.0" + } }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "4.2.1" + } } } }, @@ -4526,13 +6605,20 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=", - "dev": true + "dev": true, + "requires": { + "source-list-map": "1.1.2", + "source-map": "0.5.6" + } }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true + "dev": true, + "requires": { + "isexe": "2.0.0" + } }, "which-module": { "version": "1.0.0", @@ -4544,7 +6630,10 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2" + } }, "window-size": { "version": "0.1.0", @@ -4562,7 +6651,11 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } }, "wrappy": { "version": "1.0.2", @@ -4574,25 +6667,45 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } }, "write-json-file": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-1.2.0.tgz", "integrity": "sha1-LV3+lqvDyIkFfJOXGqQAXvtUgTQ=", - "dev": true + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "sort-keys": "1.1.2", + "write-file-atomic": "1.3.4" + } }, "write-pkg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-1.0.0.tgz", "integrity": "sha1-rriqnU14jh2JPfsIVJaLVDqRn1c=", - "dev": true + "dev": true, + "requires": { + "write-json-file": "1.2.0" + } }, "xdg-basedir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } }, "xtend": { "version": "4.0.1", @@ -4617,6 +6730,12 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + }, "dependencies": { "camelcase": { "version": "1.2.1", @@ -4631,6 +6750,9 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", "dev": true, + "requires": { + "camelcase": "3.0.0" + }, "dependencies": { "camelcase": { "version": "3.0.0", diff --git a/package.json b/package.json index 4c937ed..7eee8a9 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "email": "jake@codeincomplete.com" } ], - "license": "LGPL-3.0", + "license": "MIT", "main": "lib/state-machine.js", "files": [ "lib/**/*.js", @@ -38,7 +38,7 @@ "uglify-js": "^2.7.5", "webpack": "^2.2.0-rc.1" }, - "version": "3.0.1", + "version": "3.1.0", "scripts": { "start": "npm run watch", "build": "npm run bundle && npm run minify", From 0d603577423244228cebcd62e60dbbfff27c6ea3 Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Thu, 12 Jul 2018 07:33:43 -0700 Subject: [PATCH 52/53] update npm version badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cba155..e9b9cd3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Javascript State Machine -[![NPM version](https://img.shields.io/npm/v/javascript-state-machine.svg?style=flat)](https://www.npmjs.org/package/javascript-state-machine) +[![NPM version](https://badge.fury.io/js/javascript-state-machine.svg)](https://badge.fury.io/js/javascript-state-machine) [![Build Status](https://travis-ci.org/jakesgordon/javascript-state-machine.svg?branch=master)](https://travis-ci.org/jakesgordon/javascript-state-machine) A library for finite state machines. From 2ae84bbbaad13103be43b3e0a24c077002e2301a Mon Sep 17 00:00:00 2001 From: Jake Gordon Date: Sun, 1 Jun 2025 15:01:46 -0700 Subject: [PATCH 53/53] update links s/codeincomplete.com/jakesgordon.com/ --- README.md | 4 ++-- RELEASE_NOTES.md | 8 ++++---- package.json | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e9b9cd3..a2c4add 100644 --- a/README.md +++ b/README.md @@ -144,5 +144,5 @@ See [MIT LICENSE](https://github.com/jakesgordon/javascript-state-machine/blob/m # Contact If you have any ideas, feedback, requests or bug reports, you can reach me at -[jake@codeincomplete.com](mailto:jake@codeincomplete.com), or via -my website: [Code inComplete](http://codeincomplete.com/) +[jakesgordon@gmail.com](mailto:jakesgordon@gmail.com), or via +my website: [jakesgordon.com](https://jakesgordon.com/) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0527d19..67de268 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -81,7 +81,7 @@ Version 2.2.0 (January 26th 2013) * Added generic state callbacks 'onleavestate' and 'onenterstate' (issue #28) * Fixed 'undefined' event return codes (issue #34) - pull from gentooboontoo (thanks!) * Allow async event transition to be cancelled (issue #22) - * [read more...](http://codeincomplete.com/posts/2013/1/26/javascript_state_machine_v2_2_0/) + * [read more...](https://jakesgordon.com/writing/javascript-state-machine-v2-2-0/) Version 2.1.0 (January 7th 2012) -------------------------------- @@ -104,14 +104,14 @@ Version 2.0.0 (August 19th 2011) * added a generic `onchangestate(event,from,to)` callback to detect all state changes with a single function. * allow callbacks to be declared at creation time (instead of having to attach them afterwards) * renamed 'hooks' => 'callbacks' - * [read more...](http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/) + * [read more...](https://jakesgordon.com/writing/javascript-state-machine-v2/) Version 1.2.0 (June 21st 2011) ------------------------------ * allows the same event to transition to different states, depending on the current state (see 'Multiple...' section in README.md) - * [read more...](http://codeincomplete.com/posts/2011/6/21/javascript_state_machine_v1_2_0/) + * [read more...](https://jakesgordon.com/writing/javascript-state-machine-v1-2-0/) Version 1.0.0 (June 1st 2011) ----------------------------- * initial version - * [read more...](http://codeincomplete.com/posts/2011/6/1/javascript_state_machine/) + * [read more...](https://jakesgordon.com/writing/javascript-state-machine/) diff --git a/package.json b/package.json index 7eee8a9..a143584 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,12 @@ ], "author": { "name": "Jake Gordon", - "email": "jake@codeincomplete.com" + "email": "jakesgordon@gmail.com" }, "maintainers": [ { "name": "Jake Gordon", - "email": "jake@codeincomplete.com" + "email": "jakesgordon@gmail.com" } ], "license": "MIT",

        k?&b;HYE%(WY)!s{ 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 WEP<60VwBvs^=MKZD&VSdy>a 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 Kj@)F%tAiH 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