diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4cdfbb7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,38 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] +# Change these settings to your own preference +indent_style = space +indent_size = 4 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.html] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.styl,*.scss,*.css,*.less] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true + +[{package.json,bower.json,.eslintrc}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..0d248f1 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "env": { + "browser": true, + "node": true + }, + "rules": { + "complexity": [2, 16], + "max-nested-callbacks": [2, 3], + "max-params": [2, 4], + "max-statements": [2, 30], + "no-extra-parens": [0], + "no-magic-numbers": [0], + "no-restricted-syntax": [2, "ContinueStatement", "DebuggerStatement", "LabeledStatement", "WithStatement"], + "operator-linebreak": [2, "before"], + "spaced-comment": [0], + "strict": [0] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a3d246 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/* +bower_components/* +*.log +old/* \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..c59c87a --- /dev/null +++ b/.npmignore @@ -0,0 +1,14 @@ +node_modules/* +bower_components/* +old/* +lib/* +tables/* +test/* +*.log +*.md +bower.json +gulpfile.js +.eslintrc.json +.gitignore +.npmignore +.editorconfig diff --git a/bower.json b/bower.json index 391dad4..a039700 100644 --- a/bower.json +++ b/bower.json @@ -1,31 +1,30 @@ { - "name": "s-uid", - "main": "uid.min.js", - "version": "1.3.0", - "private": false, - "description": "Generate id from base string", - "ignore": [ - "node_modules", - "bower_components", - "package.json", - "bower.json", - "gulpfile.js", - "lib", - "test.*" - ], - "keywords": [ - "s-uid", - "uid" - ], - "homepage": "https://github.com/sajera/s-uid", - "authors": [ - "Sajera: Serhii P " - ], - "repository": { - "type": "git", - "url": "git+https://github.com/sajera/s-uid.git" - }, - "license": "MIT", - "dependencies": {}, - "devDependencies": {} -} \ No newline at end of file + "name": "s-uid", + "main": "s-uid.min.js", + "private": false, + "description": "Generate id from base string", + "ignore": [ + "node_modules", + "bower_components", + "package.json", + "bower.json", + "gulpfile.js", + "lib", + "test.*" + ], + "keywords": [ + "s-uid", + "uid" + ], + "homepage": "https://github.com/sajera/s-uid", + "authors": [ + "Sajera: Serhii P " + ], + "repository": { + "type": "git", + "url": "git+https://github.com/sajera/s-uid.git" + }, + "license": "MIT", + "dependencies": {}, + "devDependencies": {} +} diff --git a/doc/API.md b/doc/API.md new file mode 100644 index 0000000..ac372d0 --- /dev/null +++ b/doc/API.md @@ -0,0 +1,146 @@ + + +## uid + +generate random id based on template string. +Default template string is 'xxxxxxxx-xxxx-1xxx-1xxx-xxxxxxxxxxxx'. + +> Template rules very simple: +> +> **base** - it's a string for creating id. Rewrite only special characters +> +> **N** - Rewrite to random Number +> +> **H** - Rewrite to random hex numder +> +> **S** - Rewrite to random english symbol +> +> **X** - Rewrite to any from "N","H","S" + +**Parameters** + +- `base` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** :[default: 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX'] + +**Examples** + +```javascript +uid(); +uid('XXX-4NNN-dummy-SSS'); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## uid.\_time + +Humanized time string. +This method is very sensitive to the correctness of the input arguments + +**Parameters** + +- `separator` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Separator character for output +- `date` **[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)** instance of Date constructor + +**Examples** + +```javascript +uid._time('-', new Date() ); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## uid.\_date + +Humanized date string. +This method is very sensitive to the correctness of the input arguments + +**Parameters** + +- `separator` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Separator character for output +- `date` **[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)** instance of Date constructor + +**Examples** + +```javascript +uid._date('-', new Date() ); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## uid.time + +Humanized date+time string. Safe method. + +**Parameters** + +- `date` **[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)?** :[default: new Date()] - instance of Date constructor +- `separator1` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** :[default: ' - '] - Separator character for output date +- `separator2` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** :[default: ' \s '] - Separator character for output bitwin date and time +- `separator3` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** :[default: ' : '] - Separator character for output time +- `time` + +**Examples** + +```javascript +uid.time(); +uid.time( new Date() ); +uid.time( new Date(), '-', ':', '-'); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## uid.th + +hash based on time in 36 numerical system by default + +**Parameters** + +- `date` **[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)?** :[default: new Date()] - instance of Date constructor +- `Number` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** [bit]:[default: 36] - expect number 2-36 + +**Examples** + +```javascript +uid.th(); +uid.th(null, 4); +uid.th(new Date(), 10); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** hash string + +## uid.guid + +generate uuid (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx) +based on time, reserved characters and random symbols + +**Parameters** + +- `M` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** [default: random english symbol ( uid('S') )] +- `N` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** [default: random number ( uid('N') )] +- `time` **[Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)?** [default: new Date()] - date of guid generation + +**Examples** + +```javascript +uid.guid(); +uid.guid('M', 0, new Date() ); +``` + +Returns **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## exports + +defination on platforms (both variants on platform like Electron) + +bower i --save s-uid + +npm i --save s-uid + +**Examples** + +```javascript +window.uid || window['s-uid'] // in browser +``` + +```javascript +var uid = require('s-uid') // in Node.js +``` diff --git a/doc/assets/anchor.js b/doc/assets/anchor.js new file mode 100644 index 0000000..47d871a --- /dev/null +++ b/doc/assets/anchor.js @@ -0,0 +1,197 @@ +/*! + * AnchorJS - v1.2.1 - 2015-07-02 + * https://github.com/bryanbraun/anchorjs + * Copyright (c) 2015 Bryan Braun; Licensed MIT + */ + +function AnchorJS(options) { + 'use strict'; + + this.options = options || {}; + + this._applyRemainingDefaultOptions = function(opts) { + this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'. + this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' + this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left' + this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name. + }; + + this._applyRemainingDefaultOptions(options); + + this.add = function(selector) { + var elements, + elsWithIds, + idList, + elementID, + i, + roughText, + tidyText, + index, + count, + newTidyText, + readableID, + anchor; + + this._applyRemainingDefaultOptions(this.options); + + // Provide a sensible default selector, if none is given. + if (!selector) { + selector = 'h1, h2, h3, h4, h5, h6'; + } else if (typeof selector !== 'string') { + throw new Error('The selector provided to AnchorJS was invalid.'); + } + + elements = document.querySelectorAll(selector); + if (elements.length === 0) { + return false; + } + + this._addBaselineStyles(); + + // We produce a list of existing IDs so we don't generate a duplicate. + elsWithIds = document.querySelectorAll('[id]'); + idList = [].map.call(elsWithIds, function assign(el) { + return el.id; + }); + + for (i = 0; i < elements.length; i++) { + + if (elements[i].hasAttribute('id')) { + elementID = elements[i].getAttribute('id'); + } else { + roughText = elements[i].textContent; + + // Refine it so it makes a good ID. Strip out non-safe characters, replace + // spaces with hyphens, truncate to 32 characters, and make toLowerCase. + // + // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.' + tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment' + .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment' + .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment' + .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' + .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' + .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url' + + // Compare our generated ID to existing IDs (and increment it if needed) + // before we add it to the page. + newTidyText = tidyText; + count = 0; + do { + if (index !== undefined) { + newTidyText = tidyText + '-' + count; + } + // .indexOf is supported in IE9+. + index = idList.indexOf(newTidyText); + count += 1; + } while (index !== -1); + index = undefined; + idList.push(newTidyText); + + // Assign it to our element. + // Currently the setAttribute element is only supported in IE9 and above. + elements[i].setAttribute('id', newTidyText); + + elementID = newTidyText; + } + + readableID = elementID.replace(/-/g, ' '); + + // The following code builds the following DOM structure in a more effiecient (albeit opaque) way. + // ''; + anchor = document.createElement('a'); + anchor.className = 'anchorjs-link ' + this.options.class; + anchor.href = '#' + elementID; + anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID); + anchor.setAttribute('data-anchorjs-icon', this.options.icon); + + if (this.options.visible === 'always') { + anchor.style.opacity = '1'; + } + + if (this.options.icon === '\ue9cb') { + anchor.style.fontFamily = 'anchorjs-icons'; + anchor.style.fontStyle = 'normal'; + anchor.style.fontVariant = 'normal'; + anchor.style.fontWeight = 'normal'; + anchor.style.lineHeight = 1; + } + + if (this.options.placement === 'left') { + anchor.style.position = 'absolute'; + anchor.style.marginLeft = '-1em'; + anchor.style.paddingRight = '0.5em'; + elements[i].insertBefore(anchor, elements[i].firstChild); + } else { // if the option provided is `right` (or anything else). + anchor.style.paddingLeft = '0.375em'; + elements[i].appendChild(anchor); + } + } + + return this; + }; + + this.remove = function(selector) { + var domAnchor, + elements = document.querySelectorAll(selector); + for (var i = 0; i < elements.length; i++) { + domAnchor = elements[i].querySelector('.anchorjs-link'); + if (domAnchor) { + elements[i].removeChild(domAnchor); + } + } + return this; + }; + + this._addBaselineStyles = function() { + // We don't want to add global baseline styles if they've been added before. + if (document.head.querySelector('style.anchorjs') !== null) { + return; + } + + var style = document.createElement('style'), + linkRule = + ' .anchorjs-link {' + + ' opacity: 0;' + + ' text-decoration: none;' + + ' -webkit-font-smoothing: antialiased;' + + ' -moz-osx-font-smoothing: grayscale;' + + ' }', + hoverRule = + ' *:hover > .anchorjs-link,' + + ' .anchorjs-link:focus {' + + ' opacity: 1;' + + ' }', + anchorjsLinkFontFace = + ' @font-face {' + + ' font-family: "anchorjs-icons";' + + ' font-style: normal;' + + ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above + ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' + + ' }', + pseudoElContent = + ' [data-anchorjs-icon]::after {' + + ' content: attr(data-anchorjs-icon);' + + ' }', + firstStyleEl; + + style.className = 'anchorjs'; + style.appendChild(document.createTextNode('')); // Necessary for Webkit. + + // We place it in the head with the other style tags, if possible, so as to + // not look out of place. We insert before the others so these styles can be + // overridden if necessary. + firstStyleEl = document.head.querySelector('[rel="stylesheet"], style'); + if (firstStyleEl === undefined) { + document.head.appendChild(style); + } else { + document.head.insertBefore(style, firstStyleEl); + } + + style.sheet.insertRule(linkRule, style.sheet.cssRules.length); + style.sheet.insertRule(hoverRule, style.sheet.cssRules.length); + style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length); + style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length); + }; +} + +var anchors = new AnchorJS(); diff --git a/doc/assets/bass-addons.css b/doc/assets/bass-addons.css new file mode 100644 index 0000000..c27e96d --- /dev/null +++ b/doc/assets/bass-addons.css @@ -0,0 +1,12 @@ +.input { + font-family: inherit; + display: block; + width: 100%; + height: 2rem; + padding: .5rem; + margin-bottom: 1rem; + border: 1px solid #ccc; + font-size: .875rem; + border-radius: 3px; + box-sizing: border-box; +} diff --git a/doc/assets/bass.css b/doc/assets/bass.css new file mode 100644 index 0000000..15e0dc9 --- /dev/null +++ b/doc/assets/bass.css @@ -0,0 +1,543 @@ +/*! Basscss | http://basscss.com | MIT License */ + +.h1{ font-size: 2rem } +.h2{ font-size: 1.5rem } +.h3{ font-size: 1.25rem } +.h4{ font-size: 1rem } +.h5{ font-size: .875rem } +.h6{ font-size: .75rem } + +.font-family-inherit{ font-family:inherit } +.font-size-inherit{ font-size:inherit } +.text-decoration-none{ text-decoration:none } + +.bold{ font-weight: bold; font-weight: bold } +.regular{ font-weight:normal } +.italic{ font-style:italic } +.caps{ text-transform:uppercase; letter-spacing: .2em; } + +.left-align{ text-align:left } +.center{ text-align:center } +.right-align{ text-align:right } +.justify{ text-align:justify } + +.nowrap{ white-space:nowrap } +.break-word{ word-wrap:break-word } + +.line-height-1{ line-height: 1 } +.line-height-2{ line-height: 1.125 } +.line-height-3{ line-height: 1.25 } +.line-height-4{ line-height: 1.5 } + +.list-style-none{ list-style:none } +.underline{ text-decoration:underline } + +.truncate{ + max-width:100%; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; +} + +.list-reset{ + list-style:none; + padding-left:0; +} + +.inline{ display:inline } +.block{ display:block } +.inline-block{ display:inline-block } +.table{ display:table } +.table-cell{ display:table-cell } + +.overflow-hidden{ overflow:hidden } +.overflow-scroll{ overflow:scroll } +.overflow-auto{ overflow:auto } + +.clearfix:before, +.clearfix:after{ + content:" "; + display:table +} +.clearfix:after{ clear:both } + +.left{ float:left } +.right{ float:right } + +.fit{ max-width:100% } + +.max-width-1{ max-width: 24rem } +.max-width-2{ max-width: 32rem } +.max-width-3{ max-width: 48rem } +.max-width-4{ max-width: 64rem } + +.border-box{ box-sizing:border-box } + +.align-baseline{ vertical-align:baseline } +.align-top{ vertical-align:top } +.align-middle{ vertical-align:middle } +.align-bottom{ vertical-align:bottom } + +.m0{ margin:0 } +.mt0{ margin-top:0 } +.mr0{ margin-right:0 } +.mb0{ margin-bottom:0 } +.ml0{ margin-left:0 } +.mx0{ margin-left:0; margin-right:0 } +.my0{ margin-top:0; margin-bottom:0 } + +.m1{ margin: .5rem } +.mt1{ margin-top: .5rem } +.mr1{ margin-right: .5rem } +.mb1{ margin-bottom: .5rem } +.ml1{ margin-left: .5rem } +.mx1{ margin-left: .5rem; margin-right: .5rem } +.my1{ margin-top: .5rem; margin-bottom: .5rem } + +.m2{ margin: 1rem } +.mt2{ margin-top: 1rem } +.mr2{ margin-right: 1rem } +.mb2{ margin-bottom: 1rem } +.ml2{ margin-left: 1rem } +.mx2{ margin-left: 1rem; margin-right: 1rem } +.my2{ margin-top: 1rem; margin-bottom: 1rem } + +.m3{ margin: 2rem } +.mt3{ margin-top: 2rem } +.mr3{ margin-right: 2rem } +.mb3{ margin-bottom: 2rem } +.ml3{ margin-left: 2rem } +.mx3{ margin-left: 2rem; margin-right: 2rem } +.my3{ margin-top: 2rem; margin-bottom: 2rem } + +.m4{ margin: 4rem } +.mt4{ margin-top: 4rem } +.mr4{ margin-right: 4rem } +.mb4{ margin-bottom: 4rem } +.ml4{ margin-left: 4rem } +.mx4{ margin-left: 4rem; margin-right: 4rem } +.my4{ margin-top: 4rem; margin-bottom: 4rem } + +.mxn1{ margin-left: -.5rem; margin-right: -.5rem; } +.mxn2{ margin-left: -1rem; margin-right: -1rem; } +.mxn3{ margin-left: -2rem; margin-right: -2rem; } +.mxn4{ margin-left: -4rem; margin-right: -4rem; } + +.ml-auto{ margin-left:auto } +.mr-auto{ margin-right:auto } +.mx-auto{ margin-left:auto; margin-right:auto; } + +.p0{ padding:0 } +.pt0{ padding-top:0 } +.pr0{ padding-right:0 } +.pb0{ padding-bottom:0 } +.pl0{ padding-left:0 } +.px0{ padding-left:0; padding-right:0 } +.py0{ padding-top:0; padding-bottom:0 } + +.p1{ padding: .5rem } +.pt1{ padding-top: .5rem } +.pr1{ padding-right: .5rem } +.pb1{ padding-bottom: .5rem } +.pl1{ padding-left: .5rem } +.py1{ padding-top: .5rem; padding-bottom: .5rem } +.px1{ padding-left: .5rem; padding-right: .5rem } + +.p2{ padding: 1rem } +.pt2{ padding-top: 1rem } +.pr2{ padding-right: 1rem } +.pb2{ padding-bottom: 1rem } +.pl2{ padding-left: 1rem } +.py2{ padding-top: 1rem; padding-bottom: 1rem } +.px2{ padding-left: 1rem; padding-right: 1rem } + +.p3{ padding: 2rem } +.pt3{ padding-top: 2rem } +.pr3{ padding-right: 2rem } +.pb3{ padding-bottom: 2rem } +.pl3{ padding-left: 2rem } +.py3{ padding-top: 2rem; padding-bottom: 2rem } +.px3{ padding-left: 2rem; padding-right: 2rem } + +.p4{ padding: 4rem } +.pt4{ padding-top: 4rem } +.pr4{ padding-right: 4rem } +.pb4{ padding-bottom: 4rem } +.pl4{ padding-left: 4rem } +.py4{ padding-top: 4rem; padding-bottom: 4rem } +.px4{ padding-left: 4rem; padding-right: 4rem } + +.col{ + float:left; + box-sizing:border-box; +} + +.col-right{ + float:right; + box-sizing:border-box; +} + +.col-1{ + width:8.33333%; +} + +.col-2{ + width:16.66667%; +} + +.col-3{ + width:25%; +} + +.col-4{ + width:33.33333%; +} + +.col-5{ + width:41.66667%; +} + +.col-6{ + width:50%; +} + +.col-7{ + width:58.33333%; +} + +.col-8{ + width:66.66667%; +} + +.col-9{ + width:75%; +} + +.col-10{ + width:83.33333%; +} + +.col-11{ + width:91.66667%; +} + +.col-12{ + width:100%; +} +@media (min-width: 40em){ + + .sm-col{ + float:left; + box-sizing:border-box; + } + + .sm-col-right{ + float:right; + box-sizing:border-box; + } + + .sm-col-1{ + width:8.33333%; + } + + .sm-col-2{ + width:16.66667%; + } + + .sm-col-3{ + width:25%; + } + + .sm-col-4{ + width:33.33333%; + } + + .sm-col-5{ + width:41.66667%; + } + + .sm-col-6{ + width:50%; + } + + .sm-col-7{ + width:58.33333%; + } + + .sm-col-8{ + width:66.66667%; + } + + .sm-col-9{ + width:75%; + } + + .sm-col-10{ + width:83.33333%; + } + + .sm-col-11{ + width:91.66667%; + } + + .sm-col-12{ + width:100%; + } + +} +@media (min-width: 52em){ + + .md-col{ + float:left; + box-sizing:border-box; + } + + .md-col-right{ + float:right; + box-sizing:border-box; + } + + .md-col-1{ + width:8.33333%; + } + + .md-col-2{ + width:16.66667%; + } + + .md-col-3{ + width:25%; + } + + .md-col-4{ + width:33.33333%; + } + + .md-col-5{ + width:41.66667%; + } + + .md-col-6{ + width:50%; + } + + .md-col-7{ + width:58.33333%; + } + + .md-col-8{ + width:66.66667%; + } + + .md-col-9{ + width:75%; + } + + .md-col-10{ + width:83.33333%; + } + + .md-col-11{ + width:91.66667%; + } + + .md-col-12{ + width:100%; + } + +} +@media (min-width: 64em){ + + .lg-col{ + float:left; + box-sizing:border-box; + } + + .lg-col-right{ + float:right; + box-sizing:border-box; + } + + .lg-col-1{ + width:8.33333%; + } + + .lg-col-2{ + width:16.66667%; + } + + .lg-col-3{ + width:25%; + } + + .lg-col-4{ + width:33.33333%; + } + + .lg-col-5{ + width:41.66667%; + } + + .lg-col-6{ + width:50%; + } + + .lg-col-7{ + width:58.33333%; + } + + .lg-col-8{ + width:66.66667%; + } + + .lg-col-9{ + width:75%; + } + + .lg-col-10{ + width:83.33333%; + } + + .lg-col-11{ + width:91.66667%; + } + + .lg-col-12{ + width:100%; + } + +} +.flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } + +@media (min-width: 40em){ + .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } +} + +@media (min-width: 52em){ + .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } +} + +@media (min-width: 64em){ + .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } +} + +.flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column } +.flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap } + +.items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start } +.items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end } +.items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center } +.items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline } +.items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch } + +.self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start } +.self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end } +.self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center } +.self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline } +.self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch } + +.justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start } +.justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end } +.justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center } +.justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between } +.justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around } + +.content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start } +.content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end } +.content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center } +.content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between } +.content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around } +.content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch } +.flex-auto{ + -webkit-box-flex:1; + -webkit-flex:1 1 auto; + -ms-flex:1 1 auto; + flex:1 1 auto; + min-width:0; + min-height:0; +} +.flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none } + +.order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 } +.order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 } +.order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 } +.order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 } +.order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 } + +.relative{ position:relative } +.absolute{ position:absolute } +.fixed{ position:fixed } + +.top-0{ top:0 } +.right-0{ right:0 } +.bottom-0{ bottom:0 } +.left-0{ left:0 } + +.z1{ z-index: 1 } +.z2{ z-index: 2 } +.z3{ z-index: 3 } +.z4{ z-index: 4 } + +.border{ + border-style:solid; + border-width: 1px; +} + +.border-top{ + border-top-style:solid; + border-top-width: 1px; +} + +.border-right{ + border-right-style:solid; + border-right-width: 1px; +} + +.border-bottom{ + border-bottom-style:solid; + border-bottom-width: 1px; +} + +.border-left{ + border-left-style:solid; + border-left-width: 1px; +} + +.border-none{ border:0 } + +.rounded{ border-radius: 3px } +.circle{ border-radius:50% } + +.rounded-top{ border-radius: 3px 3px 0 0 } +.rounded-right{ border-radius: 0 3px 3px 0 } +.rounded-bottom{ border-radius: 0 0 3px 3px } +.rounded-left{ border-radius: 3px 0 0 3px } + +.not-rounded{ border-radius:0 } + +.hide{ + position:absolute !important; + height:1px; + width:1px; + overflow:hidden; + clip:rect(1px, 1px, 1px, 1px); +} + +@media (max-width: 40em){ + .xs-hide{ display:none !important } +} + +@media (min-width: 40em) and (max-width: 52em){ + .sm-hide{ display:none !important } +} + +@media (min-width: 52em) and (max-width: 64em){ + .md-hide{ display:none !important } +} + +@media (min-width: 64em){ + .lg-hide{ display:none !important } +} + +.display-none{ display:none !important } + diff --git a/doc/assets/fonts/EOT/SourceCodePro-Bold.eot b/doc/assets/fonts/EOT/SourceCodePro-Bold.eot new file mode 100644 index 0000000..d24cc39 Binary files /dev/null and b/doc/assets/fonts/EOT/SourceCodePro-Bold.eot differ diff --git a/doc/assets/fonts/EOT/SourceCodePro-Regular.eot b/doc/assets/fonts/EOT/SourceCodePro-Regular.eot new file mode 100644 index 0000000..09e9473 Binary files /dev/null and b/doc/assets/fonts/EOT/SourceCodePro-Regular.eot differ diff --git a/doc/assets/fonts/LICENSE.txt b/doc/assets/fonts/LICENSE.txt new file mode 100644 index 0000000..1177330 --- /dev/null +++ b/doc/assets/fonts/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/doc/assets/fonts/OTF/SourceCodePro-Bold.otf b/doc/assets/fonts/OTF/SourceCodePro-Bold.otf new file mode 100644 index 0000000..f4e576c Binary files /dev/null and b/doc/assets/fonts/OTF/SourceCodePro-Bold.otf differ diff --git a/doc/assets/fonts/OTF/SourceCodePro-Regular.otf b/doc/assets/fonts/OTF/SourceCodePro-Regular.otf new file mode 100644 index 0000000..4e3b9d0 Binary files /dev/null and b/doc/assets/fonts/OTF/SourceCodePro-Regular.otf differ diff --git a/doc/assets/fonts/TTF/SourceCodePro-Bold.ttf b/doc/assets/fonts/TTF/SourceCodePro-Bold.ttf new file mode 100644 index 0000000..e0c576f Binary files /dev/null and b/doc/assets/fonts/TTF/SourceCodePro-Bold.ttf differ diff --git a/doc/assets/fonts/TTF/SourceCodePro-Regular.ttf b/doc/assets/fonts/TTF/SourceCodePro-Regular.ttf new file mode 100644 index 0000000..437f472 Binary files /dev/null and b/doc/assets/fonts/TTF/SourceCodePro-Regular.ttf differ diff --git a/doc/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff new file mode 100644 index 0000000..cf96099 Binary files /dev/null and b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff differ diff --git a/doc/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff new file mode 100644 index 0000000..395436e Binary files /dev/null and b/doc/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff differ diff --git a/doc/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff new file mode 100644 index 0000000..c65ba84 Binary files /dev/null and b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff differ diff --git a/doc/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff new file mode 100644 index 0000000..0af792a Binary files /dev/null and b/doc/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff differ diff --git a/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 new file mode 100644 index 0000000..cbe3835 Binary files /dev/null and b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 differ diff --git a/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 new file mode 100644 index 0000000..65cd591 Binary files /dev/null and b/doc/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 differ diff --git a/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 new file mode 100644 index 0000000..b78d523 Binary files /dev/null and b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 differ diff --git a/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 new file mode 100644 index 0000000..18d2199 Binary files /dev/null and b/doc/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 differ diff --git a/doc/assets/fonts/source-code-pro.css b/doc/assets/fonts/source-code-pro.css new file mode 100644 index 0000000..3abb4f0 --- /dev/null +++ b/doc/assets/fonts/source-code-pro.css @@ -0,0 +1,23 @@ +@font-face{ + font-family: 'Source Code Pro'; + font-weight: 400; + font-style: normal; + font-stretch: normal; + src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'), + url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'), + url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'), + url('OTF/SourceCodePro-Regular.otf') format('opentype'), + url('TTF/SourceCodePro-Regular.ttf') format('truetype'); +} + +@font-face{ + font-family: 'Source Code Pro'; + font-weight: 700; + font-style: normal; + font-stretch: normal; + src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'), + url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'), + url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'), + url('OTF/SourceCodePro-Bold.otf') format('opentype'), + url('TTF/SourceCodePro-Bold.ttf') format('truetype'); +} diff --git a/doc/assets/github.css b/doc/assets/github.css new file mode 100644 index 0000000..8852abb --- /dev/null +++ b/doc/assets/github.css @@ -0,0 +1,123 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + -webkit-text-size-adjust: none; +} + +.hljs-comment, +.diff .hljs-header, +.hljs-javadoc { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #1184CE; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #ed225d; +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-phpdoc, +.hljs-dartdoc, +.tex .hljs-formula { + color: #ed225d; +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #900; + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rules .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body { + color: #008080; +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} diff --git a/doc/assets/site.js b/doc/assets/site.js new file mode 100644 index 0000000..559c65e --- /dev/null +++ b/doc/assets/site.js @@ -0,0 +1,108 @@ +/* global anchors */ + +// add anchor links to headers +anchors.options.placement = 'left'; +anchors.add('h3'); + +// Filter UI +var tocElements = document.getElementById('toc') + .getElementsByTagName('li'); + +document.getElementById('filter-input') + .addEventListener('keyup', function (e) { + + var i, element, children; + + // enter key + if (e.keyCode === 13) { + // go to the first displayed item in the toc + for (i = 0; i < tocElements.length; i++) { + element = tocElements[i]; + if (!element.classList.contains('display-none')) { + location.replace(element.firstChild.href); + return e.preventDefault(); + } + } + } + + var match = function () { + return true; + }; + + var value = this.value.toLowerCase(); + + if (!value.match(/^\s*$/)) { + match = function (element) { + return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1; + }; + } + + for (i = 0; i < tocElements.length; i++) { + element = tocElements[i]; + children = Array.from(element.getElementsByTagName('li')); + if (match(element) || children.some(match)) { + element.classList.remove('display-none'); + } else { + element.classList.add('display-none'); + } + } + }); + +var toggles = document.getElementsByClassName('toggle-step-sibling'); +for (var i = 0; i < toggles.length; i++) { + toggles[i].addEventListener('click', toggleStepSibling); +} + +function toggleStepSibling() { + var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0]; + var klass = 'display-none'; + if (stepSibling.classList.contains(klass)) { + stepSibling.classList.remove(klass); + stepSibling.innerHTML = '▾'; + } else { + stepSibling.classList.add(klass); + stepSibling.innerHTML = '▸'; + } +} + +var items = document.getElementsByClassName('toggle-sibling'); +for (var j = 0; j < items.length; j++) { + items[j].addEventListener('click', toggleSibling); +} + +function toggleSibling() { + var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0]; + var icon = this.getElementsByClassName('icon')[0]; + var klass = 'display-none'; + if (stepSibling.classList.contains(klass)) { + stepSibling.classList.remove(klass); + icon.innerHTML = '▾'; + } else { + stepSibling.classList.add(klass); + icon.innerHTML = '▸'; + } +} + +function showHashTarget(targetId) { + var hashTarget = document.getElementById(targetId); + // new target is hidden + if (hashTarget && hashTarget.offsetHeight === 0 && + hashTarget.parentNode.parentNode.classList.contains('display-none')) { + hashTarget.parentNode.parentNode.classList.remove('display-none'); + } +} + +window.addEventListener('hashchange', function() { + showHashTarget(location.hash.substring(1)); +}); + +showHashTarget(location.hash.substring(1)); + +var toclinks = document.getElementsByClassName('pre-open'); +for (var k = 0; k < toclinks.length; k++) { + toclinks[k].addEventListener('mousedown', preOpen, false); +} + +function preOpen() { + showHashTarget(this.hash.substring(1)); +} diff --git a/doc/assets/style.css b/doc/assets/style.css new file mode 100644 index 0000000..d7e56e0 --- /dev/null +++ b/doc/assets/style.css @@ -0,0 +1,136 @@ +.documentation { + font-family: Helvetica, sans-serif; + color: #666; + line-height: 1.5; + background: #f5f5f5; +} + +.black { + color: #666; +} + +.bg-white { + background-color: #fff; +} + +h4 { + margin: 20px 0 10px 0; +} + +.documentation h3 { + color: #000; +} + +.border-bottom { + border-color: #ddd; +} + +a { + color: #1184CE; + text-decoration: none; +} + +.documentation a[href]:hover { + text-decoration: underline; +} + +a:hover { + cursor: pointer; +} + +.py1-ul li { + padding: 5px 0; +} + +.max-height-100 { + max-height: 100%; +} + +section:target h3 { + font-weight:700; +} + +.documentation td, +.documentation th { + padding: .25rem .25rem; +} + +h1:hover .anchorjs-link, +h2:hover .anchorjs-link, +h3:hover .anchorjs-link, +h4:hover .anchorjs-link { + opacity: 1; +} + +.fix-3 { + width: 25%; + max-width: 244px; +} + +.fix-3 { + width: 25%; + max-width: 244px; +} + +@media (min-width: 52em) { + .fix-margin-3 { + margin-left: 25%; + } +} + +.pre, pre, code, .code { + font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace; + font-size: 14px; +} + +.fill-light { + background: #F9F9F9; +} + +.width2 { + width: 1rem; +} + +.input { + font-family: inherit; + display: block; + width: 100%; + height: 2rem; + padding: .5rem; + margin-bottom: 1rem; + border: 1px solid #ccc; + font-size: .875rem; + border-radius: 3px; + box-sizing: border-box; +} + +table { + border-collapse: collapse; +} + +.prose table th, +.prose table td { + text-align: left; + padding:8px; + border:1px solid #ddd; +} + +.prose table th:nth-child(1) { border-right: none; } +.prose table th:nth-child(2) { border-left: none; } + +.prose table { + border:1px solid #ddd; +} + +.prose-big { + font-size: 18px; + line-height: 30px; +} + +.quiet { + opacity: 0.7; +} + +.minishadow { + box-shadow: 2px 2px 10px #f3f3f3; +} diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..fd2cd49 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,747 @@ + + + + + S-UID 1.3.1 | Documentation + + + + + + +
+
+
+
+

