| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | var toggler = require('lib/toggler') | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | var actions = require('lib/actions') | 
					
						
							|  |  |  | var features = require('lib/features') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var core = require('features/core') | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | var widgets = require('features/ui-widgets') | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 04:27:01 +03:00
										 |  |  | var widget = require('lib/widget/widget') | 
					
						
							|  |  |  | var browse = require('lib/widget/browse') | 
					
						
							|  |  |  | var overlay = require('lib/widget/overlay') | 
					
						
							|  |  |  | var drawer = require('lib/widget/drawer') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var browseWalk = require('lib/widget/browse-walk') | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ExampleActions = actions.Actions({ | 
					
						
							|  |  |  | 	config: { | 
					
						
							|  |  |  | 		// XXX stuff for togglers...
 | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 01:05:40 +03:00
										 |  |  | 	// NOTE: the path / short doc is optional but it is not recommended 
 | 
					
						
							|  |  |  | 	// 		to to omit it unless defining a non-root action...
 | 
					
						
							|  |  |  | 	// XXX should an action be able to overload the doc???
 | 
					
						
							|  |  |  | 	// 		...the intuitive thing to do here is make the doc "write-once"
 | 
					
						
							|  |  |  | 	// 		i.e. once defined it can't be overwritten...
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	exampleAction: ['Test/Action', | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 		function(){ | 
					
						
							| 
									
										
										
										
											2018-12-12 00:53:17 +03:00
										 |  |  | 			console.log('>>>', ...arguments) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 			return function(){ | 
					
						
							| 
									
										
										
										
											2018-12-12 00:53:17 +03:00
										 |  |  | 				console.log('<<<', ...arguments) }}], | 
					
						
							| 
									
										
										
										
											2017-11-05 01:05:40 +03:00
										 |  |  | 	exampleActionFull: ['- Test/', | 
					
						
							|  |  |  | 		core.doc`Example full action long documentation string
 | 
					
						
							|  |  |  | 		`,
 | 
					
						
							|  |  |  | 		// action attributes...
 | 
					
						
							|  |  |  | 		{}, | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			// XXX
 | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-01 20:19:12 +03:00
										 |  |  | 	exampleActionDebounced: ['Test/Action (debounced)', | 
					
						
							|  |  |  | 		core.doc`This is .exampleAction(..) debounced.
 | 
					
						
							|  |  |  | 		`,
 | 
					
						
							|  |  |  | 		core.debounce('exampleAction')], | 
					
						
							|  |  |  | 	exampleDebouncedAction: ['Test/Custom debounced action', | 
					
						
							|  |  |  | 		core.debounce(1000, function(...args){ | 
					
						
							|  |  |  | 			console.log('exampleDebouncedAction: This can\'t be called more often than once per 1 second.') | 
					
						
							|  |  |  | 			console.log('exampleDebouncedAction: note that within this second only the original return value is returned.') | 
					
						
							|  |  |  | 			console.log('    <', args) | 
					
						
							|  |  |  | 			return args | 
					
						
							|  |  |  | 		})], | 
					
						
							| 
									
										
										
										
											2018-09-02 00:12:08 +03:00
										 |  |  | 	exampleAliasDebounced: ['Test/', | 
					
						
							|  |  |  | 		core.debounce(1000, 'exampleAction: ...')], | 
					
						
							| 
									
										
										
										
											2018-09-01 23:45:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-12 00:53:17 +03:00
										 |  |  | 	exampleAfterActionCall: ['Test/', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			// schedule a call after the action is done...
 | 
					
						
							|  |  |  | 			this.afterAction('local', | 
					
						
							|  |  |  | 				function(){ console.log('exampleAfterActionCall: done.') }) | 
					
						
							|  |  |  | 			// schedule a call after the top action call...
 | 
					
						
							|  |  |  | 			this.afterAction('top',  | 
					
						
							|  |  |  | 				function(){ console.log('exampleAfterActionCall: final done.') }) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	exampleNestedAfterActionCall: ['Test/', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			this.afterAction(function(){ console.log('exampleNestedAfterActionCall: done.') }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.exampleAfterActionCall() | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 	// a normal method...
 | 
					
						
							|  |  |  | 	exampleMethod: function(){ | 
					
						
							| 
									
										
										
										
											2018-11-12 23:04:00 +03:00
										 |  |  | 		console.log('example method:', [...arguments]) | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 		return 'example result' | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX does not work -- see actions.Actions(..) for details...
 | 
					
						
							|  |  |  | 	exampleAlias: ['Test/Action alias', | 
					
						
							|  |  |  | 		'focusImage: "prev"'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// action constructor for testing...
 | 
					
						
							|  |  |  | 	makeExampleAction: ['- Test/', | 
					
						
							|  |  |  | 		function(name){ | 
					
						
							|  |  |  | 			this[name] = actions.Action.apply(actions.Action, arguments) }], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// promise handling...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2017-11-05 01:05:40 +03:00
										 |  |  | 	// also see corresponding Example.handlers
 | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 	exampleSyncAction: ['- Test/', | 
					
						
							|  |  |  | 		//{await: true},
 | 
					
						
							|  |  |  | 		function(t){ | 
					
						
							|  |  |  | 			return new Promise(function(resolve){ | 
					
						
							|  |  |  | 				setTimeout(function(){ resolve() }, t || 1000) }) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	exampleAsyncAction: ['- Test/', | 
					
						
							|  |  |  | 		{await: false}, | 
					
						
							| 
									
										
										
										
											2018-04-12 01:40:26 +03:00
										 |  |  | 		function(t){  | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 			return new Promise(function(resolve){ | 
					
						
							|  |  |  | 				setTimeout(function(){ resolve() }, t || 1000) }) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Togglers...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 	// There are two state change strategies generally used:
 | 
					
						
							|  |  |  | 	// 	1) state accessor changes state (this example)
 | 
					
						
							|  |  |  | 	// 	2) callbacks change state
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 	// XXX add example argument handling...
 | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 	exampleToggler: ['Test/Example toggler', | 
					
						
							|  |  |  | 		core.doc`Example toggler...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		A toggler is any function that adheres to the toggler protocol  | 
					
						
							|  |  |  | 		and (optionally) inherits from toggler.Toggler | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		toggler.Toggler(..) is also a convenient toggler constructor,  | 
					
						
							|  |  |  | 		see: .exampleToggler(..) and .exampleTogglerFull(..) as examples | 
					
						
							|  |  |  | 		of its use. | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		General toggler protocol: | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 			Change to the next state... | 
					
						
							|  |  |  | 			.exampleToggler() | 
					
						
							|  |  |  | 			.exampleToggler('next') | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Change to the previous state... | 
					
						
							|  |  |  | 			.exampleToggler('prev') | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Change to specific state... | 
					
						
							|  |  |  | 			.exampleToggler(state) | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			For bool togglers, set state on/off... | 
					
						
							|  |  |  | 			.exampleToggler('on') | 
					
						
							|  |  |  | 			.exampleToggler('off') | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Get current state... | 
					
						
							|  |  |  | 			.exampleToggler('?') | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Get possible states... | 
					
						
							|  |  |  | 			.exampleToggler('??') | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		It is also possible to pass an argument to a toggler, the recommended | 
					
						
							|  |  |  | 		semantics for this is to change state of the entity passed as argument | 
					
						
							|  |  |  | 		a good example would be .toggleMark(..) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Handle state of arg (recommended semantics)... | 
					
						
							|  |  |  | 			.exampleToggler(arg, ...) | 
					
						
							|  |  |  | 				-> state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Utilities: | 
					
						
							|  |  |  | 			Check if an action is a toggler... | 
					
						
							|  |  |  | 			.isToggler('exampleToggler') | 
					
						
							|  |  |  | 				-> bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		NOTE: it is not required to use toggler.Toggler(..) as constructor | 
					
						
							|  |  |  | 			to build a toggler, a simple function that adheres to the above | 
					
						
							|  |  |  | 			protocol is enough, though it is recommended to inherit from | 
					
						
							|  |  |  | 			toggler.Toggler so as to enable support functionality that  | 
					
						
							|  |  |  | 			utilizes the protocol... | 
					
						
							|  |  |  | 		NOTE: see lib/toggler.js and toggler.Toggler(..) for more details. | 
					
						
							|  |  |  | 		`,
 | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 		toggler.Toggler(null,  | 
					
						
							|  |  |  | 			// state accessor...
 | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 			// NOTE: this may get called multiple times per state change.
 | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 			function(_, state){  | 
					
						
							|  |  |  | 				// get the state...
 | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 				// NOTE: this section should have no side-effects nor 
 | 
					
						
							|  |  |  | 				// 		should it affect the state in any way...
 | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 				if(state == null){ | 
					
						
							|  |  |  | 					return this.__example_toggler_state || 'none' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// handle state changing...
 | 
					
						
							|  |  |  | 				} else if(state == 'none'){ | 
					
						
							|  |  |  | 					delete this.__example_toggler_state | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					this.__example_toggler_state = state | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// List of states...
 | 
					
						
							|  |  |  | 			// NOTE: this can be a string for bool states and a list for
 | 
					
						
							|  |  |  | 			// 		togglers with multiple states...
 | 
					
						
							|  |  |  | 			'A')], | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 	exampleTogglerFull: ['Test/Example toggler (full)', | 
					
						
							|  |  |  | 		core.doc``, | 
					
						
							|  |  |  | 		toggler.Toggler( | 
					
						
							|  |  |  | 			// target...
 | 
					
						
							|  |  |  | 			// XXX more docs!
 | 
					
						
							|  |  |  | 			null,  | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 			// state accessor...
 | 
					
						
							|  |  |  | 			function(_, state){  | 
					
						
							|  |  |  | 				// get the state...
 | 
					
						
							|  |  |  | 				if(state == null){ | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 					return this.__example_full_toggler_state || 'A' | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				} else if(state == 'A'){ | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 					delete this.__example_full_toggler_state | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-11-20 03:19:54 +03:00
										 |  |  | 					this.__example_full_toggler_state = state | 
					
						
							| 
									
										
										
										
											2017-11-19 05:14:52 +03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// List of states...
 | 
					
						
							|  |  |  | 			['A', 'B', 'C'], | 
					
						
							|  |  |  | 			// pre-callback (optional)
 | 
					
						
							|  |  |  | 			function(){ | 
					
						
							|  |  |  | 				console.log('Changing state from:', this.exampleTogglerFull('?')) | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// post-callback...
 | 
					
						
							|  |  |  | 			function(){ | 
					
						
							|  |  |  | 				console.log('Changing state to:', this.exampleTogglerFull('?')) | 
					
						
							|  |  |  | 			})], | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// XXX docs...
 | 
					
						
							|  |  |  | 	// XXX BUG? false is not shown in the dialog button...
 | 
					
						
							|  |  |  | 	exampleConfigTogglerMin: ['- Test/', | 
					
						
							|  |  |  | 		core.doc`Minimal config toggler...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			This will toggle between true and false. | 
					
						
							|  |  |  | 			`,
 | 
					
						
							|  |  |  | 		core.makeConfigToggler('example-option-min')], | 
					
						
							|  |  |  | 	// XXX docs...
 | 
					
						
							|  |  |  | 	exampleConfigToggler: ['- Test/', | 
					
						
							|  |  |  | 		core.makeConfigToggler( | 
					
						
							|  |  |  | 			// option name...
 | 
					
						
							|  |  |  | 			'example-option', | 
					
						
							|  |  |  | 			// option states...
 | 
					
						
							|  |  |  | 			//
 | 
					
						
							|  |  |  | 			// NOTE: 'none' represents an undefined value, but when 
 | 
					
						
							|  |  |  | 			// 		setting 'none' state, 'none' is explicitly written as
 | 
					
						
							|  |  |  | 			// 		option value.
 | 
					
						
							|  |  |  | 			// 		This is done intentionally as deleting the attribute
 | 
					
						
							|  |  |  | 			// 		can expose the shadowed option value.
 | 
					
						
							|  |  |  | 			['A', 'B', 'C', 'none'], | 
					
						
							|  |  |  | 			// post-callback (optional)...
 | 
					
						
							|  |  |  | 			function(state){ | 
					
						
							|  |  |  | 				console.log('exampleConfigToggler: callback: shifting state to:', state) | 
					
						
							|  |  |  | 			})], | 
					
						
							|  |  |  | 	// XXX docs...
 | 
					
						
							|  |  |  | 	exampleConfigTogglerFull: ['- Test/', | 
					
						
							|  |  |  | 		core.makeConfigToggler( | 
					
						
							|  |  |  | 			// option name...
 | 
					
						
							|  |  |  | 			'example-option-full', | 
					
						
							|  |  |  | 			// option states...
 | 
					
						
							|  |  |  | 			function(){ | 
					
						
							|  |  |  | 				return ['A', 'B', 'C', 'none'] | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// pre-callback...
 | 
					
						
							|  |  |  | 			function(state){ | 
					
						
							|  |  |  | 				if(state == 'C'){ | 
					
						
							|  |  |  | 					console.log('exampleConfigToggler: pre-callback: preventing shift to:', state) | 
					
						
							|  |  |  | 					// we can prevent a state change by returning false...
 | 
					
						
							|  |  |  | 					// XXX should we be able to return a different state here???
 | 
					
						
							|  |  |  | 					return false | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				console.log('exampleConfigToggler: pre-callback: shifting state to:', state) | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// post-callback...
 | 
					
						
							|  |  |  | 			function(state){ | 
					
						
							|  |  |  | 				console.log('exampleConfigToggler: post-callback: shifting state to:', state) | 
					
						
							|  |  |  | 			})], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX event and event use...
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// XXX inner/outer action...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Example =  | 
					
						
							|  |  |  | module.Example = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tag: 'action-examples', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	actions: ExampleActions,  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 01:05:40 +03:00
										 |  |  | 	// XXX make this not applicable in production...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							| 
									
										
										
										
											2018-12-12 00:53:17 +03:00
										 |  |  | 		[[ | 
					
						
							|  |  |  | 			'exampleAsyncAction.pre', | 
					
						
							|  |  |  | 			'exampleSyncAction.pre', | 
					
						
							|  |  |  | 			'exampleAfterActionCall.pre', | 
					
						
							|  |  |  | 		],  | 
					
						
							| 
									
										
										
										
											2017-11-05 01:05:40 +03:00
										 |  |  | 			function(){ | 
					
						
							|  |  |  | 				console.log('PRE') | 
					
						
							|  |  |  | 				return function(){ | 
					
						
							|  |  |  | 					console.log('POST') }  | 
					
						
							|  |  |  | 			}], | 
					
						
							|  |  |  | 	], | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ExampleUIActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:23:51 +03:00
										 |  |  | 	// XXX move this to a ui-dependant feature...
 | 
					
						
							|  |  |  | 	exampleCSSClassToggler: ['- Test/', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	exampleActionDisabled: ['Test/$Disabled example action', | 
					
						
							|  |  |  | 		{browseMode: function(){ return 'disabled' }}, | 
					
						
							|  |  |  | 		function(){  | 
					
						
							| 
									
										
										
										
											2018-11-12 23:04:00 +03:00
										 |  |  | 			console.log('Disabled action called:', [...arguments]) }], | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Usage Examples:
 | 
					
						
							|  |  |  | 	// 	.exampleDrawer()						- show html in base drawer...
 | 
					
						
							|  |  |  | 	// 	.exampleDrawer('Header', 'paragraph')	- show html with custom text...
 | 
					
						
							|  |  |  | 	// 	.exampleDrawer('Overlay')				- show html in overlay...
 | 
					
						
							|  |  |  | 	// 	.exampleDrawer('Overlay', 'Header', 'paragraph')
 | 
					
						
							|  |  |  | 	// 										- show html in overlay with 
 | 
					
						
							|  |  |  | 	// 										  custom text...
 | 
					
						
							|  |  |  | 	exampleDrawer: ['Test/99: D$rawer widget example...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog('Drawer',  | 
					
						
							|  |  |  | 			function(h, txt){ | 
					
						
							|  |  |  | 				return $('<div>') | 
					
						
							|  |  |  | 					.css({ | 
					
						
							|  |  |  | 						position: 'relative', | 
					
						
							|  |  |  | 						background: 'white', | 
					
						
							|  |  |  | 						height: '300px', | 
					
						
							|  |  |  | 						padding: '20px', | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 					.append($('<h1>') | 
					
						
							|  |  |  | 						.text(h || 'Drawer example...')) | 
					
						
							|  |  |  | 					.append($('<p>') | 
					
						
							|  |  |  | 						.text(txt || 'With some text.')) | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			// pass custom configuration to container...
 | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				background: 'white', | 
					
						
							|  |  |  | 				focusable: true, | 
					
						
							|  |  |  | 			})], | 
					
						
							|  |  |  | 	// XXX show new features...
 | 
					
						
							|  |  |  | 	exampleBrowse: ['Test/-99: Demo $new style dialog...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var actions = this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 23:04:00 +03:00
										 |  |  | 			console.log('>>> args:', [...arguments]) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 				var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make('select last')  | 
					
						
							|  |  |  | 					.on('open', function(){ | 
					
						
							|  |  |  | 						that.select(-1) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 				make('do nothing') | 
					
						
							| 
									
										
										
										
											2018-11-08 21:10:58 +03:00
										 |  |  | 					.addClass('marked') | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				make('nested dialog...', | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						shortcut_key: 'n', | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 					.on('open', function(){ | 
					
						
							|  |  |  | 						actions.exampleBrowse() | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make('---') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make('$close parent') | 
					
						
							|  |  |  | 					.on('open', function(){ | 
					
						
							|  |  |  | 						that.parent.close() | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make('...') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// NOTE: the dialog's .parent is not yet set at this point...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// This will finalize the dialog...
 | 
					
						
							|  |  |  | 				//
 | 
					
						
							|  |  |  | 				// NOTE: this is not needed here as the dialog is drawn
 | 
					
						
							|  |  |  | 				// 		on sync, but for async dialogs this will align
 | 
					
						
							|  |  |  | 				// 		the selected field correctly.
 | 
					
						
							|  |  |  | 				make.done() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			// NOTE: this is not a dialog event, it is defined by the 
 | 
					
						
							|  |  |  | 			// 		container to notify us that we are closing...
 | 
					
						
							|  |  |  | 			.on('close', function(){ | 
					
						
							|  |  |  | 				console.log('Dialog closing...') | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		})], | 
					
						
							| 
									
										
										
										
											2018-11-07 23:24:09 +03:00
										 |  |  | 	// XXX use tag list and current image tags....
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	exampleBrowseCloud: ['Test/Demo $cloud dialog...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var actions = this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 23:04:00 +03:00
										 |  |  | 			console.log('>>> args:', [...arguments]) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 				var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var words = 'Lorem ipsum dolor sit amet, audiam sensibus ' | 
					
						
							|  |  |  | 					+'an mea. Accusam blandit ius in, te magna dolorum ' | 
					
						
							|  |  |  | 					+'moderatius pro, sit id dicant imperdiet definiebas. ' | 
					
						
							|  |  |  | 					+'Ad duo quod mediocrem, movet laudem discere te mel, ' | 
					
						
							|  |  |  | 					+'sea ipsum habemus gloriatur at. Sonet prodesset ' | 
					
						
							|  |  |  | 					+'democritum in vis, brute vitae recusabo pri ad, ' | 
					
						
							|  |  |  | 					+'--- ' | 
					
						
							|  |  |  | 					+'latine civibus efficiantur at his. At duo lorem ' | 
					
						
							|  |  |  | 					+'legimus, errem constituam contentiones sed ne, ' | 
					
						
							|  |  |  | 					+'cu has corpora definitionem.' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var res = [] | 
					
						
							|  |  |  | 				words | 
					
						
							|  |  |  | 					.split(/\s+/g) | 
					
						
							|  |  |  | 					.unique() | 
					
						
							|  |  |  | 					.forEach(function(c){  | 
					
						
							|  |  |  | 						var e = make(c)  | 
					
						
							|  |  |  | 							// toggle opacity...
 | 
					
						
							|  |  |  | 							.on('open', function(){ | 
					
						
							|  |  |  | 								var e = $(this).find('.text') | 
					
						
							|  |  |  | 								e.css('opacity',  | 
					
						
							|  |  |  | 									e.css('opacity') == 0.3 ? '' : 0.3) | 
					
						
							|  |  |  | 							}) | 
					
						
							|  |  |  | 						res.push(e[0]) | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				$(res).parent() | 
					
						
							|  |  |  | 					.append($('<div>') | 
					
						
							|  |  |  | 						.sortable() | 
					
						
							|  |  |  | 						.append($(res))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.done() | 
					
						
							|  |  |  | 			},  | 
					
						
							|  |  |  | 			// make the dialog a cloud...
 | 
					
						
							|  |  |  | 			{ cloudView: true }) | 
					
						
							|  |  |  | 			// NOTE: this is not a dialog event, it is defined by the 
 | 
					
						
							|  |  |  | 			// 		container to notify us that we are closing...
 | 
					
						
							|  |  |  | 			.on('close', function(){ | 
					
						
							|  |  |  | 				console.log('Dialog closing...') | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 	exampleBrowsrItems: ['Test/-99: Demo browse $items...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var actions = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var editable_list = ['x', 'y', 'z'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 				var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('Heading:', { | 
					
						
							|  |  |  | 					doc: 'Heading doc string...', | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Group([ | 
					
						
							|  |  |  | 					make('Normal item'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// this is the same as make('...')
 | 
					
						
							|  |  |  | 					make.Separator(), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					make.Editable('Editable (Select to edit)'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					make.Editable('Editable (Enter to edit, cleared)...', { | 
					
						
							|  |  |  | 						start_on: 'open', | 
					
						
							|  |  |  | 						clear_on_edit: true, | 
					
						
							|  |  |  | 					}), | 
					
						
							|  |  |  | 				]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('List:') | 
					
						
							|  |  |  | 				make.List(['a', 'b', 'c']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading(' Editable list:') | 
					
						
							|  |  |  | 				make.EditableList(editable_list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('More:') | 
					
						
							|  |  |  | 				make.Action('Editable list demos...') | 
					
						
							|  |  |  | 					.on('open', function(){ actions.exampleList() }) | 
					
						
							|  |  |  | 				make.Action('Pinned list demo...') | 
					
						
							|  |  |  | 					.on('open', function(){ actions.examplePinnedList() }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// NOTE: the dialog's .parent is not yet set at this point...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// This will finalize the dialog...
 | 
					
						
							|  |  |  | 				//
 | 
					
						
							|  |  |  | 				// NOTE: this is not needed here as the dialog is drawn
 | 
					
						
							|  |  |  | 				// 		on sync, but for async dialogs this will align
 | 
					
						
							|  |  |  | 				// 		the selected field correctly.
 | 
					
						
							|  |  |  | 				make.done() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			// NOTE: this is not a dialog event, it is defined by the 
 | 
					
						
							|  |  |  | 			// 		container to notify us that we are closing...
 | 
					
						
							|  |  |  | 			.on('close', function(){ | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 	exampleList: ['Test/-99: Demo $lists editors in dialog...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var actions = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// NOTE: passing things other than strings into a list editor
 | 
					
						
							|  |  |  | 			// 		is not supported...
 | 
					
						
							|  |  |  | 			var numbers = ['1', '2', '3', '4'] | 
					
						
							|  |  |  | 			var letters = ['a', 'b', 'c', 'd'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 				var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('Numbers:', { | 
					
						
							|  |  |  | 					doc: 'List editor with all the buttons enabled...', | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				make.EditableList(numbers, {  | 
					
						
							|  |  |  | 					list_id: 'numbers', | 
					
						
							|  |  |  | 					item_order_buttons: true, | 
					
						
							|  |  |  | 					to_top_button: true, | 
					
						
							|  |  |  | 					to_bottom_button: true, | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('Letters:', { | 
					
						
							|  |  |  | 					doc: 'Sortable list, use sort handle to the right to sort...' | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				make.EditableList(letters, {  | 
					
						
							|  |  |  | 					list_id: 'letters',  | 
					
						
							|  |  |  | 					sortable: 'y', | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// NOTE: the dialog's .parent is not yet set at this point...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// This will finalize the dialog...
 | 
					
						
							|  |  |  | 				//
 | 
					
						
							|  |  |  | 				// NOTE: this is not needed here as the dialog is drawn
 | 
					
						
							|  |  |  | 				// 		on sync, but for async dialogs this will align
 | 
					
						
							|  |  |  | 				// 		the selected field correctly.
 | 
					
						
							|  |  |  | 				make.done() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			// NOTE: this is not a dialog event, it is defined by the 
 | 
					
						
							|  |  |  | 			// 		container to notify us that we are closing...
 | 
					
						
							|  |  |  | 			.on('close', function(){ | 
					
						
							|  |  |  | 				console.log(core.doc`Lists:
 | 
					
						
							|  |  |  | 				- Numbers: ${numbers.join(', ')} | 
					
						
							|  |  |  | 				- Letters: ${letters.join(', ')}`)
 | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 	examplePinnedList: ['Test/-99: Demo $pinned lists in dialog...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var actions = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// NOTE: passing things other than strings into a list editor
 | 
					
						
							|  |  |  | 			// 		is not supported...
 | 
					
						
							|  |  |  | 			var pins = ['b', 'a'] | 
					
						
							|  |  |  | 			var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 				var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.Heading('Numbers:', { | 
					
						
							|  |  |  | 					doc: 'List editor with all the buttons enabled...', | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				make.EditablePinnedList(letters, pins, {  | 
					
						
							|  |  |  | 					list_id: 'letters', | 
					
						
							|  |  |  | 					//pins_sortable: false,
 | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// NOTE: the dialog's .parent is not yet set at this point...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// This will finalize the dialog...
 | 
					
						
							|  |  |  | 				//
 | 
					
						
							|  |  |  | 				// NOTE: this is not needed here as the dialog is drawn
 | 
					
						
							|  |  |  | 				// 		on sync, but for async dialogs this will align
 | 
					
						
							|  |  |  | 				// 		the selected field correctly.
 | 
					
						
							|  |  |  | 				make.done() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			// NOTE: this is not a dialog event, it is defined by the 
 | 
					
						
							|  |  |  | 			// 		container to notify us that we are closing...
 | 
					
						
							|  |  |  | 			.on('close', function(){ | 
					
						
							|  |  |  | 				console.log(core.doc`Lists:
 | 
					
						
							|  |  |  | 				- Pins: ${pins.join(', ')} | 
					
						
							|  |  |  | 				- Letters: ${letters.join(', ')}`)
 | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	exampleProgress: ['Test/Demo $progress bar...', | 
					
						
							|  |  |  | 		function(text){ | 
					
						
							|  |  |  | 			var done = 0 | 
					
						
							|  |  |  | 			var max = 10 | 
					
						
							|  |  |  | 			var text = text || 'Progress bar demo' | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.showProgress(text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var step = function(){ | 
					
						
							|  |  |  | 				that.showProgress(text, done++, max) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				max = done < 8 ? max + 5  | 
					
						
							|  |  |  | 					: max <= 50 && done < 30 ? max + 2  | 
					
						
							|  |  |  | 					: done > 30 ? max - 3 | 
					
						
							|  |  |  | 					: max | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// NOTE: we add 10 here to compensate for changing max value...
 | 
					
						
							|  |  |  | 				done < max+10 | 
					
						
							|  |  |  | 					&& setTimeout(step, 200)  | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			setTimeout(step, 1000) | 
					
						
							|  |  |  | 		}],  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX make this a toggler....
 | 
					
						
							|  |  |  | 	partitionByMonth: ['Test/', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.toggleImageSort('?') != 'Date' && this.sortImages('Date') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.on('updateImage', function(_, gid){ this.placeMonthPartition(gid) }) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	// XXX this should be .updateImage(..) in a real feature...
 | 
					
						
							|  |  |  | 	placeMonthPartition: ['Test/', | 
					
						
							|  |  |  | 		function(image){ | 
					
						
							|  |  |  | 			var month = [ | 
					
						
							|  |  |  | 				'January', 'February', 'March', 'April', | 
					
						
							|  |  |  | 				'May', 'June', 'July', 'August', | 
					
						
							|  |  |  | 				'September', 'October', 'November', 'December' | 
					
						
							|  |  |  | 			] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var gid = this.data.getImage(image) | 
					
						
							|  |  |  | 			var next = this.data.getImage(gid, 'next') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			cur = this.images[gid]	 | 
					
						
							|  |  |  | 			next = this.images[next] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(cur && next && cur.birthtime.getMonth() != next.birthtime.getMonth()){ | 
					
						
							|  |  |  | 				this.ribbons.getImageMarks(gid).filter('.partition').remove() | 
					
						
							|  |  |  | 				this.ribbons.getImage(gid) | 
					
						
							|  |  |  | 					.after(this.ribbons.elemGID($('<div class="mark partition">'), gid) | 
					
						
							|  |  |  | 						.attr('text', month[next.birthtime.getMonth()])) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	exampleEmbededLister: ['Test/50: Lister example (embeded)/*', | 
					
						
							|  |  |  | 		function(path, make){ | 
					
						
							|  |  |  | 			make('a/') | 
					
						
							|  |  |  | 			make('b/') | 
					
						
							|  |  |  | 			make('c/') | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	exampleFloatingLister: ['Test/50:Lister example (floating)...', | 
					
						
							|  |  |  | 		function(path){ | 
					
						
							|  |  |  | 			// we got an argument and can exit...
 | 
					
						
							|  |  |  | 			if(path){ | 
					
						
							|  |  |  | 				console.log('PATH:', path) | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// load the UI...
 | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var list = function(path, make){ | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				make('a/') | 
					
						
							|  |  |  | 				make('b/') | 
					
						
							|  |  |  | 				make('c/') | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var o = overlay.Overlay(this.dom,  | 
					
						
							|  |  |  | 				browse.makePathList(null, { | 
					
						
							|  |  |  | 					'a/*': list, | 
					
						
							|  |  |  | 					'b/*': list, | 
					
						
							|  |  |  | 					'c/*': list, | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 					.open(function(evt, path){  | 
					
						
							|  |  |  | 						o.close()  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						that.exampleFloatingLister(path) | 
					
						
							|  |  |  | 					})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return o | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 	// XXX BUG: right limit indicator can get covered by the scrollbar...
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	// XXX migrate to the dialog framework...
 | 
					
						
							|  |  |  | 	// XXX use this.dom as base...
 | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 	// XXX BUG: this breaks keyboard handling when closed...
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	showTaggedInDrawer: ['- Test/Show tagged in drawer', | 
					
						
							|  |  |  | 		function(tag){ | 
					
						
							|  |  |  | 			tag = tag || 'bookmark' | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var H = '200px' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var viewer = $('<div class="viewer">') | 
					
						
							|  |  |  | 				.css({ | 
					
						
							|  |  |  | 					height: H, | 
					
						
							|  |  |  | 					background: 'black', | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 				.attr('tabindex', '0') | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 			// XXX use this.dom as base...
 | 
					
						
							|  |  |  | 			// XXX when using viewer zoom and other stuff get leaked...
 | 
					
						
							|  |  |  | 			var widget = drawer.Drawer($('body'),  | 
					
						
							|  |  |  | 				$('<div>') | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 					.addClass('image-list-widget') | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 					.css({ | 
					
						
							|  |  |  | 						position: 'relative', | 
					
						
							|  |  |  | 						height: H, | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 					.append(viewer), | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					focusable: true, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 				.on('close', function(){ | 
					
						
							| 
									
										
										
										
											2017-12-09 03:14:36 +03:00
										 |  |  | 					if(that.nested){ | 
					
						
							|  |  |  | 						that.nested.stop() | 
					
						
							|  |  |  | 						delete that.nested | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 02:32:35 +03:00
										 |  |  | 			var data = this.data.crop(this.data.tagQuery(tag), true) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// setup the viewer...
 | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 			this.nested = core.ImageGridFeatures | 
					
						
							|  |  |  | 				// setup actions...
 | 
					
						
							|  |  |  | 				.setup([ | 
					
						
							| 
									
										
										
										
											2017-12-09 03:26:44 +03:00
										 |  |  | 					'imagegrid-ui-preview', | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 				]) | 
					
						
							|  |  |  | 				.run(function(){ | 
					
						
							|  |  |  | 					this.close = function(){ widget.close() } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					this.config['keyboard-event-source'] = viewer  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// XXX hack -- need a better way to set this (a setter?)...
 | 
					
						
							|  |  |  | 					this.__keyboard_config = { | 
					
						
							|  |  |  | 						'Basic Control': { | 
					
						
							|  |  |  | 							pattern: '*', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							Home: 'firstImage!', | 
					
						
							|  |  |  | 							End: 'lastImage!', | 
					
						
							|  |  |  | 							Left: 'prevImage!', | 
					
						
							|  |  |  | 							ctrl_Left: 'prevScreen!', | 
					
						
							|  |  |  | 							meta_Left: 'prevScreen!', | 
					
						
							|  |  |  | 							PgUp: 'prevScreen!', | 
					
						
							|  |  |  | 							PgDown: 'nextScreen!', | 
					
						
							|  |  |  | 							Right: 'nextImage!', | 
					
						
							|  |  |  | 							ctrl_Right: 'nextScreen!', | 
					
						
							|  |  |  | 							meta_Right: 'nextScreen!', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							Esc: 'close!', | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				// load some testing data...
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 				.load({ | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 					viewer: viewer, | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 					data: data, | 
					
						
							|  |  |  | 					images: this.images,  | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				.fitImage(1) | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 					// XXX for some reason this is not called...
 | 
					
						
							|  |  |  | 					.refresh() | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 				// link navigation...
 | 
					
						
							|  |  |  | 				.on('focusImage', function(){ | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 					that.focusImage(this.current) }) | 
					
						
							|  |  |  | 				// start things up...
 | 
					
						
							|  |  |  | 				.start() | 
					
						
							|  |  |  | 				.focusImage() | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 			// XXX need to focus widget -- use a real trigger event instead of timer...
 | 
					
						
							|  |  |  | 			setTimeout(function(){ | 
					
						
							|  |  |  | 				that.nested.dom.focus() | 
					
						
							|  |  |  | 			}, 200) | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 01:39:06 +03:00
										 |  |  | 			return this.nested | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 		}], | 
					
						
							|  |  |  | 	showBookmarkedInDrawer: ['Test/Show bookmarked in drawer', | 
					
						
							|  |  |  | 		function(){ this.showTaggedInDrawer('bookmark') }], | 
					
						
							| 
									
										
										
										
											2018-11-08 21:10:58 +03:00
										 |  |  | 	showSelectedInDrawer: ['Test/Show marked in drawer', | 
					
						
							|  |  |  | 		function(){ this.showTaggedInDrawer('marked') }], | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	makePartitionAfter: ['Test/Make Partition after image', | 
					
						
							|  |  |  | 		function(image, text){ | 
					
						
							|  |  |  | 			var gid = this.data.getImage(image || 'current') | 
					
						
							|  |  |  | 			var attrs = { | 
					
						
							|  |  |  | 				gid: gid | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(text){ | 
					
						
							|  |  |  | 				attrs.text = text | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			this.ribbons.getImage(gid) | 
					
						
							|  |  |  | 				.after($('<span>') | 
					
						
							|  |  |  | 					.addClass('mark partition') | 
					
						
							|  |  |  | 					.attr(attrs)) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 04:30:50 +03:00
										 |  |  | 	// Combined dialog/lister...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// XXX should this be made into a constructor???
 | 
					
						
							| 
									
										
										
										
											2017-12-17 04:45:04 +03:00
										 |  |  | 	exampleDialogLister: ['Test/Combined dialog & lister (dialog mode)', | 
					
						
							| 
									
										
										
										
											2017-12-17 04:30:50 +03:00
										 |  |  | 		widgets.makeUIDialog(function(path, make){ | 
					
						
							|  |  |  | 			var makeList = function(_, make){ | 
					
						
							|  |  |  | 				make('A') | 
					
						
							|  |  |  | 				make('B') | 
					
						
							|  |  |  | 				make('C') | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return make instanceof Function ? | 
					
						
							|  |  |  | 				makeList(path, make) | 
					
						
							|  |  |  | 				: browse.makeLister(null, makeList) | 
					
						
							|  |  |  | 		})], | 
					
						
							| 
									
										
										
										
											2017-12-17 04:45:04 +03:00
										 |  |  | 	exampleDialogListerL: ['Test/Combined dialog & lister (lister mode)/*', | 
					
						
							|  |  |  | 		'exampleDialogLister: ...'], | 
					
						
							| 
									
										
										
										
											2017-12-25 07:19:33 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-14 03:29:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 07:19:33 +03:00
										 |  |  | 	testList: ['Test/List/*', | 
					
						
							|  |  |  | 		function(path, make){ return function(){ | 
					
						
							|  |  |  | 			make('A') | 
					
						
							|  |  |  | 			make('B') | 
					
						
							|  |  |  | 			make('C') | 
					
						
							|  |  |  | 		} }], | 
					
						
							| 
									
										
										
										
											2019-11-14 03:29:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 	// XXX should this use widgets.makeUIDialog(..)
 | 
					
						
							|  |  |  | 	// 		...BUG: currently it creates a second overlay...
 | 
					
						
							| 
									
										
										
										
											2019-11-14 03:29:30 +03:00
										 |  |  | 	exampleEditor: ['Test/Universal $editor...', | 
					
						
							|  |  |  | 		widgets.uiDialog(function(spec, callback){ | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 			return this.showEditor( | 
					
						
							| 
									
										
										
										
											2019-11-14 03:29:30 +03:00
										 |  |  | 				spec || [ | 
					
						
							|  |  |  | 					// basic field...
 | 
					
						
							|  |  |  | 					[['Basic static field: ', 'value']], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					{ title: '$Toggle: ', | 
					
						
							|  |  |  | 						type: 'toggle', }, | 
					
						
							|  |  |  | 					{ title: 'Direct toggle: ', | 
					
						
							|  |  |  | 						type: 'toggle', | 
					
						
							|  |  |  | 						values: ['a', 'b', 'c'], | 
					
						
							|  |  |  | 						list: false, }, | 
					
						
							|  |  |  | 					{ title: '$List toggle: ', | 
					
						
							|  |  |  | 						type: 'toggle', | 
					
						
							|  |  |  | 						values: ['first', 'second', 'third', 'last'], }, | 
					
						
							|  |  |  | 					{ title: '$Editable list toggle: ', | 
					
						
							|  |  |  | 						type: 'toggle', | 
					
						
							|  |  |  | 						values: ['sortable', 'renamable', 'removable', 'extendable'], | 
					
						
							|  |  |  | 						list_editable: true, }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					'---', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					{ title: 'Theme (config): ', | 
					
						
							|  |  |  | 						type: 'configToggle', | 
					
						
							|  |  |  | 						key: 'theme', | 
					
						
							|  |  |  | 						values_key: 'themes', | 
					
						
							|  |  |  | 						// optional...
 | 
					
						
							|  |  |  | 						live_update: true, | 
					
						
							|  |  |  | 						callback: function(cfg, value){ | 
					
						
							|  |  |  | 							this.toggleTheme(value) }, }, | 
					
						
							|  |  |  | 					{ title: 'Theme (toggler): ', | 
					
						
							|  |  |  | 						type: 'toggler', | 
					
						
							|  |  |  | 						toggler: 'toggleTheme', | 
					
						
							|  |  |  | 						// optional...
 | 
					
						
							|  |  |  | 						live_update: true, }, | 
					
						
							|  |  |  | 					{ title: 'Slideshow direction: ', | 
					
						
							|  |  |  | 						type: 'toggler', | 
					
						
							|  |  |  | 						toggler: 'toggleSlideshowDirection', }, | 
					
						
							|  |  |  | 				],  | 
					
						
							|  |  |  | 				callback || function(res, spec){ | 
					
						
							|  |  |  | 					console.log('EDITED:', res, spec) }) })], | 
					
						
							|  |  |  | 	exampleEmbededEditor: ['Test/Universal editor (embeded)...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return browse.makeLister(null, function(_, make){ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 					that.showEditor(make,  | 
					
						
							| 
									
										
										
										
											2019-11-14 03:29:30 +03:00
										 |  |  | 						// NOTE: we need to maintain the data between updates...
 | 
					
						
							|  |  |  | 						spec = spec  | 
					
						
							|  |  |  | 							|| [ | 
					
						
							|  |  |  | 								{ title: '$Toggle: ', | 
					
						
							|  |  |  | 									type: 'toggle', }, | 
					
						
							|  |  |  | 								{ title: 'Direct toggle: ', | 
					
						
							|  |  |  | 									type: 'toggle', | 
					
						
							|  |  |  | 									values: ['a', 'b', 'c'], | 
					
						
							|  |  |  | 									list: false, }, | 
					
						
							|  |  |  | 								{ title: '$List toggle: ', | 
					
						
							|  |  |  | 									type: 'toggle', | 
					
						
							|  |  |  | 									values: ['first', 'second', 'third', 'last'], }, | 
					
						
							|  |  |  | 								{ title: '$Editable list toggle: ', | 
					
						
							|  |  |  | 									type: 'toggle', | 
					
						
							|  |  |  | 									values: ['sortable', 'renamable', 'removable', 'extendable'], | 
					
						
							|  |  |  | 									list_editable: true, },  | 
					
						
							|  |  |  | 								'---', | 
					
						
							|  |  |  | 								{ title: 'Theme (toggler): ', | 
					
						
							|  |  |  | 									type: 'toggler', | 
					
						
							|  |  |  | 									toggler: 'toggleTheme', | 
					
						
							|  |  |  | 									// optional...
 | 
					
						
							|  |  |  | 									live_update: true, }, | 
					
						
							|  |  |  | 								// XXX BUG: toggler with two values does not seem to work...
 | 
					
						
							|  |  |  | 								{ title: 'Slideshow direction: ', | 
					
						
							|  |  |  | 									type: 'toggler', | 
					
						
							|  |  |  | 									toggler: 'toggleSlideshowDirection', }, | 
					
						
							|  |  |  | 							]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					make.Separator() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					make('Done', {open: function(){ make.dialog.close() }}) | 
					
						
							|  |  |  | 				}, { cls: 'table-view' }) })], | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	exampleEditor2: ['Test/Universal Editor (2)...', | 
					
						
							|  |  |  | 		widgets.makeUIDialog(function(spec, callback){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							| 
									
										
										
										
											2019-12-22 04:04:20 +03:00
										 |  |  | 			var d0 = {} | 
					
						
							| 
									
										
										
										
											2020-01-11 23:48:36 +03:00
										 |  |  | 			var b1, b2 | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 			return browse.makeLister(null, function(path, make){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make([ | 
					
						
							|  |  |  | 					'Action count:', | 
					
						
							|  |  |  | 					function(){ | 
					
						
							|  |  |  | 						return that.actions.length }, ]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.field('Fieatures:', | 
					
						
							|  |  |  | 					function(){ | 
					
						
							|  |  |  | 						return that.features.features.length }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				make.field('A', 'B') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-08 02:45:33 +03:00
										 |  |  | 				//make.field.Toggle('Toggle: ', 'on')
 | 
					
						
							| 
									
										
										
										
											2019-12-22 04:04:20 +03:00
										 |  |  | 				make.field.Toggle('Toggle: ', d0) | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 23:48:36 +03:00
										 |  |  | 				make.batch(b1 = b1 || [ | 
					
						
							| 
									
										
										
										
											2019-12-22 04:01:14 +03:00
										 |  |  | 					'---', | 
					
						
							|  |  |  | 					[['X', 'Y']], | 
					
						
							|  |  |  | 					{title: 'foo', value: 123}, | 
					
						
							| 
									
										
										
										
											2020-01-11 23:48:36 +03:00
										 |  |  | 					{type: 'field.Toggle', title: 'Batch toggle 1: '}, | 
					
						
							| 
									
										
										
										
											2019-12-22 04:01:14 +03:00
										 |  |  | 				]) | 
					
						
							| 
									
										
										
										
											2020-01-15 02:31:55 +03:00
										 |  |  | 				make.field.batch( | 
					
						
							|  |  |  | 					b2 = b2 || [ | 
					
						
							|  |  |  | 						'---', | 
					
						
							|  |  |  | 						['X', 'Y'], | 
					
						
							|  |  |  | 						{type: 'Toggle', title: 'foo', values: ['1','2','3'], list: false}, | 
					
						
							| 
									
										
										
										
											2020-02-24 23:36:16 +03:00
										 |  |  | 						{type: 'Toggle', title: 'foo (w. list)', values: ['1','2','3']}, | 
					
						
							| 
									
										
										
										
											2020-01-15 02:31:55 +03:00
										 |  |  | 						{type: 'Toggle', title: 'Batch toggle 2: '}, | 
					
						
							|  |  |  | 					],  | 
					
						
							|  |  |  | 					function(){ | 
					
						
							|  |  |  | 						console.log('-- (2nd batch) --', ...arguments) }) | 
					
						
							| 
									
										
										
										
											2019-12-01 18:00:41 +03:00
										 |  |  | 			}, { | 
					
						
							|  |  |  | 				cls: 'table-view', | 
					
						
							|  |  |  | 			}) })], | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ExampleUI =  | 
					
						
							|  |  |  | module.ExampleUI = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tag: 'ui-action-examples', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'ui-browse-actions', | 
					
						
							|  |  |  | 	], | 
					
						
							| 
									
										
										
										
											2017-12-25 07:19:33 +03:00
										 |  |  | 	suggested: [ | 
					
						
							|  |  |  | 		'ui-action-examples-2', | 
					
						
							|  |  |  | 	], | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | 	actions: ExampleUIActions, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 07:19:33 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ExampleUI2Actions = actions.Actions({ | 
					
						
							|  |  |  | 	testList: ['Test/List/*', | 
					
						
							|  |  |  | 		function(path, make){ return function(){ | 
					
						
							|  |  |  | 			make('---') | 
					
						
							|  |  |  | 			make('X') | 
					
						
							|  |  |  | 			make('Y') | 
					
						
							|  |  |  | 			make('Z') | 
					
						
							|  |  |  | 		} }], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ExampleUI =  | 
					
						
							|  |  |  | module.ExampleUI = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tag: 'ui-action-examples-2', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'ui-action-examples', | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 	actions: ExampleUI2Actions, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 13:52:31 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | core.ImageGridFeatures.Feature('examples', [ | 
					
						
							|  |  |  | 	'action-examples', | 
					
						
							|  |  |  | 	'ui-action-examples', | 
					
						
							|  |  |  | ]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-18 17:57:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-04 17:56:14 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |