# 03. __Globals__

[![+Professional Support](https://www.totaljs.com/img/badge-support.svg)](https://www.totaljs.com/support/) [![+Chat with contributors](https://www.totaljs.com/img/badge-chat.svg)](https://messenger.totaljs.com)

This is very important part of the jComponent library because this part contains documentation for all global properties and methods defined in `window` scope.

__Quick navigation__:

- [Properties](#)
- [Methods](#)

---

## Properties

- [`DAYS`](#property-days-)
- [`DEF`](#property-def-)
- [`EMPTYARRAY`](#property-emptyarray-)
- [`EMPTYOBJECT`](#property-emptyobject-)
- [`FUNC`](#property-func-)
- [`isMOBILE`](#property-ismobile-)
- [`isPRIVATEMODE`](#property-isprivatemode-)
- [`isROBOT`](#property-isrobot-)
- [`isSTANDALONE`](#property-isstandalone-)
- [`isTOUCH`](#property-istouch-)
- [`MONTHS`](#property-months-)
- [`NOW`](#property-now-)
- [`REPO`](#property-repo-)

### Property: `DAYS`

Property contains names of days. Of course, you can localize it.

```javascript
DAYS;
// returns {Array String}

console.log(DAYS[0]);
// Output: Sunday
```

### Property: `DEF`

Contains preddefined configuration for the entire library and components. More info in __02. Library__ section.

- [Show all variables](@17092508010002yge0#property-main-defaults-)

```javascript
DEF;
// returns {Object}

// E.g.
DEF.fallbackcache = '5 minutes';
```

### Property: `EMPTYARRAY`

`readonly` This property returns readonly empty `Array`.

```javascript
EMPTYARRAY;
// returns {Array}
```

### Property: `EMPTYOBJECT`

`readonly` This property returns readonly empty `Object`.

```javascript
EMPTYOBJECT;
// returns {Object}
```

### Property: `FUNC`

`+v16` This property returns empty object for storing inline functions.

```javascript
FUNC;
// returns {Object}
```

### Property: `isMOBILE`

`readonly` It detects a mobile device.

```javascript
isMOBILE;
// returns {Boolean}
```

### Property: `isPRIVATEMODE`

Determines whether localStorage is `disabled` --> `PRIVATEMODE = true`.

```javascript
PRIVATEMODE;
// returns {Boolean}

console.log(PRIVATEMODE);
// Output: false
```

### Property: `isROBOT`

`readonly` It detects a robot/crawler.

```javascript
isROBOT;
// returns {Boolean}
```

### Property: `isSTANDALONE`

`readonly` It detects a standalone application.

```javascript
isSTANDALONE;
// returns {Boolean}
```

### Property: `isTOUCH`

`readonly` It detects a touch display.

```javascript
isTOUCH;
// returns {Boolean}
```

### Property: `MONTHS`

Property contains names of months. Of course, you can localize it.

```javascript
MONTHS;
// returns {Array String}

console.log(MONTHS[0]);
// Output: January
```

### Property: `NOW`

Property contains a current `Date` object. It's refreshed in 1 minute.

```javascript
NOW;
// returns {Date}
```

### Property: `REPO`

`+v17` This property returns empty object for storing temporary values.

```javascript
REPO;
// returns {Object}
```


## Methods

- [`ADD(declaration, [element], [config], [html])`](#method-add-)
- [`AEXEC(path, [a], [b], [..n])`](#method-aexec-)
- [`ASETTER(selector, propOrMethod, [argA], [argB], [..argN])`](#method-asetter-)
- [`AJAX(options, [data], callback/path, [delay])`](#method-ajax-)
- [`AJAXCACHE(options, data, callback/path, expiration, [delay], [clear])`](#method-ajaxcache-)
- [`AJAXCACHEREVIEW(options, data, callback/path, expiration, [delay], [clear])`](#method-ajaxcachereview-)
- [`AJAXCONFIG(name, callback)`](#method-ajaxconfig-)
- [`BIND(path)`](#method-bind-)
- [`BLOCKED(key, [expiration])`](#method-blocked-)
- [`CACHE(key, [value], [expiration])`](#method-cache-)
- [`CACHEPATH(key, expiration, [rebind])`](#method-cachepath-)
- [`CAN(path, [except])`](#method-can-)
- [`CHANGE(path, [isChange])`](#method-change-)
- [`CHANGED(path, [isChange])`](#method-changed-)
- [`CLEARCACHE()`](#method-clearcache-)
- [`CLEARSCHEDULE(id)`](#method-clearschedule-)
- [`clearTimeout2(id)`](#method-cleartimeout2-)
- [`CLONE(obj)`](#method-clone-)
- [`CMD(name, [a], [b], [n..])`](#method-cmd-)
- [`COMPILE([container])`](#method-compile-)
- [`COMPONENT(name, [config], declaration, [dependencies])`](#method-component-)
- [`CONFIG(selector, config]`](#method-config-)
- [`COPY(from, to)`](#method-copy-)
- [`CSS(value, [id], [wrap_selector])`](#method-css-)
- [`DEFAULT(path, [delay], [reset])`](#method-default-)
- [`DIFFDOM(el, selector, html)`](#method-diffdom-)
- [`DISABLED(path, [except])`](#method-disabled-)
- [`EMIT(name, [a], [b], [..n])`](#method-emit-)
- [`ENV(key, [value])`](#method-env-)
- [`ERRORS(path, [except], [highlight])`](#method-errors-)
- [`EVALUATE(path, expression, [path_is_real_value])`](#method-evaluate-)
- [`EXEC(path, [a], [b], [..n])`](#method-exec-)
- [`EXTEND(path, value, [type/delay], [reset])`](#method-extend-)
- [`EXTEND2(path, value, [type/delay])`](#method-extend2-)
- [`EXTENSION(selector, [config], declaration]`](#method-extension-)
- [`FREE([timeout])`](#method-free-)
- [`FIND(selector, [many], [callback], [timeout])`](#method-find-)
- [`FORMATTER(path, value, type, format)`](#method-formatter-)
- [`FN(expression)`](#method-fn-)
- [`GET(path, [callback])`](#method-get-)
- [`GETM(path])`](#method-getm-)
- [`GETR(path])`](#method-getr-)
- [`GETU(path])`](#method-getu-)
- [`GUID([length])`](#method-guid-)
- [`HASH(value)`](#method-hash-)
- [`IMPORT(url, [target], [callback], [insert], [preparator])`](#method-import-)
- [`IMPORTCACHE(url, [expire], [target], [callback], [insert], [preparator])`](#method-importcache-)
- [`INC(path, value, [type/delay], [reset])`](#method-inc-)
- [`INC2(path, value, [type/delay])`](#method-inc2-)
- [`INVALID(path)`](#method-invalid-)
- [`MAKE([path], fn)`](#method-make-)
- [`MEDIAQUERY(query, [element], callback)`](#method-mediaquery-)
- [`MIDDLEWARE(name, fn)`](#method-middleware-)
- [`MODIFY(path, value, [timeout])`](#method-modify-)
- [`MODIFIED(path)`](#method-modified-)
- [`NOOP()`](#method-noop-)
- [`NOTIFY(pathA, [pathB], [..pathN])`](#method-notify-)
- [`NOTMODIFIED(path, [value], [fields])`](#method-notmodified-)
- [`NOTFOCUSED()`](#method-notfocused-)
- [`NULL()`](#method-null-)
- [`OFF(name, [handler])`](#method-off-)
- [`ON(name, handler)`](#method-on-)
- [`OPT(fn(set))`](#method-opt-)
- [`PARSE(value, [date])`](#method-parse-)
- [`PARSER(path, value, type, format)`](#method-parser-)
- [`PING(url, [delay])`](#method-ping-)
- [`PLUGIN(name, [declaration])`](#method-plugin-)
- [`PUSH(path, value, [type/delay], [reset])`](#method-push-)
- [`PUSH2(path, value, [type/delay])`](#method-push2-)
- [`READPARAMS([query])`](#method-readparams-)
- [`RECONFIGURE(selector, config)`](#method-reconfigure-)
- [`REMOVECACHE(key, [isSearching])`](#method-removecache-)
- [`RESET(path, [delay])`](#method-reset-)
- [`REPEAT([condition], [processor], [delay], [init])`](#method-repeat-)
- [`RETURN(selector, [multiple])`](#method-return-)
- [`REWRITE(path, value, [type])`](#method-rewrite-)
- [`REWRITE2(path, value, [type])`](#method-rewrite2-)
- [`SCHEDULE(selector, type, delay, callback)`](#method-schedule-)
- [`SCHEMA(name, [declaration])`](#method-schema-)
- [`SCOPE(name, [scopeFn])`](#method-scope-)
- [`SCROLLBARWIDTH()`](#method-scrollbarwidth-)
- [`SEEX(path, a, [b], [c], [d])`](#method-seex-)
- [`SET(path, value, [type/delay], [reset])`](#method-set-)
- [`SET2(path, value, [type/delay])`](#method-set2-)
- [`SETR(path, value, [type])`](#method-setr-)
- [`setTimeout2(key, fn, timeout, [limit], [param])`](#method-settimeout2-)
- [`SETTER([wait], selector, propOrMethod, [argA], [argB], [..argN])`](#method-setter-)
- [`SKIP(pathA, [pathB], [pathN])`](#method-skip-)
- [`STRINGIFY(obj, [compress], [fields])`](#method-stringify-)
- [`TOGGLE(name, [type/delay], [reset]`](#method-toggle-)
- [`TOGGLE2(name, [type/delay])`](#method-toggle2-)
- [`VALID(path, [except])`](#method-valid-)
- [`VALIDATE(path, [except])`](#method-validate-)
- [`VERSION(a, [b], [n])`](#method-version-)
- [`QUEUE([name], fn)`](#method-queue-)
- [`UPLOAD(url, data, path/callback, [delay], [progress])`](#method-upload-)
- [`UPD(path, [type/delay], [reset])`](#method-upd-)
- [`UPD2(path, [type/delay])`](#method-upd2-)
- [`WAIT(path/fn, callback, [interval], [timeout])`](#method-wait-)
- [`WATCH(path, handler, [init])`](#method-watch-)

### Method: `ADD()`

`+v16` The method can create new components dynamically. __IMPORTANT__: an element must be attached element in `DOM`. `+v17` adds `config` and `html` argument.

```javascript
ADD(declaration, [element]);
// @declaration {String/String Array}
// @element {jQuery Element/Component/Scope/Plugin) optional, a parent element (default: "document.body")
// @config {Object) optional, a component configuration
// @html {String} optional, a default HTML content for the component

ADD('textbox__form.name__required:true;label:Test');

// or

ADD(['textbox__form.name__required:true;label:Test', 'checkbox__form.terms__label:I aggree with terms'], $('#tab'));

// or +v17:
ADD('textbox__form.name', { required: true, placeholder: 'Something' }, 'Name');

// or +v18
// "!" means that ADD() method checks existence of "loading" component and
// if it doesn't exist then the library will add id
ADD('!loading');
```

### Method: `AEXEC()`

`+v18` Returns a `function` (means like a callback) which contains an EXEC implementation. Last arguments are values from the function. It's targeted primary for `AJAX` operations.

```javascript
AJAX('POST /api/products/', model, AEXEC('products/refresh'));
```

### Method: `ASETTER()`

`+v18` Returns a `function` (means like a callback) which contains a SETTER implementation. Last arguments are values from the function. It's targeted primary for `AJAX` operations.

```javascript
AJAX('POST /api/products/', model, ASETTER('message/success', 'Product has been saved successfully'));

// Another example:
var fn = ASETTER('message/success')
fn('Product has been saved successfully');
```

### Method: `AJAX()`

The method creates an asynchronous request to a backend.

- CORS is enabled on all URL addresses witch start `http://` or `https://`
- Default AJAX headers are stored in [`DEF.headers`](@17092508010002yge0#property-main-defaults-)
- Event for all AJAX errors: `ON('error', function(response) {})`
- Event for all AJAX responses: `ON('response', function(response) {})`
- JSON is parsed as `JSON` and JSON dates are converted to `Date` automatically

```javascript
AJAX(options, [data], callback/path, [delay]);
// @options {String}
// @data {Object/String}
// @callback {Function} or @path {String}
// @delay {Number} Delay in milliseconds
// returns {jComponent}

// Without callback
// Response will be stored in "window.products.items" variable
AJAX('GET /api/products/', { search: 'Something' }, 'products.items');

// With a callback
AJAX('GET https://www.totaljs.com', function(value, err, response) {

	if (err) {
		// Error handling
	}

	// response.url      {String} URL address
	// response.process  {Boolean} Can disable future processing.
	// response.error    {Boolean} Is error?
	// response.upload   {Boolean} Is upload?
	// response.method   {String} Request method
	// response.data     {Object} Request data
	// response.response {String} Response content
	// response.status   {Number} HTTP status code
	// response.text     {String} HTTP status text
	// response.headers  {Object} Response headers
	// response.duration {Number} +v18 in milliseconds

	console.log(value);
});

// Request with custom headers
AJAX('GET /api/products/ {"x-token":"CUSTOM HEADER"}', 'products.items');

// Environment usage
// e.g. ENV('productsurl', '/api/products/');
// +v11
AJAX('GET [productsurl]', 'products.items');
// [productsurl] will be replaced for "/api/products/"

// Enable CORS with credentials
// +v11
AJAX('!GET https://api.domain.com/products/', 'products.items');

// Request with a custom configuration
// Read more in AJAXCONFIG() method
// +v12
AJAX('GET (customConfig) /api/products/', 'products.items');
AJAX('GET (custom1, custom2, custom3) /api/products/', 'products.items');

// Remapping
// +v12
AJAX('GET /api/products/', 'items --> products.items'); // is same as:
AJAX('GET /api/products/', function(response) {
	SET('products.items', response.items);
});

// Repeat mode
// "Repeat mode" tries to repeat a request if the connetion is lost, can be
// used for important requests.
// +v16
AJAX('GET /api/products/ REPEAT', 'products.items');

// Sync mode
// "Sync mode" performs request only when AJAX is not waiting for another request
// +v17
AJAX('GET /api/products/ SYNC', 'products.items');

// Cancel mode
// "Cancel mode" performs cancelation of previous request (method + URL without query arguments) if the request is still running
// +v17
AJAX('GET /api/products/ CANCEL', 'products.items');

// Request ID
// +v18 allows to specify request ID for canceling of specific requests
// Form:
AJAX('GET /api/products/ CANCEL #products', 'products.items');

// +v18 allows to specify cache
AJAX('GET /api/products/ <2 minutes>', 'products.items');

// +v18 response application/json otherwise response will be "null"
// Form:
AJAX('GET /api/products/ JSON', 'products.items');

// +v18 disables encryption
// Form:
AJAX('POST /api/products/ NOENCRYPT', {}, NOOP);
```

### Method: `AJAXCACHE()`

The method creates an asynchronous request to a backend with caching. Supports same features as `AJAX()`.

```javascript
AJAXCACHE(options, data, callback/path, expiration, [delay], [clear]);
// @options {String}
// @data {Object/String}
// @callback {Function} or @path {String}
// @expiration {String} In the form: "number [seconds, minutes, hours, days, weeks, months, years]"
// @delay {Number} Delay in milliseconds
// @clear {Boolean} Clears a previous cache
// returns {jComponent}

// Without callback
AJAXCACHE('GET /api/products/', null, 'products.items', '5 minutes');

// With a callback
AJAXCACHE('GET /api/products/', null, function(value, isFromCache) {
	console.log('Is from cache?', isFromCache);
}, '5 days');
```

### Method: `AJAXCACHEREVIEW()`

The method reads a data from cache and creates independent asynchronous request to a backend with caching/comparing from the cache. Supports same features as `AJAX()`.

```javascript
AJAXCACHEREVIEW(options, data, callback/path, expiration, [delay], [clear]);
// @options {String}
// @data {Object/String}
// @callback {Function} or @path {String}
// @expiration {String} In the form: "number [seconds, minutes, hours, days, weeks, months, years]"
// @delay {Number} Delay in milliseconds
// @clear {Boolean} Clears a previous cache
// returns {jComponent}

// Without callback
AJAXCACHEREVIEW('GET /api/products/', null, 'products.items', '5 days');

// With a callback
AJAXCACHEREVIEW('GET /api/products/', null, function(value, isFromCache, areDifferent) {
	console.log('Is from cache?', isFromCache);
	console.log('Are data different?', areDifferent == true);
}, '5 days');
```

### Method: `AJAXCONFIG()`

The method creates a schema of configuration for all `AJAX()` methods.

```javascript
AJAXCONFIG(name, callback);
// @name {String}
// @fn {Function(req)}
// returns {jComponent}
// +v12.0.0

AJAXCONFIG('tokenizer', function(req) {
	req.headers['x-token'] = 'custom header';
	// req.type = 'GET';
});

// Usage in AJAX():
AJAX('GET (tokenizer) /api/products/', ...);
```

### Method: `BIND()`

The method will rebind all (data-)binds based on path

```javascript
BIND(path);
// @path {String}

BIND('form')
// or
BIND('?') // works with scopes
```

### Method: `BLOCKED()`

The method can lock some code for a specific time. __IMPORTANT__: this method will store info about blocking in `localStorage` if the expiration is longer than 10 seconds.

```javascript
BLOCKED(name, timeout);
// @name {String}
// @expiration {Number/String} +v12.0.6 supports environment values too
// returns {Boolean}

if (BLOCKED('submit', '3 seconds'))
	return;

// or

if (BLOCKED('submit', 3000))
	return;
```

### Method: `CACHE()`

The method can set a value to cache or can get a value from cache. Cache keeps data in `localStorage`.

```javascript
CACHE(key, [value], [expiration]);
// @key {String}
// @value {Object}
// @expiration {String} In the form: "number [seconds, minutes, hours, days, weeks, months, years]"
// returns {Object}

// Writing:
CACHE('key', 'value', '5 minutes'); 

// Reading:
console.log(CACHE('key'));
```

### Method: `CACHEPATH()`

The method can store the last value of `path` in `cache`. If the page is refreshed the last value will be recovered.

```javascript
CACHEPATH(path, [expiration], [rebind]);
// @path {String}
// @expiration {String} In the form: "number [seconds, minutes, hours, days, weeks, months, years]"
// @rebind {Boolean} Sets the value to path automatically (default: true)

CACHEPATH('user.name', '5 minutes');

// How to set a default values for the specific path?
MAKE('user', function(obj) {
	if (obj.name == null)
		obj.name = 'DEFAULT NAME';
});
```

### Method: `CAN()`

The method checks `dirty` and `valid` states for all declared components on the `path`. If the method return `true` then the components are validated and some component has been changed by user (otherwise: `false`).

```javascript
CAN(path, [except]);
// @path {String}
// @except {Array String} With absolute paths for skipping
// returns {Boolean}

if (CAN('users.form.*'))
	submit();
	
// or you can use it for disabling of buttons like this:
$('button.submit').prop('disabled', !CAN('users.form.*'));

// +v13.0.0 supports "except" flags
// @hidden - jComponent finds all hidden components
// @visible - jComponent finds all visible components
// @disabled - jComponent finds all components which have disabled inputs
// @enabled - jComponent finds all components which have enabled inputs
if (CAN('users.form.*', ['@visible', '@enabled'))
	submit();
```

### Method: `CHANGE()`

`+v15` The method can set a change for the path or can read the state, it works with `dirty` state.

```javascript
CHANGE(path, [isChange]);
// @path {String}
// @isChange {Boolean} Can rewrite change (default: "true")
// returns {Boolean}

// Set the change for this path:
CHANGE('users.form.name', true);
CHANGE('users.form.name'); // same

// Unset the change for this path:
CHANGE('users.form.name', false);
```

### Method: `CHANGED()`

`+v15` The method reads a state, it works with `dirty` state.

```javascript
CHANGED(path);
// @path {String}
// returns {Boolean}

// Reading state:
if (CHANGED('users.form.*')) {
	// Path has been changed
}
```

### Method: `CLEARCACHE()`

`+v14.1.1` The method clears a `localStorage` cache according to the `MAIN.$localstorage` property.

```javascript
CLEARCACHE();
```

### Method: `CLEARSCHEDULE()`

The method clears a scheduler generated by `SCHEDULE()`.

```javascript
CLEARSCHEDULER(id);
// @id {Number}
```

### Method: `clearTimeout2()`

The method clears a registered by `setTimeout2()`.

```javascript
clearTimeout2(id);
// @id {Number}
```

### Method: `CLONE()`

The method can clone an object to a new. `v12.0.6` supports `path` as `obj` and the method clones an object according to the path.

```javascript
CLONE(obj);
// @obj {Object/String}
// returns {Object}

var userA = { id: 1, name: 'Peter' };
var userB = CLONE(userA);
console.log(userA === userB);
// Output: false

userB.name = 'Lucia';
console.log(userA, userB);
// Output: { id: 1, name: Peter }, { id: 1, name: Lucia }


// +v12.0.6
var clone = CLONE('path.to.object');
```

### Method: `CMD()`

`+v17` Executes a command in all components. It executes a registered method via `component.command()`.

```javascript
CMD(name, [a], [b], [n..]);
// @name {String} A command name
// @a {Object} Argument A
// @b {Object} Argument B
// @c {Object} Argument N

CMD('mycommand');
```

### Method: `COMPILE()`

The method compiles new injected jComponents. If some component appends new components dynamically then is needed to call `COMPILE()` method manually.

```javascript
COMPILE([container]);
// @container {jQuery Element} Compiles components within container otherwise in the whole "document.body"
```

### Method: `COMPONENT()`

The method registers a new reusable component.

```javascript
COMPONENT(name, [config], declaration, [dependencies]);
// @name {String}
// @config {String} A default configuration
// @declaration {Function(instance, config)}
// @dependencies {Array String} +v12.0.4 optional, can contain URL addresses (script, styles, etc.) to all dependencies

COMPONENT('helloworld', 'fontsize:20px', function(self, config) {

	self.readonly();
	
	self.make = function() {
		self.html('HELLO WORLD!');
	};

	self.configure = function(key, value, init) {
		if (key === 'fontsize')
			self.css('font-size', value);
	});
	
});
```

### Method: `CONFIG()`

`+v17` The method sets a default configuration for all components according to the `selector`. `COMPONENT_CONFIG` is currently alias to this method.

```javascript
CONFIG(selector, config);
// @selector {String}
// @config {String/Object} A default configuration

// Possibilities:
CONFIG('component-name', 'required:true;placeholder:Modified config');
CONFIG('component-name .component-path', 'required:true;placeholder:Modified config');
CONFIG('#component-id', 'required:true;placeholder:Modified config');
CONFIG('#component-id .component-path', 'required:true;placeholder:Modified config');
CONFIG('.component-path', 'required:true;placeholder:Modified config');
CONFIG('*search-in-component-path', 'required:true;placeholder:Modified config');

CONFIG(function(com) {
	// com === instance of the Component, but not fully initialized
	return true;
}, 'required:true;placeholder:Modified config');

// OR

CONFIG('component-name', function() {
	// this === component instance (but not fully loaded)
	return 'required:true;placeholder:Modified config';
});

// +v18 supports multiple selectors separated by comma
CONFIG('listing, serverlisting, datagrid', 'margin:50');
```

### Method: `COPY()`

`+v16` The method copies all values from `from` object to `to` object.

```javascript
COPY(obj_from, obj_to);
// @obj_from {Object}
// @obj_to {Object}
// returns {Object} "obj_to" object
```

### Method: `CSS()`

The method creates inline CSS registered in the `head` tag. If you use `id` and execute `CSS()` twice then the previous styles will be removed.

```javascript
CSS(value, [id], [wrap_selector]
// @value {String} or {Array String}
// @id {String} Optional, CSS identificator
// @wrap_selector {String} +v18 wraps all styles to this selector

CSS('body { background-color: red; font-size: 18px; }\ndiv { background-color: black; color: white; }');

// With a selector:
CSS('figure { background-color: red; font-size: 18px; }\ndiv { background-color: black; color: white; }', null, '.mycomponent');
```

```css
.mycomponent figure { background-color: red; font-size: 18px; }
.mycomponent div { background-color: black; color: white; }
```

### Method: `DEFAULT()`

The method sets default values for all declared components listen on the path. All components need to have declared `data-jc-value="VALUE"` attribute.

```javascript
DEFAULT(path, [delay], [reset]);
// @path {String}
// @delay {Number} Optional, default: 0
// @reset {Boolean Optional, default: true

DEFAULT('users.form.*');

// +v16 can change the model via "__DefaultValue"
DEFAULT('users.form.*__{}');
// Assings {} - empty object to users.form and performs DEFAULT()

DEFAULT('users.form.*__[]');
// Assings [] - empty array to users.form and performs DEFAULT()
```

### Method: `DIFFDOM()`

`+v17` The method compares and modifies the content of the element with `HTML` string. `HTML` string is compiled to __Virtual DOM__.

```javascript
DIFFDOM(el, selector, html);
// @el {HTMLElement}
// @selector {String} jQuery selector
// @html {String}
// returns {Object}

var output = DIFFDOM($('#myproducts')[0], '.product', '<div class="product">Shoes</div><div class="product">T-Shirts</div><div class="product">Socks</div>');
console.log(output);
// { add: 1, upd: 2, rem: 1 }
```

### Method: `DISABLED()`

The method checks `dirty` and `valid` states for all declared components on the `path`. If the method return `false` then the components are validated and some component has been changed by user (otherwise: `true`).

```javascript
DISABLED(path, [except]);
// @path {String}
// @except {Array String} With absolute paths for skipping
// returns {Boolean}

if (!DISABLED('users.form.*'))
	submit();
	
// or you can use it for disabling of buttons like this:
$('button.submit').prop('disabled', DISABLED('users.form.*'));

// +v13.0.0 supports "except" flags
// @hidden - jComponent finds all hidden components
// @visible - jComponent finds all visible components
// @disabled - jComponent finds all components which have disabled inputs
// @enabled - jComponent finds all components which have enabled inputs
if (!DISABLED('users.form.*', ['@visible', '@enabled']))
	submit();
```

### Method: `EMIT()`

The method emits event within events declared in jComponent library.

```javascript
EMIT(name, [a], [b], [..n]);
// @name {String}
// @a {Object} Optional, additional argument
// @b {Object} Optional, additional argument
// @..n {Object} Optional, additional argument

EMIT('users.create', user);
```

### Method: `ENV()`

The method gets/sets a value to/from jComponent environments.

```javascript
ENV(key, [value]);
// @key {String}
// @value {Object} Optional
// returns {Object}

ENV('productsurl', '/api/products/');
console.log(ENV('productsurl'));
// Output: /api/products/
```

### Method: `ERRORS()`

The method returns `Array` of all not validated components.

```javascript
ERRORS(path, [except], [highlight]);
// @path {String}
// @except {Array String} Optional With absolute paths for skipping
// @highlight {Boolean} Optional, can highlight components (default: false)
// returns {Array Component}

console.log(ERRORS('users.form.*'));

// +v13.0.0 supports "except" flags
// @hidden - jComponent finds all hidden components
// @visible - jComponent finds all visible components
// @disabled - jComponent finds all components which have disabled inputs
// @enabled - jComponent finds all components which have enabled inputs
console.log(ERRORS('users.form.*', ['@visible', '@enabled']);
```

### Method: `EVALUATE()`

The method can evaluate `String` expression as JavaScript code.

```javascript
EVALUATE(path, expression, [path_is_real_value]);
// @path {String/Object} Can be object if "path_is_real_value" is "true"
// @expression {String} A condition.
// @path_is_real_value {Boolean} Optional, default: false
// returns {Boolean}

// With reading a value according to the "path"
var isTeenager = EVALUATE('users.form.age', 'value >= 10 && value <= 20');

// With a real value
var isTeenager = EVALUATE(15, 'value >= 10 && value <= 20', true);
```

### Method: `EXEC()`

The method executes a method according to the path. It wont't throw any exception if the method not exist. Supports execution of:

- `method` according the path
- `method` in the `controllers`
- `events`
- supports environments

```javascript
EXEC([wait], path, [a], [b], [..n]);
// @wait {Boolean} enables a waiter for the method instance (if method doesn't exist)
// @path {String}
// @a {Object} Optional, additional argument
// @b {Object} Optional, additional argument
// @..n {Object} Optional, additional argument

EXEC('users_refresh');
// Executes --> window.users_refresh();

EXEC('users_refresh', true);
// Executes --> window.users_refresh(true);

EXEC('#submit', true);
// Executes --> EMIT('submit', true);

EXEC('PLUGIN/method_name');
EXEC('@PLUGIN.method_name');
```

### Method: `EXTEND()`

The method extends a path by adding/rewrite new fields with new values.
`+v18` **SUPPORTS API REQUEST**

```javascript
EXTEND(path, value, [type/delay], [reset]);
// @path {String}
// @value {Object}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, default: false

EXTEND('users.form', { age: 35, alias: 'Peter' });

// +v18
EXTEND('GET /api/users/', 'users');
// or with cache 2 minutes
EXTEND('GET /api/users/ <2 minutes>', 'users');
```

### Method: `EXTEND2()`

`+v16` The method extends a path by adding/rewrite new fields with new values and performs `CHANGE()`.

```javascript
EXTEND2(path, value, [type/delay]);
// @path {String}
// @value {Object}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
```

### Method: `EXTENSION()`

`+v17` The method can extend a component by adding new features. `COMPONENT_EXTEND()` is alias for this method.

```javascript
EXTENSION(name, [config], declaration);
// @name {String}
// @config {String} Optional, a default configuration
// @declaration {Function}

// Possibilities:
EXTENSION('component-name', 'name:Custom config;width:300', function(self, config) {
	self.element.append('<div>EXTENDED 1</div>');
});

EXTENSION('component-name', function(self, config) {
	self.element.append('<div>EXTENDED 2</div>');
});

// With description
EXTENSION('component-name:description', function(self, cofnig) {
	self.element.append('<div>EXTENDED 3</div>');
});
```

### Method: `FREE()`

Manual cleaning of removed components

```javascript
FREE([timeout]);
// @timeout {Number} Optional, a in milliseconds (default: 10)
```

### Method: `FIND()`

The method finds all component according to the selector.

```javascript
FIND(selector, [many], [callback], [timeout]);
// @selector {String}
// @many {Boolean} Optional, output will be Array
// @callback {Function(response)} Optional and the method will be wait for non-exist components
// @timeout {Number} Optional, in milliseconds (default: 0)
// returns {Component} or {Array Component}

var com = FIND('component_name'); // FILTER: data-jc="component_name" or data-jc="component_name@..."
// Returns the only one component according to the component name

var com = FIND('component_name@1'); // FILTER: data-jc="component_name@1"
// +v14.0.0 Finds component according to the specific version

var com = FIND('component_name[path]'); // FILTER: data-jc="component_name" data-jc-path="path"
// Returns the only one component according to the component name and path

var com = FIND('#component_id'); // FILTER: data-jc-id="component_id"
// Returns the only one component according to the component id

var com = FIND('#component_id[path]'); // FILTER: data-jc-id="component_id" data-jc-path="path"
// Returns the only one component according to the component id and path

var com = FIND('.path'); // FILTER: data-jc-path="path"
// Returns the only one component according to the path

var com = FIND($(window)); // FILTER: jQuery container
// Returns the only one component according to the container as jQuery element
// +v11.4.0

var com = FIND('textbox', true);
// Returns Array of all components according to the selector

// Waiting for a component:
FIND('SELECTOR', function(component) {
	// This callback will be executed if the component will exist
	// @component {Component}
});

// Waiting for a component with 5 seconds timeout:
FIND('SELECTOR', function(component) {
	// This callback will be executed if the component will exist
	// @component {Component}
}, 5000);
// You can't process a timeout error (callback won't be executed).
```

### Method: `FORMATTER()`

This method registers/evaluates a global formatter.

- `format` was added `+v18`

```javascript
FORMATTER(value, path, type, format);

// Registers a new formatter
// All components use global formatters
FORMATTER(function(path, value, type, format) {
	// @path {String}
	// @value {Object}
	// @type {String}
	// @format {String}
	// MUST RETURN A VALUE!!!
	return value.toUpperCase(); 
});

// Executes a formatter for a value
console.log(FORMATTER('peter'));
```

### Method: `FN()`

The method generates `Function` from expression of Arrow Function.

```javascript
FN(expression);
// @expression {String}
// returns {Function}

var fn = FN('n => n.toUpperCase()');
console.log(fn('peter'));
// Output: PETER
```

### Method: `GET()`

The method reads a value according to the path.

```javascript
GET(path, [callback]);
// @path {String} A path to a variable
// @callback {Function} Optional, is executed when the variable will contain a value (v17)
// returns {Object}

console.log(GET('common.page'));
```

### Method: `GETM()`

`+v17` The method returns only __modified values__.

```javascript
GETM(path);
// returns {Object}

console.log(GETM('users.form'));
```

### Method: `GETR()`

`+v15` The method reads a value and resets all components according to the path.

```javascript
GETR(path);
// returns {Object}

console.log(GETR('users.form.name'));
```

### Method: `GETU()`

`+v17` The method reads a value and after 1 miliseconds it performs `UPD()` according to the path

```javascript
GETU(path);
// returns {Object}

var model = GETU('users.form'));
model.name = 'Peter Širka';
```

### Method: `GUID()`

The method generates a unique `String`.

```javascript
GUID([length]);
// @length {Number} Default: 10
// returns {String}

console.log(GUID());
// Output: 7a9zrsw2hi
```

### Method: `HASH()`

The method generates `Number` hash sum.

```javascript
HASH(value, unsigned);
// @value {String}
// @unsigned {Boolean} Default: false
// returns {Number}

console.log(HASH('Peter'));
// Output: -77005292

console.log(HASH('Peter', true));
// Output: 77005292
```

### Method: `IMPORT()`

The method can import HTML content, JavaScript or CSS from external source.

- supports re-type of extension `https://maps.googleapis.com/maps/api/js?key=KEY .js`
- styles and scripts are inserted into the HTML head
- supports environments
- `+v16` __NEW__ supports a dependency validator via `<path>` phrase

```javascript
IMPORT(url, [target], [callback], [insert], [preparator]);
// @url {String or String Array} Relative or Absolute URL address
// @target {String} Optional, jQuery selector (default: "document.body")
// @callback {Function} Optional and the method will be wait for non-exist components
// @preparator {Function(content)} Optional, needs to return modified content

// Simple usage:
IMPORT('/templates/products.html');

// Content will be inserted to <div id="templates"></div>
IMPORT('/templates/products.html', '#templates');

// With a callback:
IMPORT('/templates/products.html', function() {
	// Done, template is imported and inserted
	// You can manipulate with DOM
});

// With a preparator function
IMPORT('/templates/products.html', NOOP, function(content, response) {
	return content.replace(/logo\.png/i, 'newlogo.png');
});

// Import e.g. scripts
IMPORT('https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js');

// Import some dependency only one!!!
IMPORT('ONCE https://.....');
// or
IMPORT('!https://.....');

// +v16
// Supports dependency validator
// Imports D3 only when d3 is not part of window
IMPORT('<d3> https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js');

// or "path to variable", a negative value will import dependency
IMPORT('<path> https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js');

// or "path to function", a negative value will import dependency
// function will be evaluated as a function
// IMPORTANT: you can't use any argument for the function
IMPORT('<path()> https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js');
```

### Method: `IMPORTCACHE()`

`+v14.0.0.` Is same as `IMPORT()` method but it needs to contain `expire` argument. This method can't cache plain `css` or `js`.

```javascript
IMPORTCACHE(url, expire, [target], [callback], [insert], [preparator]);
// @url {String} Relative or Absolute URL address
// @expire {String} Expiration, e.g. 5 minutes
// @target {String} Optional, jQuery selector (default: "document.body")
// @callback {Function} Optional and the method will be wait for non-exist components
// @preparator {Function(content)} Optional, needs to return modified content
```

### Method: `INC()`

The method increments a `Number` according to the `path`.

```javascript
INC(path, value, [type/delay], [reset]);
// @path {String}
// @value {Number}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, default: false

// users.form.age = 35;
INC('users.form.age', 1);
// Output: users.form.age = 36;
```

### Method: `INC2()`

`+v16` The method increments a `Number` according to the `path` and performs `CHANGE()`.

```javascript
INC2(path, value, [type/delay]);
// @path {String}
// @value {Number}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
```

### Method: `INVALID()`

The method highlights all components on the path as `invalid`.

```javascript
INVALID(path, [except]);
// @path {String}
// @except {Array String} Can contain absolute paths for skipping (optional)

INVALID('users.form.*');

// +v13.0.0 supports "except" flags
// @hidden - jComponent finds all hidden components
// @visible - jComponent finds all visible components
// @disabled - jComponent finds all components which have disabled inputs
// @enabled - jComponent finds all components which have enabled inputs
console.log(INVALID('users.form.*', ['@visible', '@enabled']);
```

### Method: `MAKE()`

`+v15` This method can create an object.

```javascript
MAKE(obj/path, fn, [update]);
// @path {Object/String}
// @fn {Function}
// @notify {Boolean} Optional, default "true"
// returns {String}

// Creates an object on the path "users.form" and notifies all components
MAKE('users.form', function(obj) {
	obj.name = 'Peter Širka';
	obj.age = 33;
});

console.log(users.form);
// Output: { name: 'Peter Širka', age: 33 }
```

### Method: `MAKEPARAMS()`

__`REMOVED in +v18`__. `+v15` This method can appends custom params to `url`.

```javascript
MAKEPARAMS([url], values);
// @url {String} Optional, default: "location.href"
// @values {Object}
// returns {String}

console.log(MAKEPARAMS({ sort: 1, pricefrom: 300 }));
// Output: /?sort=1&price=300

console.log(MAKEPARAMS('/search/?q=Peter', { sort: 1, pricefrom: 300 }));
// Output: /search/?q=Peter&sort=1&pricefrom=300
```

### Method: `MEDIAQUERY()`

__`REMOVED in v17`__ This method registers a listener for specific size of the browser `window` or `element`. Read more in [`Responsive UI`](@17092508530002lex0) section.

```javascript
MEDIAQUERY(query, [element], callback(w, h, type, id));
// @query {String} media CSS query string
// @element {jQuery Element} optional, needs to be jQuery element (default: "window")
// @callback {Function(w, h, type, id)} callback
// returns {Number} an idetificator of MediaQuery

// For the whole window
MEDIAQUERY('(min-width: 500px) and (max-width: 1024px) and (orientation: landscape)', function(w, h, type, id) {
	
	// w {Number} "window" width
	// h {Number} "window" height
	// type {String} display type, can be "xs", "sm", "md" or "lg"
	// id {Number} identificator of MediaQuery
	
	// This method will be executed if the MediaQuery condition will be valid for "window".
	
});

// For an element:
MEDIAQUERY('(min-width: 200px) and (max-width: 600px)', $('#panel'), function(w, h, type, id) {
	
	// w {Number} "element" width
	// h {Number} "element" height
	// type {String} display type, can be "xs", "sm", "md" or "lg"
	// id {Number} identificator of MediaQuery
	
	// This method will be executed if the MediaQuery condition will be valid for this element.
	
});
```

### Method: `MIDDLEWARE()`

`+v14.1.1` This method registers a new jRouting middleware. It's alias for `NAV.middleware()`.

```javascript
MIDDLEWARE(name, fn);
// @name {String} A middleware name
// @fn {Function(next)} Executor
// returns {NAV}

MIDDLEWARE('delay', function(next, options, roles) {
	// @next {Function} "next(false)" or "next(Error") won't be continue in processing
	// @options {Object} custom options defined in a route
	// @roles {String Array} roles defined in a route
	setTimeout(next, 1000);
});
```

### Method: `MODIFIED()`

The method returns all modified components by user on the path.

```javascript
MODIFIED(path);
// @path {String}
// returns {Array String}

console.log(MODIFIED('users.form.*'));
```

### Method: `NOOP`

The method is an empty function and can be used as `callback` in some asynchronous method.

### Method: `NOTIFY()`

The method notifies a `setter` in all components on the path.

```javascript
NOTIFY(pathA, [pathB], [..pathN]);
// @pathA {String}
// @pathB {String} Optional
// @pathN {String} Optional

NOTIFY('users.form.name', 'users.form.age');
```

### Method: `NOTMODIFIED()`

The method checks whether the value has not been modified on the `path`.

```javascript
NOTMODIFIED(path, [value], [fields]);
// @path {String}
// @value {Object} Optional
// @fields {Array String} Optional, field names
// returns {Boolean}

// Is the "path.to.model" modified?
if (NOTMODIFIED('path.to.model')) {
	// The value according to the path is not modified
	return;
}

// Are fields "name" and "age" in "path.to.model" modified?
if (NOTMODIFIED('path.to.model', undefined, ['name', 'age'])) {
	// The value according to the path is not modified
	return;
}

// Compares a value according to the "modified.key"
// In other words: you can compare your own custom values
if (NOTMODIFIED('modified.key', your_custom_value)) {
	// The value according to the "modified.key" is not modified
	return;
}
```

### Method: `NOTFOCUSED()`

`+v18` The method determines if the brower tab is focused or not. The method checks:

- `document.hasFocus()` with except mobile devices
- `navigator.onLine` state

```javascript
NOTFOCUSED();
// returns {Boolean}

if (NOTFOCUSED())
	return;
```

### Method: `NULL`

`+v17` The method sets `null` value according to the path.

```javascript
NULL(path, [sleep\type]);
// @path {String}
// @sleep {Number} or @type {Number/String} Optional
```

### Method: `OFF()`

The method unregisters an event listener.

```javascript
OFF(name, [handler]);
// @name {String} Event name
// @callback {Function} Optional, event handler

OFF('response');
OFF('response', my_handler);

// Or for multiple events
OFF('name1 + name2 + name3');
```

### Method: `ON()`

The method registers an event listener.

```javascript
ON(name, handler];
// @name {String} Event name
// @callback {Function} Event handler

ON('response', function(response) {
	console.log(response);
});

// Or for multiple events
ON('name1 + name2 + name3', function() {
	
});
```

### Method: `OPT()`

`+v16` The method creates an object with more readable properties.

```javascript
OPT([obj], maker);
// @name {String} Event name
// @maker {Function} A maker


var obj = OPT(function(set) {
	// set(path, value);
	set('address.city', 'Bratislava');
	set('user.name', 'Peter Sirka');
});
// output: { address: { city: 'Bratislava' }, user: { name: 'Peter Sirka' }}
```

### Method: `PARSE()`

The method parses JSON `String` to `Object`.

```javascript
PARSE(value, [date]);
// @value {String}
// @date {Boolean} Auto-converting string dates to Date (default: "MAIN.defaults.jsondate")
// returns {Object}
```

### Method: `PARSER()`

This method registers/evaluates a global parser.

- `format` was added in `+v18`

```javascript
PARSER(path, value, type, format);

// Registers a new formatter
// All components use global formatters
PARSER(function(path, value, type, format) {
	// @path {String}
	// @value {Object}
	// @type {String}
	// @format {String}
	// MUST RETURN A VALUE!!!!
	return value.toLowerCase(); 
});

// Executes a formatter for a value
console.log(PARSER('PETER'));
```

### Method: `PING()`

__`REMOVED in v17`__ The method pings a URL address. Each request contains additional header `X-Ping` with the current location).

- `+v11.0.0` __important__: the response will be evaluated as JavaScript code
- `+v11.0.0` additional request PING data are stored in `MAIN.defaults.pingdata`
- `+v11.2.0` supports environments variables
- `+v14.1.1` supports `execute` argument (default: `false`) for immediate invocation
- `+v14.1.1` adds new headers `x-cookies` and `x-referrer`

```javascript
PING(url, [delay], [execute]);
// @url {String}
// @delay {Number} Optional, in milliseconds (default: "30000")
// @execute {Boolean} Optional (default: false)
// returns {Object}

PING('/api/ping');

// or with another method than GET
PING('POST /api/ping');

// or with environment key:
PING('[pingurl]');
```

### Method: `PLUGIN()`

The method can register or get a plugin. Read more about plugins in __Plugins section__.

```javascript
PLUGIN(name, [declaration]);
// @name {String}
// @declaration {Function}
// returns {Plugin}

// Registers a plugin:
PLUGIN('Users', function(instance) {
	// New instance of the 
});

// Gets a plugin
var users = PLUGIN('Users');
```

### Method: `PUSH()`

The method pushs a new item into the `Array` according to the path.

- `+v18` **SUPPORTS API REQUEST**
- `+v18` supports flags `PATH @flag1 @flag2`, supported flags: `reset`, `change`

```javascript
PUSH(path, value, [type/delay], [reset]);
// @path {String}
// @value {Object} or {Array}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional

// Single item:
PUSH('users.form.tags', 'Total.js');

// Or Array:
PUSH('users.form.tags', ['Node.js', 'Total.js']);

// Unshift items with ^ char
PUSH('^users.form.tags', 'This will be first item in the array');

// +v18
PUSH('GET /api/users/', 'users');
// or with cache 2 minutes
PUSH('GET /api/users/ <2 minutes>', 'users');
```

### Method: `READPARAMS()`

__`REMOVED in +v18`__ This method parses URL arguments from the current URL address.

```javascript
READPARAMS([query]);
// @query {String} Optional, custom URL (default: "location.href")
// returns {Object}

console.log(READPARAMS('/search/?q=Peter'));
// Output: { q: "Peter" }
```

### Method: `RECONFIGURE()`

`+v13.0.0` reconfigures all components according to the `selector`.

```javascript
RECONFIGURE(selector, config);
// @selector {String}
// @config {String/Object}

RECONFIGURE('form', 'title:Edit product;width:800');
RECONFIGURE('form', { title: 'Edit product' }); 
```

### Method: `REMOVECACHE()`

The method removes item(s) from cache.

```javascript
REMOVECACHE(key, [isSearching]);
// @key {String}
// @isSearching {Boolean} Optional, default: "false"

REMOVECACHE('myKey'); 

// All keys which contain "home":
REMOVECACHE('home', true); 
```

### Method: `RESET()`

The method resets `dirty` and `valid` state in all components on the `path`.

```javascript
RESET(path, [delay]);
// @path {String}
// @delay {Number} Optional, in milliseconds (default: 0)

RESET('users.form.*'); 
```

### Method: `REPEAT()`

`+v18` The method performs `setInterval()` with specific conditions and it's pluginable.

- browser must be online
- browser tab must be focused
- condition must be valid

Removed plugin removes interval of `REPEAT()` method automatically.

```javascript
REPEAT([condition], processor, interval, [init]);
// @condition {String/Function}
// @processor {Function}
// @interval {Number} Interval in milliseconds (default: 0)

REPEAT('your.path.to.value__value===100', function() {
	// browser is online
	// browser tab is focused
	// defined condition is valid
}, 1000);

REPEAT('your.path', function() {
	// browser is online
	// browser tab is focused
	// defined condition contains a positive value
}, 1000);

REPEAT(function() {
	return common.page === 'users';
}, function() {
	// browser is online
	// browser tab is focused
	// defined condition is valid
}, 1000);
```

- `focus` condition can be disabled via `DEF.repeatfocus = false`;

### Method: `RETURN()`

`+v18` The method tries to find a component and read a value according to the specific path. The method uses `FIND()` method.

- `selector` must be in the form `selector/path.to.property_or_method`

```javascript
RETURN(selector, [multiple]);
// @selector {String}
// @multiple {Boolean} returns Array (default: false)

// Tries to find "input" component and reads "config.maxlength" value
var maxlength = RETURN('input/config.maxlength');

var values = RETURN('input/config.maxlength', true);
// values will be {Array} with numbers
```

### Method: `REWRITE()`

`+v17` The method rewrites a value without notifications of components with except data binders `data-bind` and watchers `WATCH()`.

- `+v18` supports flags `PATH @flag1 @flag2`, supported flags:
	- `nobind` skips data-bind
	- `nowatch` skips WATCHERS

```javascript
REWRITE(path, value, [type]);
// @path {String}
// @value {Object}
// @type {Number/Type}
```

### Method: `SCHEDULE()`

__`REMOVED in v17`__ The method resets `dirty` and `valid` state in all components on the `path`.

__Types__:
- `input` value has been changed by `input`
- `manually` value has been changed by e.g. `SET()`, `UPDATE()`, `PUSH()`, etc.
- `init` from initialization of the component

```javascript
SCHEDULE(selector, type, delay, callback);
// @selector {String} Selector within components according to the "FIND()" method
// @type {String} Can be: "input", "manually", "init"
// @delay {String} Last update time and in the form: "number [seconds, minutes, hours, days, weeks, months, years]"
// @callback {Function(component}
// returns {Number} Scheduler identificator like "setTimeout()"

// Evaluates the callback after 5 minutes if the value according to the "data-jc-path" has been changed by "input"
SCHEDULE('.find-by-component-path', 'input', '5 minutes', function(component) {
	AJAX('GET /api/refresh/', component.path);
});

// Evaluates the callback after 3 seconds if the value according to the "data-jc-path" has been changed manually by developer
SCHEDULE('#find-by-component-id', 'manually', '3 seconds', function(component) {
	AJAX('GET /api/refresh/', component.path);
});

// Evalutes the callback 1 hour from initialization of the component
var task = SCHEDULE('find-by-component-name', 'init', '1 hour', function(component) {
	AJAX('GET /api/refresh/', component.path);
});

// Removing existing schedulers:
CLEARSCHEDULE(task);
```

### Method: `SCHEMA()`

The method registers a schema or reads existing. The schema can be used for forms for declaring default values.

```javascript
SCHEMA(name, [declaration]);
// @name {String}
// @declaration {Object} Optional

// Registers a new schema with raw object
SCHEMA('User', { firstname: 'Peter', lastname: 'Širka', note: 'default values' });

// Creates object according to the schema
var userA = SCHEMA('User');
var userB = SCHEMA('User');

console.log(userA === userB);
// Output: false

console.log(userA);
// Output: { firstname: Peter, lastname: Širka, note: default values }
```

### Method: `SCOPE()`

The method can extend existing controller's scope. If the controller doesn't exist the method is waiting on it (otherwise: `scopeFn` function is evaluated when the controller exists).

```javascript
SCOPE(name, [scopeFn]);
// @name {String}
// @scopeFn {Function}

SCOPE('UserController', function(instance, scope, element) {
	// Controller's scope
});
```

### Method: `SCROLLBARWIDTH()`

`v12.0.0` The method gets a width of scrollbar and caches it for future usage in the current session.

```javascript
SCROLLBARWIDTH();
// Returns {Number}
```

### Method: `SEEX()`

`v17` The method combines `SET()` and `EXEC()` methods together.

```javascript
SEEX(path, a, [b], [c], [d]);
// @path {String}
// @a {Object} value for SET() or argument for EXEC()
// @b {Object} Optional, argument for EXEC()
// @c {Object} Optional, argument for EXEC()
// @d {Object} Optional, argument for EXEC()

SEEX('some.path', 'Peter');
// performs SET() because contains '.' (dot)

SEEX('main/refresh', true);
// performs EXEC() because doesn't '.' (dot)
```

Sure you can ask why, right? The answer is very easy, just imagine a component with:

```javascript
self.event('click', function(e) {
	SEEX(config.select, $(this).attrd('id'));
	// Some components like j-DataGrid or j-Folder can emit e.g. selected row/item to a method or according to a path
});
```

### Method: `SET()`

The method sets a new value according to the path.

- `+v18` **SUPPORTS API REQUEST**
- `+v18` supports flags `PATH @flag1 @flag2`, supported flags:
	- `default` components will be set default values and resetted state
	- `reset` components will be resetted 
	- `change` components will have changed state to changed
	- `extend` flag will update only defined keys/values in `value`
	- `type:1`, `type:2` or `type:customtype` flag will change a `SET` type
	- `nowatch` flag skips WACHTERS after change

```javascript
SET(path, value, [type/delay], [reset]);
// @path {String}
// @value {Object} +v18 {Function}
// @type/delay {String/Number} Optional, number > 10 will be used as a delay
// @reset {Boolean} Optional, default: false

SET('users.form.age', 30);

// +v18
SET('GET /api/users/', 'users');
// or with cache 2 minutes
SET('GET /api/users/ <2 minutes>', 'users');

// +v18 flags
SET('usersform @default', {});
```

### Method: `SET2()`

`+v16` The method sets a new value according to the path and performs `CHANGE()` for all components which are listening on the `path`.

__IMPORTANT__: Instead of `SET2()` use `SET('PATH @change', ...)`

```javascript
SET2(path, value, [type/delay]);
// @path {String}
// @value {Object}
// @type/delay {String/Number} Optional, number > 10 will be used as a delay

SET2('users.form.age', 30);
```

### Method: `SETR()`

`+v16` The method sets a new value according to the path and resets the state.
`+v18` **SUPPORTS API REQUEST**

__IMPORTANT__: Instead of `SET2()` use `SET('PATH @reset', ...)`

```javascript
SETR(path, value, [type/delay], [reset]);
// @path {String}
// @value {Object}
// @type {String/Number} Optional, number > 10 will be used as a delay

SETR('users.form.age', 30);

// +v18
SETR('GET /api/users/', 'users');
// or with cache 2 minutes
SETR('GET /api/users/ <2 minutes>', 'users');
```

### Method: `setTimeout2()`

The method is improved `setTimeout` method. This method cancels a previous unexecuted call.

```javascript
setTimeout2(key, fn, timeout, [limit], [param]);
// @key {String}
// @fn {Function(param)}
// @timeout {Number}
// @limit {Number} Optional, a maximum clear limit (default: 0)
// @param {Object} Optional, additional argument
// return {Number}

setTimeout2('key', function() {
	console.log('DONE');
}, 100);

setTimeout2('key', function() {
	console.log('DONE');
}, 100);

setTimeout2('key', function() {
	console.log('DONE');
}, 100);

// Output: DONE

// Clearing of registered setTimeout2():
var id = setTimeout2('something', NOOP, 1000);
clearTimeout2(id);
```

### Method: `SETTER()`

The method can set a new value to the specific method in components.

```javascript
SETTER([wait], selector, propOrMethod, [argA], [argB], [..argN]);
// @wait {Boolean} Optional, can it wait for non-exist components?
// @selector {String}
// @propOrMethod {String} Property or Method name (can't be nested)
// @argA {Object} Optional, additional argument
// @argB {Object} Optional, additional argument
// @..argN {Object} Optional, additional argument

SETTER('#loading', 'hide', 1000);
// Executes --> FIND('#loading').hide(1000);

SETTER('textbox', 'set', 'NEW VALUE');
// Executes --> FIND('textbox').set('NEW VALUE');

SETTER('textbox@1', 'set', 'NEW VALUE');
// Executes --> FIND('textbox@1').set('NEW VALUE');

SETTER(true, 'loading', 'show');
// +v9.0.0 It will waits for "lodaing" component and then executes --> FIND('loading').show();

SETTER($('#container'), 'reconfigure', 'icon:home');
// +v11.4.0 supports jQuery element or DOM element

SETTER('!datepicker', 'hide');
// +v17
// It executes `hide` if the component has been loaded
// It's targeted for LAZY components

// +v18 supports shorter notations:
SETTER('loading/show');
SETTER('!datepicker/hide');
```

### Method: `STRINGIFY()`

The method serializes `Object` to `JSON`.

```javascript
STRINGIFY(obj, [compress], [fields]);
// @obj {Object}
// @compress {Boolean} Optional, default: "MAIN.defaults.jsoncompress"
// @fields {Array String} or {Object} Optional

STRINGIFY({ name: 'Peter', age: 33 });
// Output: {"name":"Peter","age":33}

// With enabled compression:
STRINGIFY({ name: '  Peter  ', age: 33, something: null }, true);
// Output: {"name":"Peter","age":33}

// With custom fields (Array):
STRINGIFY({ name: '  Peter  ', age: 33, something: null }, true, ['age']);
// Output: {"age":33}

// With custom fields (Object):
STRINGIFY({ name: '  Peter  ', age: 33, something: null }, false, { name: false });
// Output: {"age":33,"something":null}
```

### Method: `TOGGLE()`

`+v16` The method performs `toggle` for the path. A value must be `Boolean`.

- `+v18` support flags, more in `SET()` method

```javascript
TOGGLE(path, [type/delay], [reset]);
// @path {String}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, resets state of all components

TOGGLE('form.terms');
```

### Method: `TOGGLE2()`

`+v16` The method performs `toggle` for the path and changes the state to `changed`. A value must be `Boolean`.

__IMPORTANT__: Instead of `TOGGLE2()` use `TOGGLE('PATH @change')`

```javascript
TOGGLE2(path, [type/delay]]);
// @path {String}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, resets state of all components

TOGGLE2('form.terms');
```

### Method: `VALID()`

`+v17` The method returns validation state (without dirty state) from all components according to the `path`.

```javascript
VALID(path, [except]);
// @path {String}
// @except {Array String} Optional With absolute paths for skipping
// returns {Boolean}

var valid = VALID('users.form.*');
console.log(valid);
```

### Method: `VALIDATE()`

The method validates all components on the `path`.

```javascript
VALIDATE(path, [except]);
// @path {String}
// @except {Array String} Optional With absolute paths for skipping
// returns {Boolean}

var valid = VALIDATE('users.form.*');
console.log(valid);
```

### Method: `VERSION()`

`+v14.0.0` The method sets a version for specific components.

```javascript
VERSION(a, [b], [n]);
// @a {String} name + version
// @b {String} Optional
// @n {String} Optional

VERSION('textbox@1', 'dropdown@1');
```

### Method: `QUEUE()`

`+v18` The method adds a function into the queue defined according to the `name`. If the queue is running then the method is added into the queue at the end. This method doesn't exec multiple function in queue in the same time.

```javascript
// QUEUE([name], fn);
// @name {String} optional
// @function {Function(next, pending)}

QUEUE(function(next, pending) {
	console.log('TASK 1, pending:', pending);
	setTimeout(next, 1000);
});

QUEUE(function(next, pending) {
	console.log('TASK 2, pending:', pending);
	setTimeout(next, 1000);
});

// Output:
// TASK 1
// TASK 2
```

### Method: `UPLOAD()`

The method can upload `multipart/form-data` asynchronous.

```javascript
UPLOAD(url, data, path/callback, [delay], [progress]);
// @url {String}
// @data {FormData}
// @path/callback {String} or {Function(response, err, output)}
// @delay {Number} Optional, delay to upload
// @progress {String} or {Function(percentage, speed, remaining)}

var data = new FormData();
data.append('file', files[0]);

// Basic usage:
UPLOAD('/api/logo/', data, 'path.to.response');

// or
UPLOAD('/api/logo/', data, function(response, err) {
	console.log(response);
});

// With progress bar
UPLOAD('/api/logo/', data, function(response, err) {
	console.log(response);
}, 'path.to.progress.percentage');

// or
UPLOAD('/api/logo/', data, function(response, err) {
	console.log(response);
}, function(percentage, speed, remaining) {
	console.log('Upload: ' + percentage);
});
```

### Method: `UPD()`

The method updates all components on the entire path.

- `+v18` supports flags, more in `SET()` method

```javascript
UPD(path, [type/delay], [reset]);
// or alias UPDATE()
// @path {String}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, default: false

users.form.name = 'Peter';
users.form.age = 30;
UPD('users.form');

// +v14.1.1 with custom setter type
UPD('users.form', 'mytype');
```

### Method: `UPD2()`

`+v16` The method updates all components on the entire path and performs `CHANGE()`.

__IMPORTANT__: Instead of `UPD2()` use `UPD('PATH @change')`

```javascript
UPD2(path, [type/delay]);
// or alias UPDATE2()
// @path {String}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
```

### Method: `WAIT()`

The method can wait for a feature.

```javascript
WAIT(path/fn, callback, [interval], [timeout]);
// @path/fn {String} or {Function}
// @callback {Function}
// @interval {Number} Optional, in milliseconds (default: 500)
// @timeout {Number} Optional, a timeout (default: 0 - disabled)

// With a path defined in "window" scope:
WAIT('d3', function(err) {
	if (err) {
		console.log(err);
	} else {
		console.log('D3 is initialized');
	}
});

// With a function:
WAIT(function() {
	return window.d3;
}, function(err) {
	if (err) {
		console.log(err);
	} else {
		console.log('D3 is initialized');
	}
});
```

### Method: `WATCH()`

The method registers a new watcher for a specific path.

```javascript
WATCH(path, handler, [init]];
// @path {String} Event name
// @handler {Function} Event handler
// @init {Boolean} Optional, it evaluates path now (default: false)

WATCH('path.to.model', function(path, value, type) {

	// Arguments description:
	// @path {String} Path which has been changed
	// @value {Object} New value
	// @type {Number} 0: init, 1: manually, 2: input, 3 default
	
	console.log('NEW VALUE', value);
});

// with the evaluation:
WATCH('path.to.model', function(path, value, type) {
	console.log('NEW VALUE', value);
}, true);

// or for multiple paths:
WATCH('path1 + path2 + path3', function(path, value, type) {
	
});
```

### Method: `USAGE()`

__`REMOVED in v17`__ This method returns last usage components.

```javascript
USAGE(type, expire, [path], [callback]);
// @type {String} Can be "init", "manually", "input" or "custom"
// @expire {String/Number}, for example "5 minutes"
// @path {String} Optional, for example "users.form.name"
// returns {Array Component} or {jComponent}

console.log(USAGE('init', '5 minutes'));
// Returns {Array Component}

USAGE('init', '5 minutes', function(component) {
	console.log(component);
});
```