S-UID

+
1.3.1
+ +
+ +
+ +
+
+
+ + +
+ + +
+ +

+ uid +

+ + +
+ + +

generate random id based on template string. +Default template string is 'xxxxxxxx-xxxx-1xxx-1xxx-xxxxxxxxxxxx'.

+
+

Template rules very simple:

+

base - it's a string for creating id. Rewrite only special characters

+

N - Rewrite to random Number

+

H - Rewrite to random hex numder

+

S - Rewrite to random english symbol

+

X - Rewrite to any from "N","H","S"

+
+ + +
uid(base: String?): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ base (String?) + : +[ +default: 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX' +] + +
+ +
+ +
+ + + + + + +
Returns
+ String: + + + + + + + + + +
Example
+ + +
uid();
+uid('XXX-4NNN-dummy-SSS');
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ uid._time +

+ + +
+ + +

Humanized time string. +This method is very sensitive to the correctness of the input arguments

+ + +
uid._time(separator: String, date: Date): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ separator (String) + Separator character for output + +
+ +
+ +
+
+ date (Date) + instance of Date constructor + +
+ +
+ +
+ + + + + + +
Returns
+ String: + + + + + + + + + +
Example
+ + +
uid._time('-', new Date() );
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ uid._date +

+ + +
+ + +

Humanized date string. +This method is very sensitive to the correctness of the input arguments

+ + +
uid._date(separator: String, date: Date): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ separator (String) + Separator character for output + +
+ +
+ +
+
+ date (Date) + instance of Date constructor + +
+ +
+ +
+ + + + + + +
Returns
+ String: + + + + + + + + + +
Example
+ + +
uid._date('-', new Date() );
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ uid.time +

+ + +
+ + +

Humanized date+time string. Safe method.

+ + +
uid.time(date: Date?, separator1: String?, separator2: String?, separator3: String?, time: any): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ date (Date?) + : +[ +default: new Date() +] + - instance of Date constructor + +
+ +
+ +
+
+ separator1 (String?) + : +[ +default: ' - ' +] + - Separator character for output date + +
+ +
+ +
+
+ separator2 (String?) + : +[ +default: ' \s ' +] + - Separator character for output bitwin date and time + +
+ +
+ +
+
+ separator3 (String?) + : +[ +default: ' : ' +] + - Separator character for output time + +
+ +
+ +
+
+ time (any) + +
+ +
+ +
+ + + + + + +
Returns
+ String: + + + + + + + + + +
Example
+ + +
uid.time();
+uid.time( new Date() );
+uid.time( new Date(), '-', ':', '-');
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ uid.th +

+ + +
+ + +

hash based on time in 36 numerical system by default

+ + +
uid.th(date: Date?, Number: Number): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ date (Date?) + : +[ +default: new Date() +] + - instance of Date constructor + +
+ +
+ +
+
+ Number (Number) + [ +bit +] +: +[ +default: 36 +] + - expect number 2-36 + +
+ +
+ +
+ + + + + + +
Returns
+ String: + hash string + + + + + + + + +
Example
+ + +
uid.th();
+uid.th(null, 4);
+uid.th(new Date(), 10);
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ uid.guid +

+ + +
+ + +

generate uuid (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx) +based on time, reserved characters and random symbols

+ + +
uid.guid(M: String?, N: String?, time: Date?): String
+ + + + + + + + + + +
Parameters
+
+ +
+
+ M (String?) + [ +default: random english symbol ( uid('S') ) +] + +
+ +
+ +
+
+ N (String?) + [ +default: random number ( uid('N') ) +] + +
+ +
+ +
+
+ time (Date?) + [ +default: new Date() +] + - date of guid generation + +
+ +
+ +
+ + + + + + +
Returns
+ String: + + + + + + + + + +
Example
+ + +
uid.guid();
+uid.guid('M', 0, new Date() );
+ + + + + + + + +
+ + + + +
+ + +
+ +

+ exports +

+ + +
+ + +

defination on platforms (both variants on platform like Electron)

+

bower i --save s-uid

+

npm i --save s-uid

+ + +
exports
+ + + + + + + + + + + + + + + + + + +
Example
+ + +
window.uid || window['s-uid'] // in browser
+ + +
var uid = require('s-uid')    // in Node.js
+ + + + + + + + +
+ + + +
+
+
+ + + + diff --git a/gulpfile.js b/gulpfile.js index 56005be..4227aea 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,9 +1,11 @@ var gulp = require('gulp'); var wrapper = require('gulp-wrap'); -var anonymous = '(function () {\'use strict\';\n<%= contents %>\n})()'; -var license = '/**\n * s-uid\ - \n * MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera )\ +var pkg = require('./package.json'); +var date = (new Date).toISOString().substring(0,10); +var anonymous = '/** @ignore */\n(function () {\'use strict\';\n<%= contents %>\n})()'; +var license = '/*\n * s-uid version '+pkg.version+' at '+date+'\ + \n * @license MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera )\ \n */\n<%= contents %> '; @@ -20,20 +22,71 @@ function src ( name ) { } gulp.task('concat', function () { - return src('uid.js') + return src('s-uid.js') .pipe( wrapper(license) ) .pipe( gulp.dest('./') ); }); gulp.task('minify', function () { - return src('uid.min.js') + return src('s-uid.min.js') .pipe( require('gulp-uglify')() ) .pipe( wrapper(license) ) .pipe( gulp.dest('./') ); }); gulp.task('watch', function () { - gulp.watch('lib/*.js', ['concat']); +}); + +gulp.task('lint', function () { + return gulp.src(['s-uid.js','s-uid.min.js']) + .pipe( require('gulp-eslint')() ) + .pipe( require('gulp-eslint').format() ) + .pipe( require('gulp-eslint').failAfterError() ); +}); + +gulp.task('test', function ( done ) { + return gulp.src('test/test.js', {read: false}) + .pipe( require('gulp-mocha')({reporter: 'nyan'}) ); +}); + +gulp.task('doc', function () { + var doc = require('gulp-documentation'); + return gulp.src('s-uid.js') + .pipe( doc('html', {}, { + name: pkg.name.toUpperCase(), + version: pkg.version, + license: pkg.license, + date: date + }) ) + .pipe( gulp.dest('doc') ); +}); + +gulp.task('doc-md', function () { + var doc = require('gulp-documentation'); + return gulp.src('s-uid.js') + .pipe( doc('md', {}, { + name: pkg.name.toUpperCase(), + version: pkg.version, + license: pkg.license, + date: date, + }) ) + .pipe( gulp.dest('doc') ); +}); -}); \ No newline at end of file +gulp.task('doc-json', function () { + var doc = require('gulp-documentation'); + return gulp.src('s-uid.js') + .pipe( doc('json', {}, { + name: pkg.name.toUpperCase(), + version: pkg.version, + license: pkg.license, + date: date + }) ) + .pipe( gulp.dest('doc') ); +}); + +gulp.task('build', ['concat', 'minify'], function () { + // gulp.start('lint'); + // gulp.start('test'); +}); diff --git a/lib/define.js b/lib/define.js index 71ec91a..a0768eb 100644 --- a/lib/define.js +++ b/lib/define.js @@ -1,11 +1,20 @@ /** - * EXPORTS + * @description + defination on platforms (both variants on platform like Electron) + + bower i --save s-uid + + npm i --save s-uid + + * @example window.uid || window['s-uid'] // in browser + * @example var uid = require('s-uid') // in Node.js * - * @public + * @exports s-uid + * @publick */ if ( typeof process != 'undefined' && Object.prototype.toString.call(process) == '[object process]' ) { module.exports = uid; } if ( typeof window != 'undefined' && Object.prototype.toString.call(window) == '[object Window]' ) { - window['uid'] = uid; + window['uid'] = window['s-uid'] = uid; } diff --git a/lib/guid.js b/lib/guid.js index 4828ff1..13a68a1 100644 --- a/lib/guid.js +++ b/lib/guid.js @@ -1,20 +1,27 @@ /** - * generate uuid - * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx - * - * @param M: { String } - [option] - * @param N: { String } - [option] - * @param time: { Object } - [option] expect new Date() - * @returns: { Object } + * @description + generate uuid (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx) + based on time, reserved characters and random symbols + + * @example + uid.guid(); + uid.guid('M', 0, new Date() ); + + * @param { String } [M] [default: random english symbol ( uid('S') )] + * @param { String } [N] [default: random number ( uid('N') )] + * @param { Date } [time] [default: new Date()] - date of guid generation + * @returns { String } + * @function uid.guid + * @publick */ uid['guid'] = guid; function guid ( M, N, time ) { time = time instanceof Date ? time : new Date; M = typeof M == 'string' && M.length == 1 ? M : uid('S'); N = typeof N == 'string' && N.length == 1 ? N : uid('N'); - return ts.call(time.valueOf(), 36)+'-'+ - ts.call((''+time.getFullYear()+time.getMonth())*1, 36)+'-'+ - M+ts.call((''+time.getDay()+time.getHours()+time.getMinutes())*1, 36)+'-'+ - N+ts.call((''+time.getSeconds()+time.getMilliseconds())*1, 36)+'-'+ - uid('XXXXXXXXXXXX'); -} \ No newline at end of file + return ts.call(time.valueOf(), 36) + +'-'+ts.call((''+time.getFullYear()+time.getMonth())*1, 36) + +'-'+M+ts.call((''+time.getDay()+time.getHours()+time.getMinutes())*1, 36) + +'-'+N+ts.call((''+time.getSeconds()+time.getMilliseconds())*1, 36) + +'-'+uid('XXXXXXXXXXXX'); +} diff --git a/lib/time.js b/lib/time.js index fcc450e..7247020 100644 --- a/lib/time.js +++ b/lib/time.js @@ -1,47 +1,95 @@ -var ts = Number.prototype.toString; +/** + * method of converting number to string with static length + * if number does not have enough length add '0' in to begin of string + * @param { Number } val - any number + * @param { Number } len - expected min length + * @returns { String } + * @function uid._time + * @private + */ function to ( val, len ) { val = val.toString(); while ( val.toString().length < len ) val = '0'+val; return val; -} +}; /** - * hash based on time in 36 numerical system by default - * - * @param base: { Number } - [option] expect 2-36 (36) - * @param time: { Object } - [option] expect new Date() - * @returns: { String } - hash + * Humanized date string. + * This method is very sensitive to the correctness of the input arguments + * @example + uid._date('-', new Date() ); + + * @param { String } separator - Separator character for output + * @param { Date } date - instance of Date constructor + * @returns { String } + * @function uid._date + * @public */ -uid['th'] = function ( base, time ) { - return ts.call( - (time instanceof Date ? time : new Date).valueOf(), - typeof base == 'number' && base > 0 ? base%37 : 36 - ); -} +uid['_date'] = _date; +function _date ( separator, date ) { + return to(date.getFullYear(),4) + +separator+to(date.getMonth(),2) + +separator+to(date.getDate(),2); +}; /** - * humanized time stamp - * - * @param sep: { String } - expect '-' - * @param time: { Object } - expect new Date() - * @returns: { String } + * Humanized time string. + * This method is very sensitive to the correctness of the input arguments + * @example + uid._time('-', new Date() ); + + * @param { String } separator - Separator character for output + * @param { Date } date - instance of Date constructor + * @returns { String } + * @function uid._time + * @public */ -uid['_date'] = _date; -function _date ( sep, date ) { return to(date.getFullYear(),4)+sep+to(date.getMonth(),2)+sep+to(date.getDate(),2); }; -uid['_time'] = _time; -function _time ( sep, date ) { return to(date.getHours(),2)+sep+to(date.getMinutes(),2); } +uid['_time'] = _time; +function _time ( sep, date ) { return to(date.getHours(),2)+sep+to(date.getMinutes(),2); }; + /** - * slowest humanized time stamp with checks + * Humanized date+time string. Safe method. * - * @param sep1: { String } - [option] expect '-' - * @param sep2: { String } - [option] expect ':' - * @param time: { Object } - [option] expect new Date() - * @returns: { String } + * @example + uid.time(); + uid.time( new Date() ); + uid.time( new Date(), '-', ':', '-'); + + * @param { Date } [date]:[default: new Date()] - instance of Date constructor + * @param { String } [separator1]:[default: ' - '] - Separator character for output date + * @param { String } [separator2]:[default: ' \s '] - Separator character for output bitwin date and time + * @param { String } [separator3]:[default: ' : '] - Separator character for output time + * @returns { String } + * @function uid.time + * @public */ -uid['time'] = function ( sep1, sep2, time ) { +uid['time'] = function ( time, separator1, separator2, separator3 ) { time = time instanceof Date ? time : new Date; - sep1 = typeof sep1 == 'string'? sep1 : '-'; - sep2 = typeof sep2 == 'string'? sep2 : ':'; - return _date(sep1, time)+sep1+_time(sep2, time); -} \ No newline at end of file + separator1 = typeof separator1 == 'string'? separator1 : '-'; + separator2 = typeof separator2 == 'string'? separator2 : ' '; + separator3 = typeof separator3 == 'string'? separator3 : ':'; + return _date(separator1, time)+separator2+_time(separator3, time); +}; + +/** + * hash based on time in 36 numerical system by default + * + * @example + uid.th(); + uid.th(null, 4); + uid.th(new Date(), 10); + + * @param { Date } [date]:[default: new Date()] - instance of Date constructor + * @param { Number } - [bit]:[default: 36] - expect number 2-36 + * @returns { String } - hash string + * @function uid.th + * @public + */ +var ts = Number.prototype.toString; +uid['th'] = function ( time, bit ) { + return ts.call( + (time instanceof Date ? time : new Date).valueOf(), + typeof bit == 'number' && bit >= 2 && bit <= 36 ? bit : 36 + ); +}; diff --git a/lib/uid.js b/lib/uid.js index 451d0bb..afd79d4 100644 --- a/lib/uid.js +++ b/lib/uid.js @@ -1,20 +1,41 @@ /** - * generate a random string by base - * - * @param: { String } - [option] base for uid - * @returns: { String } + * @description + generate random id based on template string. + Default template string is 'xxxxxxxx-xxxx-1xxx-1xxx-xxxxxxxxxxxx'. + + >Template rules very simple: + + >**base** - it's a string for creating id. Rewrite only special characters + + >**N** - Rewrite to random Number + + >**H** - Rewrite to random hex numder + + >**S** - Rewrite to random english symbol + + >**X** - Rewrite to any from "N","H","S" + + * @example + uid(); + uid('XXX-4NNN-dummy-SSS'); + + * @param { String } [base]:[default: 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX'] + * @returns { String } + * @function uid + * @publick */ function uid ( base ) { // check data type - base = typeof base == 'string' ? base : (!uid.DEBUG ? 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX' : - ( (function(){ throw new Error('Wrong data type of base for uid generate: '+base); })())); + base = typeof base == 'string' ? base + : (!uid.DEBUG ? 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX' + : ( (function(){ throw new Error('Wrong data type of base for uid generate: '+base); })())); // generate from base return base.replace(/[X|S|N|H]/g, function ( s ) { return ( - s == 'X' ? Math.random()*32|0 : - s == 'N' ? Math.random()*10|0 : - s == 'H' ? Math.random()*16|0 : - /*s == 'S'*/Math.random()*32|10 + s == 'X' ? Math.random()*32|0 + : s == 'N' ? Math.random()*10|0 + : s == 'H' ? Math.random()*16|0 + : /*s == 'S'*/Math.random()*32|10 ).toString(32); }); }; diff --git a/package.json b/package.json index 6b04564..c8e57f1 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "s-uid", - "version": "1.3.0", + "version": "1.3.1", "description": "Generate id from base string", "main": "uid.min.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "rebuild": "gulp concat&gulp minify", - "debug": "devtool test" + "tables": "node test/write-tables", + "rebuild": "gulp build&&npm run test&&gulp doc&&gulp doc-md", + "test": "gulp lint&&gulp test", + "debug": "devtool s-uid" }, "homepage": "https://github.com/sajera/s-uid#readme", "repository": { @@ -25,11 +26,19 @@ "license": "MIT", "dependencies": {}, "devDependencies": { + "chai": "^3.5.0", + "eslint": "^3.12.2", "gulp": "^3.9.1", + "devtool": "^2.3.1", "gulp-concat": "^2.6.1", + "gulp-documentation": "^3.1.0", + "gulp-eslint": "^3.0.1", + "gulp-mocha": "^3.0.1", "gulp-order": "^1.1.1", "gulp-uglify": "^2.0.0", "gulp-wrap": "^0.13.0", + "mocha": "^3.2.0", + "q": "^1.4.1", "s-is": "^1.2.0" } -} \ No newline at end of file +} diff --git a/readme.md b/readme.md index b0e872c..722ee76 100644 --- a/readme.md +++ b/readme.md @@ -83,6 +83,9 @@ uid(null); ``` +#### [```API documentation ```](https://github.com/sajera/s-uid/blob/master/doc/API.md) + + [npm-image]: https://badge.fury.io/js/s-uid.svg [npm-url]: https://npmjs.org/package/s-uid [license-image]: http://img.shields.io/npm/l/s-uid.svg diff --git a/s-uid.js b/s-uid.js new file mode 100644 index 0000000..23b2005 --- /dev/null +++ b/s-uid.js @@ -0,0 +1,194 @@ +/* + * s-uid version 1.3.1 at 2017-06-24 + * @license MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera ) + */ +/** @ignore */ +(function () {'use strict'; +/** + * @description + generate random id based on template string. + Default template string is 'xxxxxxxx-xxxx-1xxx-1xxx-xxxxxxxxxxxx'. + + >Template rules very simple: + + >**base** - it's a string for creating id. Rewrite only special characters + + >**N** - Rewrite to random Number + + >**H** - Rewrite to random hex numder + + >**S** - Rewrite to random english symbol + + >**X** - Rewrite to any from "N","H","S" + + * @example + uid(); + uid('XXX-4NNN-dummy-SSS'); + + * @param { String } [base]:[default: 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX'] + * @returns { String } + * @function uid + * @publick + */ +function uid ( base ) { + // check data type + base = typeof base == 'string' ? base + : (!uid.DEBUG ? 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX' + : ( (function(){ throw new Error('Wrong data type of base for uid generate: '+base); })())); + // generate from base + return base.replace(/[X|S|N|H]/g, function ( s ) { + return ( + s == 'X' ? Math.random()*32|0 + : s == 'N' ? Math.random()*10|0 + : s == 'H' ? Math.random()*16|0 + : /*s == 'S'*/Math.random()*32|10 + ).toString(32); + }); +}; + + +/** + * method of converting number to string with static length + * if number does not have enough length add '0' in to begin of string + * @param { Number } val - any number + * @param { Number } len - expected min length + * @returns { String } + * @function uid._time + * @private + */ +function to ( val, len ) { + val = val.toString(); + while ( val.toString().length < len ) val = '0'+val; + return val; +}; + +/** + * Humanized date string. + * This method is very sensitive to the correctness of the input arguments + * @example + uid._date('-', new Date() ); + + * @param { String } separator - Separator character for output + * @param { Date } date - instance of Date constructor + * @returns { String } + * @function uid._date + * @public + */ +uid['_date'] = _date; +function _date ( separator, date ) { + return to(date.getFullYear(),4) + +separator+to(date.getMonth(),2) + +separator+to(date.getDate(),2); +}; + +/** + * Humanized time string. + * This method is very sensitive to the correctness of the input arguments + * @example + uid._time('-', new Date() ); + + * @param { String } separator - Separator character for output + * @param { Date } date - instance of Date constructor + * @returns { String } + * @function uid._time + * @public + */ +uid['_time'] = _time; +function _time ( sep, date ) { return to(date.getHours(),2)+sep+to(date.getMinutes(),2); }; + +/** + * Humanized date+time string. Safe method. + * + * @example + uid.time(); + uid.time( new Date() ); + uid.time( new Date(), '-', ':', '-'); + + * @param { Date } [date]:[default: new Date()] - instance of Date constructor + * @param { String } [separator1]:[default: ' - '] - Separator character for output date + * @param { String } [separator2]:[default: ' \s '] - Separator character for output bitwin date and time + * @param { String } [separator3]:[default: ' : '] - Separator character for output time + * @returns { String } + * @function uid.time + * @public + */ +uid['time'] = function ( time, separator1, separator2, separator3 ) { + time = time instanceof Date ? time : new Date; + separator1 = typeof separator1 == 'string'? separator1 : '-'; + separator2 = typeof separator2 == 'string'? separator2 : ' '; + separator3 = typeof separator3 == 'string'? separator3 : ':'; + return _date(separator1, time)+separator2+_time(separator3, time); +}; + +/** + * hash based on time in 36 numerical system by default + * + * @example + uid.th(); + uid.th(null, 4); + uid.th(new Date(), 10); + + * @param { Date } [date]:[default: new Date()] - instance of Date constructor + * @param { Number } - [bit]:[default: 36] - expect number 2-36 + * @returns { String } - hash string + * @function uid.th + * @public + */ +var ts = Number.prototype.toString; +uid['th'] = function ( time, bit ) { + return ts.call( + (time instanceof Date ? time : new Date).valueOf(), + typeof bit == 'number' && bit >= 2 && bit <= 36 ? bit : 36 + ); +}; + +/** + * @description + generate uuid (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx) + based on time, reserved characters and random symbols + + * @example + uid.guid(); + uid.guid('M', 0, new Date() ); + + * @param { String } [M] [default: random english symbol ( uid('S') )] + * @param { String } [N] [default: random number ( uid('N') )] + * @param { Date } [time] [default: new Date()] - date of guid generation + * @returns { String } + * @function uid.guid + * @publick + */ +uid['guid'] = guid; +function guid ( M, N, time ) { + time = time instanceof Date ? time : new Date; + M = typeof M == 'string' && M.length == 1 ? M : uid('S'); + N = typeof N == 'string' && N.length == 1 ? N : uid('N'); + return ts.call(time.valueOf(), 36) + +'-'+ts.call((''+time.getFullYear()+time.getMonth())*1, 36) + +'-'+M+ts.call((''+time.getDay()+time.getHours()+time.getMinutes())*1, 36) + +'-'+N+ts.call((''+time.getSeconds()+time.getMilliseconds())*1, 36) + +'-'+uid('XXXXXXXXXXXX'); +} + +/** + * @description + defination on platforms (both variants on platform like Electron) + + bower i --save s-uid + + npm i --save s-uid + + * @example window.uid || window['s-uid'] // in browser + * @example var uid = require('s-uid') // in Node.js + * + * @exports s-uid + * @publick + */ +if ( typeof process != 'undefined' && Object.prototype.toString.call(process) == '[object process]' ) { + module.exports = uid; +} +if ( typeof window != 'undefined' && Object.prototype.toString.call(window) == '[object Window]' ) { + window['uid'] = window['s-uid'] = uid; +} + +})() \ No newline at end of file diff --git a/uid.min.js b/s-uid.min.js similarity index 54% rename from uid.min.js rename to s-uid.min.js index 957050e..893d905 100644 --- a/uid.min.js +++ b/s-uid.min.js @@ -1,5 +1,5 @@ -/** - * s-uid - * MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera ) +/* + * s-uid version 1.3.1 at 2017-06-24 + * @license MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera ) */ -!function(){"use strict";function t(e){return e="string"==typeof e?e:t.DEBUG?function(){throw new Error("Wrong data type of base for uid generate: "+e)}():"XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX",e.replace(/[X|S|N|H]/g,function(t){return("X"==t?32*Math.random()|0:"N"==t?10*Math.random()|0:"H"==t?16*Math.random()|0:32*Math.random()|10).toString(32)})}function e(t,e){for(t=t.toString();t.toString().length0?t%37:36)},t._date=n,t._time=o,t.time=function(t,e,r){return r=r instanceof Date?r:new Date,t="string"==typeof t?t:"-",e="string"==typeof e?e:":",n(t,r)+t+o(e,r)},t.guid=r,"undefined"!=typeof process&&"[object process]"==Object.prototype.toString.call(process)&&(module.exports=t),"undefined"!=typeof window&&"[object Window]"==Object.prototype.toString.call(window)&&(window.uid=t)}(); \ No newline at end of file +!function(){"use strict";function t(e){return e="string"==typeof e?e:t.DEBUG?function(){throw new Error("Wrong data type of base for uid generate: "+e)}():"XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX",e.replace(/[X|S|N|H]/g,function(t){return("X"==t?32*Math.random()|0:"N"==t?10*Math.random()|0:"H"==t?16*Math.random()|0:32*Math.random()|10).toString(32)})}function e(t,e){for(t=t.toString();t.toString().length=2&&e<=36?e:36)},t.guid=r,"undefined"!=typeof process&&"[object process]"==Object.prototype.toString.call(process)&&(module.exports=t),"undefined"!=typeof window&&"[object Window]"==Object.prototype.toString.call(window)&&(window.uid=window["s-uid"]=t)}(); \ No newline at end of file diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..aa48ec9 --- /dev/null +++ b/test/test.js @@ -0,0 +1,171 @@ +/* +* Unit tests for s-uid.min.js +*/ +var uid = require('../s-uid.min.js'); + +// require('chai').should(); +var expect = require('chai').expect; +var assert = require('chai').assert; + +/** + * indexOf work very slow with gigantic array + * this is a reason why i create many arrays to matching unique + * It's amazing, but it works much faster + * @param: { String } uniq - Value to be checked for uniqueness + * @param: { Array } store - array with arrays with values to be compared + * @returns { Boolean } + * @function + * @public + */ +function customMatching ( uniq, store ) { + for ( var arr of store ) { + if ( arr.indexOf(uniq) > -1 ) return true; + } + if ( store[store.length-1].length < 100 ) { + store[store.length-1].push(uniq); + } else { + store.push([uniq]); + } + return false; +} + +describe('TESTS', function () { + + describe('uid() case default base', function () { + + it('simple data types', function () { + assert.isString(uid(), 'must be a string'); + assert.equal(uid().length, '36', 'lenght of default base must be 36'); + assert.equal(uid().split('-').length, '5', 'default base Consists of 5 parts'); + }); + + it('uid log time of creation 10 000 uids', function () { + var key = 10*1000; + console.time('uid case default base: 10 000'); + while (key--) uid(); + console.timeEnd('uid case default base: 10 000'); + }); + + it('uid matches 10 000 uids', function () { + var key = 10*1000; + var storeUid = [[]]; + while ( key-- ) { + assert.isNotTrue( + customMatching(uid(), storeUid), + 'match found on '+key+' item !' + ); + } + }); + }); + + describe('uid("XXX-4NNN-dummy-SSS") case custom base', function () { + + it('simple data types', function () { + assert.isString(uid('XXX-4NNN-dummy-SSS'), 'must be a string'); + assert.equal(uid('XXX-4NNN-dummy-SSS').length, '18', 'lenght of custom base must be 18'); + assert.equal(uid('XXX-4NNN-dummy-SSS').split('-').length, '4', 'custom base Consists of 4 parts'); + }); + + it('uid log time of creation 10 000 uids', function () { + var key = 10*1000; + console.time('uid case XXX-4NNN-dummy-SSS base: 10 000'); + while (key--) uid('XXX-4NNN-dummy-SSS'); + console.timeEnd('uid case XXX-4NNN-dummy-SSS base: 10 000'); + }); + + it('uid matches 10 000 uids', function () { + var key = 10*1000; + var storeUid = [[]]; + while ( key-- ) { + assert.isNotTrue( + customMatching(uid('XXX-4NNN-dummy-SSS'), storeUid), + 'match found on '+key+' item !' + ); + } + }); + }); + + describe('uid.guid() default', function () { + + it('simple data types', function () { + assert.isString(uid.guid(), 'must be a string'); + assert.equal(uid.guid().split('-').length, '5', 'default base Consists of 5 parts'); + }); + + it('uid.guid log time of creation 10 000 guids', function () { + var key = 10*1000; + console.time('uid.guid case default 10 000'); + while (key--) uid.guid(); + console.timeEnd('uid.guid case default 10 000'); + }); + + it('uid.guid matches 10 000 uids based on one time', function () { + // iven fast match its to long for "chai" + this.timeout(10*1000); + var key = 10*1000; + var time = new Date(); + var storeGuid = [[]]; + while ( key-- ) { + assert.isNotTrue( + customMatching(uid.guid(null, null, time), storeGuid), + 'match found on '+key+' item !' + ); + } + }); + + }); + + describe('uid.time()', function () { + + it('default simple data types', function () { + assert.isString(uid.time(), 'must be a string'); + assert.equal(uid.time().length, '16', 'lenght of time must be 16'); + }); + + it('based on July 21, 1983 01:15:00', function () { + assert.equal( + uid.time(new Date('July 21, 1983 01:15:00'),'_','_','_'), + '1983_06_21_01_15', + 'parse error' + ); + }); + + }); + + describe('uid.th()', function () { + + it('default simple data types', function () { + assert.isString(uid.th(), 'must be a string'); + }); + + it('based on July 21, 1983 01:15:00', function () { + assert.equal( + uid.th(new Date('July 21, 1983 01:15:00'), 2), + '110001110001110001100000110101010100000', + 'convert error on 2 bit' + ); + assert.equal( + uid.th(new Date('July 21, 1983 01:15:00'), 4), + '12032032030012222200', + 'convert error on 4 bit' + ); + assert.equal( + uid.th(new Date('July 21, 1983 01:15:00'), 10), + '427587300000', + 'convert error on 10 bit' + ); + assert.equal( + uid.th(new Date('July 21, 1983 01:15:00'), 18), + '22e7a704g0', + 'convert error on 18 bit' + ); + assert.equal( + uid.th(new Date('July 21, 1983 01:15:00'), 36), + '5gfifs80', + 'convert error on 36 bit' + ); + }); + + }); + +}); diff --git a/test.js b/test/write-tables.js similarity index 83% rename from test.js rename to test/write-tables.js index 1d46d0f..e6f2efe 100644 --- a/test.js +++ b/test/write-tables.js @@ -1,6 +1,6 @@ -console.log('test'); -var uid = require('./uid.min.js'); +console.log('write-tables'); +var uid = require('../s-uid.min.js'); function matchGuid ( key ) { key = key || 100; @@ -73,7 +73,7 @@ function table ( name, methods, testData ) { // make first headers row var table = yellow(td(name, max))+'|'; for ( var method of methods ) table += td(method.replace(/[\(]/g,''), low)+'|'; - // data result rows + // data result rows for (var field in testData ) { table+='\n'+line; table+=('\n'+td(field, max)+'|'); @@ -88,9 +88,7 @@ function table ( name, methods, testData ) { }; // write tables console.log(table('S-UID', - [ - 'uid(' - ], { + ['uid('], { 'undefined' : '', 'String ""' : '', 'NNNNNN' : '\'NNNNNN\'', @@ -103,41 +101,36 @@ console.log(table('S-UID', '\n'); console.log(table('S-UID time based hash', - [ - 'uid.th(' - ], { + ['uid.th('], { 'undefined' : '', 'String ""' : '', - 'Number 0' : '0', - 'Number 10' : '10', - 'Number 16' : '16', - 'Number 32' : '32', - 'Number 36' : '36', + 'Number 4' : 'null, 4', + 'Number 10' : 'null, 10', + 'Number 16' : 'null, 16', + 'Number 32' : 'null, 32', + 'Number 36' : 'null, 36', }), '\n'); console.log(table('S-UID time humanized', - [ - 'uid.time(' - ], { + ['uid.time('], { 'undefined' : '', 'String ""' : '', - '("-",":")' : '"-",":"', - '("_","_")' : '"_","_"', - '("",":")' : '"",":"', - '("&","&")' : '"&","&"', + '("-",":")' : 'null,"-",":"', + '("_","_")' : 'null,"_","_"', + '("",":")' : 'null,"",":"', + '("&","&")' : 'null,"&","&"', + '("&",":","&")' : 'null,"&",":","&"', }), '\n'); console.log(table('S-UID guid', - [ - 'uid.guid(' - ], { + ['uid.guid('], { 'undefined' : '', 'String ""' : '', '("M","N")' : '"M","N"', '("V","")' : '"V",""', '("","N")' : '"","N"', - '("2","4")' : '"&","&"', + '("2","4")' : '"2","4"', }), -'\n'); \ No newline at end of file +'\n'); diff --git a/uid.js b/uid.js deleted file mode 100644 index 8b7ac97..0000000 --- a/uid.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * s-uid - * MIT License Copyright (c) 2016 Serhii Perekhrest ( Sajera ) - */ -(function () {'use strict'; -/** - * generate a random string by base - * - * @param: { String } - [option] base for uid - * @returns: { String } - */ -function uid ( base ) { - // check data type - base = typeof base == 'string' ? base : (!uid.DEBUG ? 'XXXXXXXX-XXXX-1XXX-1XXX-XXXXXXXXXXXX' : - ( (function(){ throw new Error('Wrong data type of base for uid generate: '+base); })())); - // generate from base - return base.replace(/[X|S|N|H]/g, function ( s ) { - return ( - s == 'X' ? Math.random()*32|0 : - s == 'N' ? Math.random()*10|0 : - s == 'H' ? Math.random()*16|0 : - /*s == 'S'*/Math.random()*32|10 - ).toString(32); - }); -}; - - -var ts = Number.prototype.toString; -function to ( val, len ) { - val = val.toString(); - while ( val.toString().length < len ) val = '0'+val; - return val; -} - -/** - * hash based on time in 36 numerical system by default - * - * @param base: { Number } - [option] expect 2-36 (36) - * @param time: { Object } - [option] expect new Date() - * @returns: { String } - hash - */ -uid['th'] = function ( base, time ) { - return ts.call( - (time instanceof Date ? time : new Date).valueOf(), - typeof base == 'number' && base > 0 ? base%37 : 36 - ); -} - -/** - * humanized time stamp - * - * @param sep: { String } - expect '-' - * @param time: { Object } - expect new Date() - * @returns: { String } - */ -uid['_date'] = _date; -function _date ( sep, date ) { return to(date.getFullYear(),4)+sep+to(date.getMonth(),2)+sep+to(date.getDate(),2); }; -uid['_time'] = _time; -function _time ( sep, date ) { return to(date.getHours(),2)+sep+to(date.getMinutes(),2); } -/** - * slowest humanized time stamp with checks - * - * @param sep1: { String } - [option] expect '-' - * @param sep2: { String } - [option] expect ':' - * @param time: { Object } - [option] expect new Date() - * @returns: { String } - */ -uid['time'] = function ( sep1, sep2, time ) { - time = time instanceof Date ? time : new Date; - sep1 = typeof sep1 == 'string'? sep1 : '-'; - sep2 = typeof sep2 == 'string'? sep2 : ':'; - return _date(sep1, time)+sep1+_time(sep2, time); -} -/** - * generate uuid - * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx - * - * @param M: { String } - [option] - * @param N: { String } - [option] - * @param time: { Object } - [option] expect new Date() - * @returns: { Object } - */ -uid['guid'] = guid; -function guid ( M, N, time ) { - time = time instanceof Date ? time : new Date; - M = typeof M == 'string' && M.length == 1 ? M : uid('S'); - N = typeof N == 'string' && N.length == 1 ? N : uid('N'); - return ts.call(time.valueOf(), 36)+'-'+ - ts.call((''+time.getFullYear()+time.getMonth())*1, 36)+'-'+ - M+ts.call((''+time.getDay()+time.getHours()+time.getMinutes())*1, 36)+'-'+ - N+ts.call((''+time.getSeconds()+time.getMilliseconds())*1, 36)+'-'+ - uid('XXXXXXXXXXXX'); -} -/** - * EXPORTS - * - * @public - */ -if ( typeof process != 'undefined' && Object.prototype.toString.call(process) == '[object process]' ) { - module.exports = uid; -} -if ( typeof window != 'undefined' && Object.prototype.toString.call(window) == '[object Window]' ) { - window['uid'] = uid; -} - -})() \ No newline at end of file