Initial commit
37
.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/.idea/
|
||||
/node_modules
|
||||
*.zip
|
||||
**/*.zip
|
||||
/_socket
|
||||
/.build
|
||||
#/lib/js
|
||||
#/lib/css
|
||||
#/www/_socket
|
||||
#/cordova/www
|
||||
#/cordova/platforms/android/assets/www
|
||||
#/cordova/platforms/android/.gradle
|
||||
#/cordova/platforms/android/build
|
||||
#/cordova/platforms/android/CordovaLib/build
|
||||
#/www/edit.full.html
|
||||
#/www/index.full.html
|
||||
#/www/worker-css.js
|
||||
#/www/worker-html.js
|
||||
#/www/worker-javascript.js
|
||||
#/www/css/vis.min.css
|
||||
#/www/css/visEdit.min.css
|
||||
#/www/js/vis.min.js
|
||||
#/www/js/vis.mmin.js
|
||||
#/www/js/visEdit.min.js
|
||||
#/www/js/visEdit.mmin.js
|
||||
#/www/css/channel.png
|
||||
#/www/css/device.png
|
||||
#/www/css/icons.gif
|
||||
#/www/css/loading.gif
|
||||
#/www/css/state.png
|
||||
#/iob_npm.done
|
||||
#/package-lock.json
|
||||
admin/i18n/*/flat.txt
|
||||
admin/i18n/flat.txt
|
||||
.DS_Store
|
||||
|
||||
|
15
.npmignore
Normal file
@ -0,0 +1,15 @@
|
||||
Gruntfile.js
|
||||
gulpfile.js
|
||||
tasks
|
||||
ablage.html
|
||||
node_modules
|
||||
cordova
|
||||
.idea
|
||||
.git
|
||||
test
|
||||
*.zip
|
||||
.travis.yml
|
||||
appveyor.yml
|
||||
iob_npm.done
|
||||
package-lock.json
|
||||
admin/i18n
|
24
.travis.yml
Normal file
@ -0,0 +1,24 @@
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
language: node_js
|
||||
node_js:
|
||||
- '4'
|
||||
- '6'
|
||||
- '8'
|
||||
- '10'
|
||||
before_script:
|
||||
- export NPMVERSION=$(echo "$($(which npm) -v)"|cut -c1)
|
||||
- 'if [[ $NPMVERSION == 5 ]]; then npm install -g npm@5; fi'
|
||||
- npm -v
|
||||
- npm install winston@2.3.0 --production
|
||||
- 'npm install https://github.com/ioBroker/ioBroker.js-controller/tarball/master --production'
|
||||
- npm install iobroker.web --prefix ./node_modules/iobroker.js-controller/ --production
|
||||
env:
|
||||
- CXX=g++-4.8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
568
Gruntfile.js
Normal file
@ -0,0 +1,568 @@
|
||||
// To use this file in WebStorm, right click on the file name in the Project Panel (normally left) and select "Open Grunt Console"
|
||||
|
||||
/** @namespace __dirname */
|
||||
/* jshint -W097 */
|
||||
/* jshint strict:false */
|
||||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
function getAppName() {
|
||||
var parts = __dirname.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 1].split('.')[0].toLowerCase();
|
||||
}
|
||||
|
||||
module.exports = function (grunt) {
|
||||
|
||||
var srcDir = __dirname + '/';
|
||||
var pkg = grunt.file.readJSON('package.json');
|
||||
var iopackage = grunt.file.readJSON('io-package.json');
|
||||
var version = (pkg && pkg.version) ? pkg.version : iopackage.common.version;
|
||||
var appName = getAppName();
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
replace: {
|
||||
core: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /var version = *'[.0-9]*';/g,
|
||||
replacement: "var version = '" + version + "';"
|
||||
},
|
||||
{
|
||||
match: /"version": *"[.0-9]*",/g,
|
||||
replacement: '"version": "' + version + '",'
|
||||
},
|
||||
{
|
||||
match: /version: *"[.0-9]*",/,
|
||||
replacement: 'version: "' + version + '",'
|
||||
},
|
||||
{
|
||||
match: /version: *'[.0-9]*',/,
|
||||
replacement: "version: '" + version + "',"
|
||||
}, {
|
||||
match: /<!-- vis Version [.0-9]+ -->/,
|
||||
replacement: '<!-- vis Version ' + version + ' -->'
|
||||
},
|
||||
{
|
||||
match: /# vis Version [.0-9]+/,
|
||||
replacement: '# vis Version ' + version
|
||||
},
|
||||
{
|
||||
match: /# dev build [.0-9]+/g,
|
||||
replacement: '# dev build 0'
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'package.json',
|
||||
srcDir + 'io-package.json'
|
||||
],
|
||||
dest: srcDir
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'www/cache.manifest',
|
||||
srcDir + 'www/edit.html',
|
||||
srcDir + 'www/index.html'
|
||||
],
|
||||
dest: srcDir + '/www'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'www/js/vis.js'
|
||||
],
|
||||
dest: srcDir + '/www/js'
|
||||
}
|
||||
]
|
||||
},
|
||||
name: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /iobroker/gi,
|
||||
replacement: appName
|
||||
},
|
||||
{
|
||||
match: / *\s*Copyright \(c\) \d+-\d+ bluefox https:\/\/github.com\/GermanBluefox, hobbyquaker https:\/\/github.com\/hobbyquaker/gi,
|
||||
replacement: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + '*.*',
|
||||
srcDir + '.travis.yml',
|
||||
'!' + srcDir + 'Gruntfile.js'
|
||||
],
|
||||
dest: srcDir
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'admin/*.*',
|
||||
'!' + srcDir + 'admin/*.png'
|
||||
],
|
||||
dest: srcDir + 'admin'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'lib/*.*'
|
||||
],
|
||||
dest: srcDir + 'lib'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'example/*.*'
|
||||
],
|
||||
dest: srcDir + 'example'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'www/*.*'
|
||||
],
|
||||
dest: srcDir + 'www'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'www/js/*.*'
|
||||
],
|
||||
dest: srcDir + 'www/js'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'www/widgets/*.*'
|
||||
],
|
||||
dest: srcDir + 'www/widgets'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'test/*.*'
|
||||
],
|
||||
dest: srcDir + 'test'
|
||||
},
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + 'test/lib/*.*'
|
||||
],
|
||||
dest: srcDir + 'test/lib'
|
||||
}
|
||||
]
|
||||
},
|
||||
minify: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /<script type="text\/javascript" src="cordova\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/translate\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/app\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/can\.custom\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/jquery.ui.touch-punch.min.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/jquery\.multiselect-1\.13\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/quo\.standalone\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/loStorage\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/conn\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/vis\.js"><\/script>/,
|
||||
replacement: '<script type="text/javascript" src="js/vis.min.js"></script>'
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/backgrounds.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/vis.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/app.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/styles.css" \/>/,
|
||||
replacement: '<link rel="stylesheet" type="text/css" href="css/vis.min.css" />'
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="lib\/css\/jquery.multiselect-1\.13\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/fm\/fileManager\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visLang\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visAbout\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visEditWelcome\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visEdit\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visEditExt\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/visEditInspect\.js"><\/script>/,
|
||||
replacement: '<script type="text/javascript" src="js/visEdit.min.js"></script>'
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/jquery\.fancytree-all\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/colResizable-1\.5\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/dropzone\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/html2canvas\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/jquery\.jgrowl\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/superclick\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/ace\/ace\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/ace\/ext-language_tools\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<script type="text\/javascript" src="lib\/js\/farbtastic\.js"><\/script>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="lib\/css\/fancytree\/ui.fancytree\.min\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="lib\/css\/superfish\/superfish\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="lib\/css\/jquery\.jgrowl\.min\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="lib\/css\/farbtastic\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/vis\.min\.css" \/>/,
|
||||
replacement: '<link rel="stylesheet" type="text\/css" href="css\/visEdit\.min\.css" \/>'
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="css\/vis-editor\.css" \/>/,
|
||||
replacement: ''
|
||||
},
|
||||
{
|
||||
match: /<link rel="stylesheet" type="text\/css" href="js\/fm\/fileManager\.css" \/>/,
|
||||
replacement: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + '/www/index.html',
|
||||
srcDir + '/www/edit.html'
|
||||
],
|
||||
dest: srcDir + '/www/'
|
||||
}
|
||||
]
|
||||
},
|
||||
minifyEdit: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /<script type="text\/javascript" src="js\/vis\.min\.js"><\/script>/,
|
||||
replacement: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
expand: true,
|
||||
flatten: true,
|
||||
src: [
|
||||
srcDir + '/www/edit.html'
|
||||
],
|
||||
dest: srcDir + '/www/'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
// Javascript code styler
|
||||
jscs: require(__dirname + '/tasks/jscs.js'),
|
||||
// Lint
|
||||
jshint: require(__dirname + '/tasks/jshint.js'),
|
||||
http: {
|
||||
get_utilsfile: {
|
||||
options: {
|
||||
url: 'https://raw.githubusercontent.com/' + appName + '/' + appName + '.build/master/adapters/utils.js'
|
||||
},
|
||||
dest: 'lib/utils.js'
|
||||
},
|
||||
get_jscsRules: {
|
||||
options: {
|
||||
url: 'https://raw.githubusercontent.com/' + appName + '/' + appName + '.js-controller/master/tasks/jscsRules.js'
|
||||
},
|
||||
dest: 'tasks/jscsRules.js'
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
options: {
|
||||
separator: ';\n'
|
||||
},
|
||||
index: {
|
||||
src: [
|
||||
'www/lib/js/can.custom.min.js',
|
||||
'www/lib/js/jquery.ui.touch-punch.min.js',
|
||||
'www/lib/js/jquery.multiselect-1.13.min.js',
|
||||
'www/lib/js/quo.standalone.js',
|
||||
'www/lib/js/loStorage.js',
|
||||
'www/js/vis.mmin.js'
|
||||
],
|
||||
dest: 'www/js/vis.min.js'
|
||||
},
|
||||
edit: {
|
||||
src: [
|
||||
'www/lib/js/jquery.fancytree-all.min.js',
|
||||
'www/lib/js/colResizable-1.5.min.js',
|
||||
'www/lib/js/dropzone.js',
|
||||
'www/lib/js/html2canvas.min.js',
|
||||
'www/lib/js/jquery.jgrowl.min.js',
|
||||
'www/lib/js/superclick.js',
|
||||
'www/lib/ace/ace.js',
|
||||
'www/lib/ace/ext-language_tools.js',
|
||||
'www/lib/ace/ext-searchbox.js',
|
||||
'www/lib/ace/mode-css.js',
|
||||
'www/lib/ace/mode-html.js',
|
||||
'www/lib/ace/mode-javascript.js',
|
||||
//'www/lib/ace/worker-css.js', - needs to be in root
|
||||
//'www/lib/ace/worker-html.js',
|
||||
//'www/lib/ace/worker-javascript.js',
|
||||
'www/lib/js/farbtastic.js',
|
||||
'www/js/vis.min.js',
|
||||
'www/js/visEdit.mmin.js'
|
||||
],
|
||||
dest: 'www/js/visEdit.min.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
index: {
|
||||
files: {
|
||||
'www/js/vis.mmin.js': [
|
||||
'www/lib/js/translate.js',
|
||||
'www/js/conn.js',
|
||||
'www/js/vis.js'
|
||||
]
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
files: {
|
||||
'www/js/visEdit.mmin.js': [
|
||||
'www/js/fm/fileManager.js',
|
||||
'www/js/visLang.js',
|
||||
'www/js/visEditWelcome.js',
|
||||
'www/js/visEdit.js',
|
||||
'www/js/visEditExt.js',
|
||||
'www/js/visEditInspect.js'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
options: {
|
||||
mergeIntoShorthands: false,
|
||||
roundingPrecision: -1
|
||||
},
|
||||
index: {
|
||||
files: {
|
||||
'www/css/vis.min.css': [
|
||||
'www/lib/css/jquery.multiselect-1.13.css',
|
||||
'www/css/background.css',
|
||||
'www/css/styles.css',
|
||||
'www/css/vis.css'
|
||||
]
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
files: {
|
||||
'www/css/visEdit.min.css': [
|
||||
'www/lib/css/fancytree/ui.fancytree.min.css',
|
||||
'www/lib/css/superfish/superfish.css',
|
||||
'www/lib/css/jquery.jgrowl.min.css',
|
||||
'www/lib/css/farbtastic.css',
|
||||
'www/js/fm/fileManager.css',
|
||||
'www/css/vis.min.css',
|
||||
'www/css/vis-editor.css'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('updateReadme', function () {
|
||||
var readme = grunt.file.read('README.md');
|
||||
var pos = readme.indexOf('## Changelog');
|
||||
if (pos !== -1) {
|
||||
var readmeStart = readme.substring(0, pos + '## Changelog\r'.length);
|
||||
var readmeEnd = readme.substring(pos + '## Changelog\r'.length);
|
||||
|
||||
if (readme.indexOf(version) === -1) {
|
||||
var timestamp = new Date();
|
||||
var date = timestamp.getFullYear() + '-' +
|
||||
('0' + (timestamp.getMonth() + 1).toString(10)).slice(-2) + '-' +
|
||||
('0' + (timestamp.getDate()).toString(10)).slice(-2);
|
||||
|
||||
var news = '';
|
||||
if (iopackage.common.whatsNew) {
|
||||
for (var i = 0; i < iopackage.common.whatsNew.length; i++) {
|
||||
if (typeof iopackage.common.whatsNew[i] === 'string') {
|
||||
news += '* ' + iopackage.common.whatsNew[i] + '\r\n';
|
||||
} else {
|
||||
news += '* ' + iopackage.common.whatsNew[i].en + '\r\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grunt.file.write('README.md', readmeStart + '### ' + version + ' (' + date + ')\r\n' + (news ? news + '\r\n\r\n' : '\r\n') + readmeEnd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
grunt.loadNpmTasks('grunt-replace');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-jscs');
|
||||
grunt.loadNpmTasks('grunt-http');
|
||||
grunt.loadNpmTasks('grunt-npm-install');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-htmlmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
|
||||
grunt.registerTask('copyAce', function () {
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync('www/worker-css.js', fs.readFileSync('www/lib/ace/worker-css.js'));
|
||||
fs.writeFileSync('www/worker-html.js', fs.readFileSync('www/lib/ace/worker-html.js'));
|
||||
fs.writeFileSync('www/worker-javascript.js', fs.readFileSync('www/lib/ace/worker-javascript.js'));
|
||||
|
||||
fs.writeFileSync('www/css/channel.png', fs.readFileSync('www/lib/css/fancytree/channel.png'));
|
||||
fs.writeFileSync('www/css/device.png', fs.readFileSync('www/lib/css/fancytree/device.png'));
|
||||
fs.writeFileSync('www/css/icons.gif', fs.readFileSync('www/lib/css/fancytree/icons.gif'));
|
||||
fs.writeFileSync('www/css/loading.gif', fs.readFileSync('www/lib/css/fancytree/loading.gif'));
|
||||
fs.writeFileSync('www/css/state.png', fs.readFileSync('www/lib/css/fancytree/state.png'));
|
||||
});
|
||||
|
||||
var fs = require('fs');
|
||||
if (!fs.existsSync('www/index.full.html')) fs.writeFileSync('www/index.full.html', fs.readFileSync('www/index.html'));
|
||||
if (!fs.existsSync('www/edit.full.html')) fs.writeFileSync('www/edit.full.html', fs.readFileSync('www/edit.html'));
|
||||
grunt.registerTask('copySrc', function () {
|
||||
});
|
||||
|
||||
grunt.registerTask('minify', [
|
||||
'copySrc',
|
||||
'uglify:index',
|
||||
'uglify:edit',
|
||||
'cssmin:index',
|
||||
'cssmin:edit',
|
||||
'concat:index',
|
||||
'concat:edit',
|
||||
'replace:minify',
|
||||
'replace:minifyEdit',
|
||||
'copyAce'
|
||||
]);
|
||||
|
||||
grunt.registerTask('beta', [
|
||||
'beta-pre',
|
||||
'npm-install',
|
||||
'beta-post'
|
||||
]);
|
||||
grunt.registerTask('default', [
|
||||
'http',
|
||||
'replace:core',
|
||||
'updateReadme',
|
||||
'jshint',
|
||||
'jscs'
|
||||
]);
|
||||
|
||||
grunt.registerTask('prepublish', ['replace:core', 'updateReadme']);
|
||||
grunt.registerTask('p', ['prepublish']);
|
||||
grunt.registerTask('rename', ['replace:name']);
|
||||
};
|
91
LICENSE
Normal file
@ -0,0 +1,91 @@
|
||||
Creative Commons Attribution-NonCommercial 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
|
||||
|
||||
Section 1 – Definitions.
|
||||
|
||||
Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
|
||||
Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
|
||||
Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
||||
Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
|
||||
Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
|
||||
Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
|
||||
Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
|
||||
Licensor means the individual(s) or entity(ies) granting rights under this Public License.
|
||||
NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
|
||||
Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
|
||||
Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
|
||||
You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
|
||||
Section 2 – Scope.
|
||||
|
||||
License grant.
|
||||
Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
|
||||
reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
|
||||
produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
|
||||
Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
|
||||
Term. The term of this Public License is specified in Section 6(a).
|
||||
Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
|
||||
Downstream recipients.
|
||||
Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
|
||||
No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
|
||||
No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
|
||||
Other rights.
|
||||
|
||||
Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
|
||||
Patent and trademark rights are not licensed under this Public License.
|
||||
To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
|
||||
Section 3 – License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
|
||||
|
||||
Attribution.
|
||||
|
||||
If You Share the Licensed Material (including in modified form), You must:
|
||||
|
||||
retain the following if it is supplied by the Licensor with the Licensed Material:
|
||||
identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
|
||||
a copyright notice;
|
||||
a notice that refers to this Public License;
|
||||
a notice that refers to the disclaimer of warranties;
|
||||
a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
||||
indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
|
||||
indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
|
||||
You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
|
||||
If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||
If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
|
||||
Section 4 – Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
|
||||
|
||||
for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
|
||||
if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
|
||||
You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
|
||||
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
|
||||
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
|
||||
To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
|
||||
The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
|
||||
Section 6 – Term and Termination.
|
||||
|
||||
This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
|
||||
Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
|
||||
|
||||
automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
|
||||
upon express reinstatement by the Licensor.
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
|
||||
For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
|
||||
Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||
Section 7 – Other Terms and Conditions.
|
||||
|
||||
The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
|
||||
Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
|
||||
Section 8 – Interpretation.
|
||||
|
||||
For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
|
||||
To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
|
||||
No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
|
||||
Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
|
||||
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
452
OLD_CHANGELOG.md
Normal file
@ -0,0 +1,452 @@
|
||||
## Changelog
|
||||
|
||||
### 0.9.4 (2016-04-05)
|
||||
* (bluefox) implement more "close" types
|
||||
* (bluefox) set height of about window
|
||||
* (bluefox) rename the upper case datei extensions into lower case by upload
|
||||
* (bluefox) reload vis if lost connection for longer than 1 minute
|
||||
|
||||
### 0.9.3 (2016-03-23)
|
||||
* (bluefox) allow onChange for OIDs too
|
||||
* (bluefox) add quality
|
||||
* (bluefox) changes for app
|
||||
* (bluefox) add new flag "render always" in this case this view will be rendered in any way.
|
||||
* (bluefox) add about dialog
|
||||
* (bluefox) remove bind(this) to enable it run on iPad1
|
||||
|
||||
### 0.9.2 (2016-02-29)
|
||||
* (bluefox) allow onChange for OIDs too
|
||||
* (bluefox) show reconnecting process
|
||||
* (pmant) use new gestures lib
|
||||
* (bluefox) show project name
|
||||
|
||||
### 0.9.1 (2016-02-24)
|
||||
* (bluefox) fix safary error
|
||||
|
||||
### 0.9.0 (2016-02-20)
|
||||
* (pmant) add guestures
|
||||
* (bluefox) fix svg bool on touch devices
|
||||
|
||||
### 0.8.6 (2016-01-27)
|
||||
* (bluefox) fix load of project CSS
|
||||
|
||||
### 0.8.4 (2016-01-26)
|
||||
* fix load of user and project CSS
|
||||
|
||||
### 0.8.3 (2016-01-21)
|
||||
* (bluefox) non vis adapters may have widgets too
|
||||
|
||||
### 0.8.2 (2015-12-22)
|
||||
* (bluefox) make yahoo widget work again
|
||||
* (bluefox) add Welcome Page
|
||||
|
||||
### 0.8.1 (2015-12-14)
|
||||
* (bluefox) remove most of themes
|
||||
* (bluefox) add cordova
|
||||
|
||||
### 0.7.9 (2015-12-07)
|
||||
* (bluefox) fix "bar-basic"
|
||||
|
||||
### 0.7.8 (2015-12-06)
|
||||
* (bluefox) support flag "always" (to always load the widget set)
|
||||
* (bluefox) fix error in jqui Container view
|
||||
* (bluefox) make basic xxx8 to possible have any count of entries
|
||||
* (bluefox) scroll on basic-iframe
|
||||
* (bluefox) fix basic - table details
|
||||
* (bluefox) add refreshOnViewChange for iFrame
|
||||
* (bluefox) remove "basic - val,bulb" and replace it with "basic - ctrl,bulb" + readOnly flag
|
||||
* (bluefox) add update on view change for "basic - iFrame"
|
||||
* (bluefox) remove "bar - Vertical" and replace it with "bar" + "orientation = vertical"
|
||||
* (bluefox) change calculation for bars. Use min/max instead of factor
|
||||
|
||||
### 0.7.7 (2015-11-07)
|
||||
* (bluefox) move jQueryUI css files
|
||||
|
||||
### 0.7.6 (2015-11-05)
|
||||
* (bluefox) fix version
|
||||
|
||||
### 0.7.5 (2015-11-02)
|
||||
* (bluefox) fix Widget "basic - ctrl Bool Html "
|
||||
* (bluefox) make red-number working again.
|
||||
* (bluefox) extend dialog with atuoclose timeout
|
||||
* (bluefox) add editWidgetNames
|
||||
* (bluefox) remove jqueryUI files to iobroker.web
|
||||
|
||||
### 0.7.4 (2015-10-27)
|
||||
* (SmilingJack) add "jqui-navigation" with password
|
||||
* (bluefox) fix jqui-selectValue: write number instead of string
|
||||
* (bluefox) make all jqui buttons resizable.
|
||||
* (bluefox) add "image height %" to jqui with icons
|
||||
* (bluefox) add some features to basic and jqui widgets
|
||||
* (bluefox) add to jqui option: no jQuiery style.
|
||||
* (bluefox) make possible to use new line in jqui-buttons
|
||||
* (bluefox) extend basic-screen resolution with instance information
|
||||
* (SmilingJack) Remove vkb (for own adapter)
|
||||
|
||||
### 0.7.3 (2015-10-18)
|
||||
* (SmilingJack) expand slider to range slider
|
||||
* (bluefox) fix Basci-htmlBool, basic-svgbool, basic-val bulb
|
||||
* (bluafox) add basic-input widget
|
||||
|
||||
### 0.7.2 (2015-10-13)
|
||||
* (bluefox) fix error with view change and click on widget
|
||||
|
||||
### 0.7.1 (2015-10-10)
|
||||
* (bluefox) parse value by ctrl widgets
|
||||
* (bluefox) update select ID
|
||||
* (bluefox) add to file upload "file select dialog"
|
||||
* (bluefox) add browse objects dialog
|
||||
* (bluefox) fix update container by bindings
|
||||
* (bluefox) warnings clear
|
||||
|
||||
### 0.7.0 (2015-10-05)
|
||||
* (bluefox) add door_tilt pictures
|
||||
* (bluefox) update RGraph library
|
||||
* (bluefox) fix RGraph/ bar chart "Label color" bug
|
||||
* (bluefox) fix jquery valve dialog
|
||||
* (bluefox) support of binding like "{;Math.random()}
|
||||
* (bluefox) remove jqui-mfd to own package
|
||||
* (bluefox) remove RGraph and fancyswitch sets
|
||||
* (bluefox) increase wait period by view changes to fix click on the next view
|
||||
* (bluefox) fix view selector for some jqui dialogs
|
||||
* (bluefox) remove time and weather
|
||||
* (bluefox) check some possible error
|
||||
|
||||
### 0.6.19 (2015-09-27)
|
||||
* (bluefox) translate segment clock
|
||||
* (bluefox) fix slider "dark On/Off" and autoOFF
|
||||
* (bluefox) support mouseup and mouse down by debouncing
|
||||
* (bluefox) make url as URL and not as sound selector
|
||||
* (bluefox) add special variables "view", wname and "wid" to use it in bindings
|
||||
* (bluefox) update ace editor
|
||||
* (bluefox) highligh vis in admin
|
||||
* (bluefox) add to dialogs: position, hide header, scroll settings
|
||||
* (bluefox) make dialogs work
|
||||
* (bluefox) add jqui dialog close button
|
||||
* (bluefox) set maximal height for all select menus
|
||||
* (bluefox) add setId by opening of dialog
|
||||
|
||||
### 0.6.18 (2015-09-24)
|
||||
(bluefox) add segment clock widget
|
||||
(bluefox) clear filter button in File Manager
|
||||
(bluefox) add to fancy switch "autoOff" property
|
||||
(bluefox) add svg shapes
|
||||
(bluefox) fix problem with view selection for widget
|
||||
(bluefox) add new widget "Svg clock"
|
||||
|
||||
### 0.6.17 (2015-09-20)
|
||||
* (bluefox) add fancyswitch-6.png
|
||||
* (bluefox) add icons for some jqui widgets
|
||||
* (bluefox) fix some errors in qui and jqui-mfd
|
||||
* (bluefox) add to Bulb on/off image selector
|
||||
* (bluefox) fix "ctrl - Icon State / val - Icon Bool"
|
||||
* (bluefox) fix fileManager.js
|
||||
|
||||
### 0.6.16 (2015-09-17)
|
||||
* (bluefox) add to fancyswitch custom values and light style to german switch
|
||||
* (bluefox) try to accept for visibility true and false
|
||||
|
||||
### 0.6.15 (2015-09-15)
|
||||
* (bluefox) add Custom10 to jqui-mfd
|
||||
* (bluefox) ignore "touch" event exactly after the view change
|
||||
|
||||
### 0.6.14 (2015-09-13)
|
||||
* (bluefox) allow change the color of jqui-mfd
|
||||
|
||||
### 0.6.13 (2015-08-23)
|
||||
* (bluefox) update select ID dialog, support of role filter in selectId dialog
|
||||
* (bluefox) fix Gruntfile.js
|
||||
* (bluefox) call convertOldHqWidgets by import
|
||||
* (bluefox) remove prepublish script
|
||||
* (bluefox) allow for visibility false/0, true/1
|
||||
* (bluefox) support of import of old hqWidgets
|
||||
|
||||
### 0.6.12 (2015-08-14)
|
||||
* (bluefox) update development packets
|
||||
* (bluefox) improve table widget (do not try to show functions)
|
||||
* (bluefox) support of custom set OIDs for metro/toggle, basic/BulbOnOff, jqui-mfd/socketCtrl
|
||||
|
||||
### 0.6.11 (2015-08-12)
|
||||
* (bluefox) improve click bounce detection
|
||||
* (bluefox) add filter to fileManager
|
||||
* (bluefox) add file manager to "setup" menu
|
||||
* (bluefox) fix SVG
|
||||
* (bluefox) remove: Hide on >0/True, Show on Value, Hide on 0/False, Turning handle, Door/Window sensor
|
||||
* (bluefox) add all previews in basic
|
||||
|
||||
### 0.6.10 (2015-08-11)
|
||||
- (bluefox) protect against double event: click and touchstart
|
||||
- (bluefox) implement urlTrue/urlFalse and oidTrue/oirFalse by jqui-mfd/socket
|
||||
- (bluefox) remove bars and plumbs
|
||||
- (bluefox) remove jshint warnings
|
||||
|
||||
### 0.6.9 (2015-08-11)
|
||||
- (bluefox) protect against double event: click and touchstart
|
||||
|
||||
### 0.6.8 (2015-08-08)
|
||||
* (bluefox) all jqui-mfd widgets
|
||||
do not background if active and no background desired
|
||||
new widget jqui-mfd valve
|
||||
change jqui-mfd window (close 0, opened 1, closed 2)
|
||||
* (bluefox) hide "Name: .." text that sometimes is shown
|
||||
* (bluefox) use "click touchstart" instead of "click" to enable mobile devices
|
||||
* (bluefox) fix export/import titles
|
||||
* (bluefox) add preview to stateful image
|
||||
|
||||
### 0.6.7 (2015-08-06)
|
||||
* (bluefox) fix scroll of view tabs
|
||||
* (bluefox) add comment about group/byindex
|
||||
* (bluefox) add update interval to small icon jqui-mfd
|
||||
* (bluefox) filter key as autocomplete
|
||||
* (bluefox) fix paths for plumps
|
||||
* (bluefox) enable install for node-red-vis
|
||||
|
||||
### 0.6.5 (2015-07-25)
|
||||
* (bluefox) fix hqWidgets dimmer
|
||||
* (bluefox) optimize upload
|
||||
* (bluefox) catch error after import
|
||||
* (bluefix) add changeView event (required for lcars)
|
||||
* (bluefox) fix update of cache.manifest
|
||||
|
||||
### 0.6.4 (2015-07-19)
|
||||
* (bluefox) add permissions
|
||||
* (bluefox) upload config.js to fix error with vis-metro
|
||||
* (bluefox) remove hqWidgets and colorpicker
|
||||
* (bluefox) add jqui-mfd translations
|
||||
* (bluefox) add "new project" menu
|
||||
|
||||
### 0.6.2 (2015-07-01)
|
||||
- (bluefox) fix metro widgets
|
||||
|
||||
### 0.6.1 (2015-06-28)
|
||||
- (bluefox) fix jqui-mfd
|
||||
- (bluefox) add prev for "jqui-mfd" dimmer dialog
|
||||
- (bluefox) fix bars in firefox
|
||||
- (bluefox) add permissions check
|
||||
- (bluefox) fix problem with hqWidgets and image selector
|
||||
* (bluefox) implement list of projects
|
||||
* (bluefox) case insensitive sorting of views
|
||||
* (bluefox) set automatically temperature ID of metro Heating
|
||||
* (bluefox) add max_rows for basic-table
|
||||
* (bluefox) show label on jqui-toggle
|
||||
* (bluefox) fix cameras jqui-mfd
|
||||
* (bluefox) jqui-mfd - remove most of all mfd icons
|
||||
|
||||
### 0.5.9 (2015-06-10)
|
||||
- (bluefox) fix jqui-mfd
|
||||
- (bluefox) change adapter type from "visualisation" to "vis"
|
||||
- (bluefox) enable zoom on chrome
|
||||
- (bluefox) fix close button
|
||||
|
||||
### 0.5.8 (2015-06-01)
|
||||
- (bluefox) add forgotten noise.png for hqWidgets buttons
|
||||
- (bluefox) jqui dialog fixed
|
||||
- (bluefox) fixed edit number in FireFox
|
||||
- (bluefox) create logout button
|
||||
- (bluefox) fix "basic - table"
|
||||
- (bluefox) fix jqui-mfd
|
||||
- (bluefox) fix bars on multiple views
|
||||
|
||||
### 0.5.5 (2015-05-26)
|
||||
- (bluefox) activate try/catch again
|
||||
|
||||
### 0.5.4 (2015-05-26)
|
||||
- (bluefox) add some button styles
|
||||
- (bluefox) fix conn.js
|
||||
|
||||
### 0.5.3 (2015-05-25)
|
||||
- (bluefox) fix "delete counter"
|
||||
- (bluefox) fix table "scroll" flag
|
||||
- (bluefox) do not require minmax for jqui increment
|
||||
- (bluefox) fix jqui-mfd
|
||||
- (bluefox) add textarea to HTML edit
|
||||
- (bluefox) change bar buttons
|
||||
|
||||
### 0.5.2 (2015-05-21)
|
||||
- (bluefox) add "change background" in image dialog
|
||||
- (bluefox) new widget - basic-table
|
||||
- (bluefox) update objects in selectID dialog
|
||||
- (bluefox) fix CSS editor
|
||||
|
||||
### 0.5.1 (2015-05-19)
|
||||
- (bluefox) fix german attribute name for RGraph.html
|
||||
- (bluefox) store css after edit, enable edition of jquery ui CSS in editor
|
||||
- (bluefox) fix error if all views have the same jquery style
|
||||
- (bluefox) fix delete more than one widget
|
||||
- (bluefox) try to fix fileManager
|
||||
- (bluefox) fix hqWidgets/Circle if greater than 200px
|
||||
|
||||
### 0.5.0 (2015-05-16)
|
||||
- (bluefox) context menu
|
||||
- (bluefox) lock widgets
|
||||
- (bluefox) fix metro
|
||||
- (bluefox) add preview in basics
|
||||
|
||||
### 0.4.1 (2015-05-13)
|
||||
- (bluefox) fix error with CanJS
|
||||
|
||||
### 0.4.0 (2015-05-12)
|
||||
- (smiling_Jack) Bugfix View select tabs
|
||||
- (smiling_Jack) Add a optional attr "data-vis-beta" in tpl set. To show a "!!! Beta !!!" label at the Widgetpreview
|
||||
- (smiling_Jack) *Add plump set*
|
||||
- (smiling_Jack) change widget-helper size
|
||||
- (bluefox) fix error in hqWidgets
|
||||
- (bluefox) *default view settings*
|
||||
- (bluefox) new metro Widget iFrame /Dialog
|
||||
- (bluefox) all metro widgets are revised
|
||||
- (bluefox) add dev6 as string
|
||||
- (bluefox) add widget filter
|
||||
- (bluefox) change style selector
|
||||
- (bluefox) update canJS to 2.2.4
|
||||
- (bluefox) send vis.command from browsers with no instanceID
|
||||
- (bluefox) performance improvement in edit mode (no map of states)
|
||||
|
||||
### 0.3.2 (2015-05-09)
|
||||
- (bluefox) fix errors in binding
|
||||
- (bluefox) start implement hqWidgets
|
||||
|
||||
### 0.3.1 (2015-05-01)
|
||||
- (bluefox) support of binding with formula "{object;*(2);/(3)}"
|
||||
|
||||
### 0.3.0 (2015-05-01)
|
||||
- (bluefox) enable binding of any attribute of widget to object
|
||||
- (bluefox) implement export/import of array of widgets (and not only whole views)
|
||||
- (bluefox) update jquery-ui
|
||||
- (bluefox) optimize styles of views
|
||||
|
||||
### 0.2.15 (2015-04-26)
|
||||
- (bluefox) fix error with bars
|
||||
|
||||
### 0.2.14 (2015-04-26)
|
||||
- (bluefox) Add BARS
|
||||
- (bluefox) Add "accordion" to properties of widget
|
||||
- (bluefox) Better import
|
||||
- (bluefox) Fix error with lock-widget zindex and the Color Select Dialog and the Image Select Dialog
|
||||
- (bluefox) Switch Tab to widget, when widget is selected
|
||||
|
||||
### 0.2.13 (2015-04-20)
|
||||
- (smiling_Jack) Bugfix View Size
|
||||
- (smiling_Jack) Add "_project" view
|
||||
- (smiling_Jack) Add VBK Widget Set
|
||||
- (smiling_Jack) Working on Plumb Widget Set
|
||||
- (smiling_Jack) Working on Plumb Widget Set
|
||||
- (smiling_Jack) some small Bugfix
|
||||
- (smiling_Jack) remove animation on add Widget by Drag&Drop
|
||||
- (smiling_Jack) fm_manager safety function vor sandbox
|
||||
|
||||
### 0.2.12 (2015-04-14)
|
||||
- (bluefox) fix jqui radio
|
||||
- (bluefox) add to created objects "native"
|
||||
- (bluefox) fix metro heating
|
||||
- (bluefox) fix installation process
|
||||
|
||||
### 0.2.11 (2015-03-11)
|
||||
- (bluefox) fix install for iobroker. Required newest ioBroke.js-controller
|
||||
|
||||
### 0.2.10 (2015-03-09)
|
||||
- (bluefox) fix install for node-red-vis
|
||||
|
||||
### 0.2.8 (2015-03-08)
|
||||
- (bluefox) fix the version numbers
|
||||
|
||||
### 0.2.7 (2015-03-08)
|
||||
- (SmilingJack) add css editor
|
||||
- (SmilingJack) bugfix zoom
|
||||
- (SmilingJack) Bugfix select view menu
|
||||
- (bluefox) read last change of the state by start
|
||||
- (bluefox) fix formatDate and short year
|
||||
|
||||
### 0.2.6 (2015-03-03)
|
||||
- (bluefox) change shutter in metro
|
||||
- (bluefox) fix jqui- Select List
|
||||
|
||||
### 0.2.5 (2015-03-03)
|
||||
- (bluefox) fix lock interaction with widgets
|
||||
- (bluefox) add visibility dependency for every widget
|
||||
- (bluefox) change shutter in metro
|
||||
- (SmilingJack) Bugfix View theme select
|
||||
- (SmilingJack) Bugfix widget Align
|
||||
- (bluefox) use showWidgetHelper instead of direct editing of "widget_helper"
|
||||
- (bluefox) add px for width and radius of border
|
||||
- (bluefox) decrease size of widget_helper (selection frame)
|
||||
- (bluefox) fix "time stamp" and "last change" widgets
|
||||
|
||||
|
||||
### 0.2.4 (2015-02-22)
|
||||
- (bluefox) create some previews
|
||||
- (bluefox) fix error with color editor.css
|
||||
- (bluefox) new lcars widget - End
|
||||
- (bluefox) show images in selectID dialog
|
||||
- (bluefox) fix jqui buttons
|
||||
|
||||
|
||||
### 0.2.3 (2015-02-21)
|
||||
- (bluefox) add tooltips to buttons
|
||||
- (bluefox) fix view container widgets
|
||||
- (SmilingJack) fix error with align of widgets
|
||||
- (bluefox) lcars/metro/jqui/basic
|
||||
- (bluefox) fix move with arrows
|
||||
- (bluefox) lcars.html
|
||||
- (bluefox) update RGraph
|
||||
- (bluefox) update license text
|
||||
- (bluefox) add RGraph
|
||||
- (bluefox) show images in selectID dialog
|
||||
|
||||
### 0.2.2 (2015-02-17)
|
||||
- (smiling_Jack) align icons
|
||||
- (bluefox) support of sayIt and control
|
||||
- (smiling_Jack) show color in edit
|
||||
- (smiling_Jack) show settings in full screen mode
|
||||
|
||||
|
||||
### 0.2.1 (2015-02-14)
|
||||
- (smiling_Jack) widget lock & no Drag
|
||||
- (bluefox) fix yahoo weather widget and resizeable
|
||||
- (bluefox) fix undo
|
||||
- (smiling_Jack) Safari 6.0 prefix and OSX bug fixing
|
||||
- (bluefox) fix duplicate widgets
|
||||
- (bluefox) change ValueList HTML 8
|
||||
- (smiling_Jack) color attribute preview
|
||||
|
||||
### 0.2.0 (2015-02-12)
|
||||
- (smiling_Jack) widget preview icons
|
||||
- (bluefox) fixed many bugs
|
||||
- (bluefox) multiedit (many widgets can be edited together)
|
||||
|
||||
### 0.1.0 (2015-01-31)
|
||||
- (smiling_Jack) New Editor
|
||||
- (bluefox) new features (many and small)
|
||||
|
||||
### 0.0.8 (2015-01-24)
|
||||
- (smiling_Jack) New Editor
|
||||
|
||||
### 0.0.7 (2015-01-18)
|
||||
- (bluefox) image select dialog is connected
|
||||
|
||||
### 0.0.6 (2015-01-14)
|
||||
- (bluefox) add update interval to basic/static-HTML
|
||||
|
||||
### 0.0.5 (2015-01-13)
|
||||
- (bluefox) fancybuttons and metro
|
||||
|
||||
### 0.0.4 (2015-01-06)
|
||||
- (bluefox) support of file manager
|
||||
|
||||
### 0.0.3 (2015-01-03)
|
||||
- (bluefox) npm install
|
||||
|
||||
### 0.0.1 (2014-12-28)
|
||||
- (bluefox) initial checkin
|
||||
|
||||
## License
|
||||
Copyright (c) 2013-2015 bluefox https://github.com/GermanBluefox, hobbyquaker https://github.com/hobbyquaker
|
||||
Creative Common Attribution-NonCommercial (CC BY-NC)
|
||||
|
||||
http://creativecommons.org/licenses/by-nc/4.0/
|
||||
|
||||
![CC BY-NC License](https://github.com/GermanBluefox/DashUI/raw/master/images/cc-nc-by.png)
|
||||
|
||||
Short content:
|
||||
Licensees may copy, distribute, display and perform the work and make derivative works based on it only if they give the author or licensor the credits in the manner specified by these.
|
||||
Licensees may copy, distribute, display, and perform the work and make derivative works based on it only for noncommercial purposes.
|
||||
(Free for non-commercial use).
|
417
README.md
Normal file
@ -0,0 +1,417 @@
|
||||
![Logo](admin/vis.png)
|
||||
# iobroker.vis
|
||||
============
|
||||
|
||||
[![NPM version](http://img.shields.io/npm/v/iobroker.vis.svg)](https://www.npmjs.com/package/iobroker.vis)
|
||||
[![Downloads](https://img.shields.io/npm/dm/iobroker.vis.svg)](https://www.npmjs.com/package/iobroker.vis)
|
||||
|
||||
[![NPM](https://nodei.co/npm/iobroker.vis.png?downloads=true)](https://nodei.co/npm/iobroker.vis/)
|
||||
|
||||
WEB visualisation for iobroker platform.
|
||||
|
||||
## Installation & Documentation
|
||||
|
||||
![Demo interface](https://github.com/GermanBluefox/DashUI/raw/master/images/user0.png)
|
||||
![Demo interface](https://github.com/GermanBluefox/DashUI/raw/master/images/user7.png)
|
||||
|
||||
[Online Demos](https://iobroker.net:8080)
|
||||
|
||||
## Bindings of objects
|
||||
Normally most of widgets have ObjectID attribute. And this attribute can be bound with some value of object ID.
|
||||
But there is another option how to bind *any* attribute of widget to some ObjectID.
|
||||
|
||||
Just write into attribute ```{object.id}``` and it will be bound (not in edit mode) to this object's value.
|
||||
If you will use special format, you can even make some simple operations with it, e.g. multiplying or formatting.
|
||||
Patten has following format:
|
||||
|
||||
```
|
||||
{objectID;operation1;operation2;...}
|
||||
```
|
||||
|
||||
Following operations are supported:
|
||||
|
||||
- \* - multiplying. Argument must be in brackets, like "*(4)". In this sample we multiplying value with 4.
|
||||
- \+ - add. Argument must be in brackets, like "+(4.5)". In this sample we add to value 4.5.
|
||||
- \- - subtract. Argument must be in brackets, like "-(-674.5)". In this sample we subtract from value -674.5.
|
||||
- / - dividing. Argument must be in brackets, like "/(0.5)". In this sample we dividing value by 0.5.
|
||||
- % - modulo. Argument must be in brackets, like "%(5)". In this sample we take modulo of 5.
|
||||
- round - round the value.
|
||||
- round(N) - round the value with N places after point, e.g. 34.678;round(1) => 34.7
|
||||
- hex - convert value to hexadecimal value. All letters are lower cased.
|
||||
- hex2 - convert value to hexadecimal value. All letters are lower cased. If value less 16, so the leading zero will be added.
|
||||
- HEX - same as hex, but upper cased.
|
||||
- HEX2 - same as hex2, but upper cased.
|
||||
- date - format date according to given format. Format is the same as in [iobroker.javascript](https://github.com/iobroker/iobroker.javascript/blob/master/README.md#formatdate)
|
||||
- min(N) - if value is less than N, take the N, elsewise value
|
||||
- max(M) - if value is greater than M, take the M, elsewise value
|
||||
- sqrt - square root
|
||||
- pow(n) - power of N.
|
||||
- pow - power of 2.
|
||||
- floor - Math.floor
|
||||
- ceil - Math.ceil
|
||||
- random(R) - Math.random() * R, or just Math.random() if no argument
|
||||
- formatValue(decimals) - format value according to system settings and use decimals
|
||||
- date(format) - format value as date. Format is like: "YYYY-MM-DD hh:mm:ss.sss"
|
||||
- array(element1,element2[,element3,element4]) - returns the element of index. e.g.: {id.ack;array(ack is false,ack is true)}
|
||||
|
||||
You can use this pattern in any text, like
|
||||
|
||||
```
|
||||
My calculations with {objectID1;operation1;operation2;...} are {objectID2;operation3;operation4;...}
|
||||
```
|
||||
|
||||
or color calculations:
|
||||
|
||||
```
|
||||
#{objectRed;/(100);*(255);HEX2}{objectGreen;HEX2}{objectBlue;HEX2}
|
||||
```
|
||||
|
||||
To show timestamp of object write ".ts" or ".lc" (for last change) at the end of object id, e.g.:
|
||||
|
||||
```
|
||||
Last change: {objectRed.lc;date(hh:mm)}
|
||||
```
|
||||
|
||||
There is another possibility to write pattern:
|
||||
|
||||
```
|
||||
Hypotenuse of {height} and {width} = {h:height;w:width;Math.max(20, Math.sqrt(h*h + w*w))}
|
||||
```
|
||||
|
||||
```{h:height;w:width;h*w}``` will be interpreted as function:
|
||||
|
||||
```
|
||||
value = (function () {
|
||||
var h = "10";
|
||||
var w = "20";
|
||||
return Math.max(20, Math.sqrt(h*h + w*w));
|
||||
})();
|
||||
```
|
||||
|
||||
You can use *any* javascript functions. Arguments must be defined with ':', if not, it will be interpreted as formula.
|
||||
|
||||
Take care about types. All of them defined as strings. To be sure, that value will be treated as number use parseFloat function.
|
||||
|
||||
```
|
||||
Hypotenuse of {height} and {width} = {h:height;w:width;Math.max(20, Math.sqrt(Math.pow(parseFloat(h), 2) + Math.pow(parseFloat(w), 2)))}
|
||||
```
|
||||
|
||||
### Special bindings
|
||||
There are a number different internal bindings to provide additional information in views:
|
||||
* username - shows logged in user
|
||||
* view - name of actual view
|
||||
* wname - widget name
|
||||
* widget - is an object with all data of widget. Can be used only in JS part, like {a:a;widget.data.name}
|
||||
* wid - name of actual widget
|
||||
* language - can be "de", "en" or "ru".
|
||||
* instance - browser instance
|
||||
* login - if login required or not (e.g. to show/hide logout button)
|
||||
|
||||
Note: to use ":" in calculations (e.g. in string formula) use "::" instead.
|
||||
|
||||
**Remember**, that style definitions will be interpreted as bindings, so use ```{{style: value}}``` or just
|
||||
|
||||
```
|
||||
{
|
||||
style: value
|
||||
}
|
||||
```
|
||||
|
||||
for that.**
|
||||
|
||||
## Filters
|
||||
To visualise on the one view thw whole number of widgets you can use filters to reduce the amount of widgets simultaneously shown on the view.
|
||||
|
||||
Every widget has a field "filter". If you set it to some value, e.g. "light", so you can use other widget (bars - filters, filter - dropdown) to control which filter is actually active.
|
||||
|
||||
## Control interface
|
||||
Vis creates 3 variables:
|
||||
|
||||
- control.instance - Here the browser instance should be written or FFFFFFFF if every browser must be controlled.
|
||||
- control.data - Parameter for command. See specific command description.
|
||||
- control.command - Command name. Write this variable triggers the command. That means before command will be written the "instance" and "data" must be prepared with data.
|
||||
|
||||
Commands:
|
||||
|
||||
* alert - show alert window in vis. "control.data" has following format "message;title;jquery-icon". Title and jquery-icon are optional. Icon names can be found [here](http://jqueryui.com/themeroller/). To show icon "ui-icon-info" write ```Message;;info```.
|
||||
* changeView - switch to desired view. "control.data" must have name of view. You can specify project name too as "project/view". Default project is "main".
|
||||
* refresh - reload vis, for instance after project is changed to reload on all browsers.
|
||||
* reload - same as refresh.
|
||||
* dialog - Show dialog window. Dialog must exist on view. One of:
|
||||
|
||||
- "static - HTML - Dialog",
|
||||
- "static - Icon - Dialog",
|
||||
- "container - HTML - view in jqui Dialog",
|
||||
- "container - ext cmd - view in jqui Dialog",
|
||||
- "container - Icon - view in jqui Dialog",
|
||||
- "container - Button - view in jqui Dialog".
|
||||
|
||||
"control.data" must have id of dialog widget, e.g. "w00056".
|
||||
* dialogClose
|
||||
* popup - opens a new browser window. Link must be specified in "control.data", e.g. http://google.com
|
||||
* playSound - play sound file. The link to file is specified in "control.data", e.g. http://www.modular-planet.de/fx/marsians/Marsiansrev.mp3.
|
||||
You can upload your own file in vis and let it play as for instance "/vis.0/main/img/myFile.mp3".
|
||||
|
||||
If user changes the view or at start the variables will be filled by vis with
|
||||
|
||||
- "control.instance": browser instance and ack=true
|
||||
- "control.data": project and view name in form "project/view", e.g. "main/view" (and ack=true)
|
||||
- "control.command": "changedView" and ack=true
|
||||
|
||||
You can write the JSON-string or Object into control.command as ```{instance: 'AABBCCDD', command: 'cmd', data: 'ddd'}```. In this case the instance and data will be taken from JSON object.
|
||||
|
||||
## Default view
|
||||
You can define for every view the desired resolution (Menu=>Tools=>Resolution). This is only the visual border in edit mode to show you the screen size on some specific device. In real time mode it will not be visible and all widgets outside of border will be visible.
|
||||
|
||||
Additionally you can define if this view must be used as default for this resolution.
|
||||
|
||||
So every time the **index.html** (without #viewName) is called, the best suitable for this resolution view will be opened.
|
||||
If only one view has *"Default"* flag, so this view will be opened independent from screen resolution or orientation.
|
||||
|
||||
E.g. you can create two views "Landscape-Mobile" and "Portrait-Mobile" and these two views will be switched automatically when you change the orientation or screen size.
|
||||
|
||||
There is a helper widget "basic - Screen Resolution" that shows actual screen resolution and best suitable default view for this resolution.
|
||||
|
||||
## Settings
|
||||
### Reload if sleep longer than
|
||||
There is a rule, that after some disconnection period the whole VIS page will be reloaded to synchronise the project.
|
||||
You can configure it in menu "Settings...". If you set interval to "never" so the page will be never reloaded.
|
||||
|
||||
### Reconnect interval
|
||||
Set the interval between the connection attempts if disconnected. If you will set 2 seconds, it will try to establish the connection every 2 seconds.
|
||||
|
||||
### Dark reconnect screen
|
||||
Sometimes (in the night) it is required to have dark loading screen. With this option you can set it.
|
||||
|
||||
Notice that this settings is valid only for reconnection and not for the first connect.
|
||||
|
||||
![Dark](img/dark_screen.png)
|
||||
|
||||
## Changelog
|
||||
### 1.1.7 (2018-07-24)
|
||||
* (bluefox) view8 corrected
|
||||
|
||||
### 1.1.6 (2018-07-18)
|
||||
* (bluefox) support of new variables (see [Special bindings](#special-bindings) )
|
||||
* (bluefox) fix error if fast view changes
|
||||
* (bluefox) fix "jqui - ctrl - IconState / val - Icon Bool"
|
||||
|
||||
### 1.1.5 (2018-06-10)
|
||||
* (bluefox) show more information if widget cannot be rendered
|
||||
* (bluefox) fix saving of widgets if they have bindings
|
||||
* (bluefox) show error stack
|
||||
* (bluefox) fix binding
|
||||
* (Apollon77) fix testing
|
||||
* (bluefox) fix for iobroker.pro and external socket.io settings
|
||||
* (bluefox) A user variable was added into bindings.
|
||||
* (bluefox) Fixed widget tabs
|
||||
|
||||
### 1.1.4 (2018-04-23)
|
||||
* (bluefox) fix bool SVG
|
||||
|
||||
### 1.1.3 (2018-04-12)
|
||||
* (bluefox) ignore click by scrolling on touch devices
|
||||
* (bluefox) remove wrong state vis.0.command
|
||||
* (bluefox) fix error with jplot
|
||||
* (bluefox) better widget behaviour in edit Mode (basic, jqui)
|
||||
* Fix config dialog
|
||||
|
||||
### 1.1.2 (2018-02-02)
|
||||
* (bluefox) Fixing the saving of project
|
||||
* (bluefox) Fixing the background selector
|
||||
* (bluefox) Fixing the null pointer problem
|
||||
* (bluefox) Fixing the selection helper
|
||||
* Update translations
|
||||
|
||||
### 1.1.1 (2018-01-07)
|
||||
* (bluefox) The problem with view change on the touch devices fixed
|
||||
|
||||
### 1.0.5 (2017-11-19)
|
||||
* (bluefox) show number of datapoints in every project
|
||||
|
||||
### 1.0.4 (2017-10-22)
|
||||
* (bluefox) Add autocomplete for view CSS options
|
||||
* (bluefox) change edit of view CSS background options
|
||||
|
||||
### 1.0.3 (2017-10-20)
|
||||
* (bluefox) Fix parse of invalid bindings
|
||||
* (bluefox) add moment.js
|
||||
|
||||
### 1.0.0 release candidate (2017-10-13)
|
||||
* (bluefox) fix iframe and image updates
|
||||
* (bluefox) fix fonts
|
||||
|
||||
### 0.15.7 (2017-10-01)
|
||||
* (bluefox) allow update of images without additional query (but it works only in spome very specific cases)
|
||||
* (bluefox) zoom of iframes
|
||||
|
||||
### 0.15.5 (2017-07-24)
|
||||
* (bluefox) Fix widgets upload
|
||||
|
||||
### 0.15.4 (2017-07-19)
|
||||
* (bluefox) Add swipe
|
||||
|
||||
### 0.15.3 (2017-07-12)
|
||||
* (bluefox) Add full screen widget
|
||||
* (bluefox) Fix timestamp widget
|
||||
|
||||
### 0.15.2 (2017-07-07)
|
||||
* (bluefox) Fix binding if it has "-" in the OID
|
||||
|
||||
### 0.15.1 (2017-06-30)
|
||||
* (bluefox) Fix error with context menu
|
||||
* (bluefox) Allow add class to view
|
||||
|
||||
### 0.15.0 (2017-05-25)
|
||||
* (bluefox) fix copy of grouped widgets
|
||||
* (bluefox) fix subscribe if empty states
|
||||
|
||||
### 0.14.7 (2017-05-19)
|
||||
* (bluefox) add templates
|
||||
|
||||
### 0.14.6 (2017-05-16)
|
||||
* (bluefox) Fix error by groups selection
|
||||
* (apollon77) fix jqui-dialog for auto-open
|
||||
|
||||
### 0.14.3 (2017-05-11)
|
||||
* (bluefox) fix export/import of groupped widgets
|
||||
|
||||
### 0.14.2 (2017-04-29)
|
||||
* (bluefox) Fix install error
|
||||
|
||||
### 0.14.1 (2017-04-27)
|
||||
* (bluefox) move beta to main
|
||||
* (bluefox) fix choose filter
|
||||
* (bluefox) fix error if some views do not exist
|
||||
* (bluefox) fix binding problem, e.g. "a:-45?0" was detected as variable too.
|
||||
* (bluefox) fix some font sizes
|
||||
* (bluefox) fix undo
|
||||
* (bluefox) fix themes change
|
||||
* (bluefox) optimize load of pages
|
||||
* (bluefox) check license
|
||||
* (bluefox) fix basic views 8
|
||||
* (bluefox) fix time picker if opened in dialog
|
||||
|
||||
### 0.14.0 (2017-04-10)
|
||||
* (bluefox) add mandatory license input
|
||||
|
||||
### 0.12.7 (2017-02-09)
|
||||
* (bluefox) prepare beta
|
||||
|
||||
### 0.12.6 (2017-01-29)
|
||||
* (pmant) fix view copy
|
||||
* (pmant) Improvements to context menu
|
||||
* (pmant) usability improvements for both view dropdowns
|
||||
* (bluefox) small fix of dragging
|
||||
|
||||
### 0.12.6 (2017-01-29)
|
||||
* (pmant) add dropdown menu to views bar
|
||||
* (pmant) sort widgets widget selector by name
|
||||
* (bluefox) fix groupAttr in signals and visibility
|
||||
|
||||
### 0.12.2 (2016-12-04)
|
||||
* (bluefox) fix errors with grouping
|
||||
|
||||
### 0.12.1 (2016-11-30)
|
||||
* (bluefox) fix errors with containers
|
||||
|
||||
### 0.12.0 (2016-11-24)
|
||||
* (bluefox) subscribe mode for faster state loading
|
||||
* (bluefox) add grouping
|
||||
|
||||
### 0.10.15 (2016-11-06)
|
||||
* (bluefox) remove weather-adapter.html
|
||||
* (bluefox) clean config.js
|
||||
* (bluefox) remove old widgets
|
||||
* (bluefox) improve authentication in app
|
||||
* (bluefox) allow creation of instance from helper widget
|
||||
|
||||
### 0.10.14 (2016-10-09)
|
||||
* (bluefox) fix rendering of widgets
|
||||
* (bluefox) working on relative positions.
|
||||
* (bluefox) destroy widgets before views deletion
|
||||
|
||||
### 0.10.13 (2016-09-23)
|
||||
* (bluefox) fixed errors for iPad 1
|
||||
* (bluefox) start wokring on relative positions
|
||||
|
||||
### 0.10.12 (2016-09-16)
|
||||
* (bluefox) group specific visibility of widgets and views
|
||||
|
||||
### 0.10.11 (2016-09-15)
|
||||
* (bluefox) fix for iOS 10
|
||||
* (bluefox) allow disabling of groups for performance
|
||||
|
||||
### 0.10.10 (2016-09-14)
|
||||
* (bluefox) add text2speech widget
|
||||
* (bluefox) try to fix problem with iOS 10
|
||||
|
||||
### 0.10.9 (2016-09-04)
|
||||
* (bluefox) support of web-sockets force
|
||||
* (bluefox) destory unused views after 30 seconds
|
||||
* (bluefox) do not show middle leading lines if top and bottom are shown
|
||||
* (bluefox) let timestamp and lastchange to show time as interval
|
||||
|
||||
### 0.10.7 (2016-07-09)
|
||||
* (bluefox) add settings to reload vis
|
||||
* (bluefox) add dark reload screen
|
||||
* (bluefox) fix reload interval
|
||||
* (bluefox) export/import
|
||||
* (bluefox) add global script
|
||||
* (bluefox) add 'not exist'/'not consist'/'exist' to signal and visibility
|
||||
* (bluefox) fix oids in editor
|
||||
|
||||
### 0.10.5 (2016-06-15)
|
||||
* (bluefox) fix select ID dialog
|
||||
* (bluefox) add align help lines
|
||||
* (bluefox) never store data in non-edit mode
|
||||
|
||||
### 0.10.4 (2016-06-14)
|
||||
* (bluefox) fix drag and resize
|
||||
* (Patrick) fix QuoJS
|
||||
* (bluefox) support of milliseconds in formatDate
|
||||
* (bluefox) support of getHistory
|
||||
* (bluefox) support of show history instances
|
||||
* (bluefox) grid
|
||||
* (bluefox) add previews
|
||||
|
||||
### 0.10.3 (2016-05-30)
|
||||
* (bluefox) update canJS
|
||||
* (pmant) fixes bugs with dialogs on touchscreens
|
||||
* (bluefox) speedUP show attributes at 300ms
|
||||
* (bluefox) fix click on widget if signal is active
|
||||
|
||||
### 0.10.2 (2016-05-24)
|
||||
* (bluefox) fix widgets with timestamps
|
||||
|
||||
### 0.10.1 (2016-05-23)
|
||||
* (bluefox) change version
|
||||
|
||||
### 0.10.0 (2016-05-23)
|
||||
* (bluefox) translates
|
||||
* (bluefox) fix 'no widgets selected'
|
||||
* (bluefox) change widget icons
|
||||
* (bluefox) add signals
|
||||
* (bluefox) add app.css for cordova
|
||||
* (bluefox) change icons preview
|
||||
* (bluefox) show properties of widget as icon
|
||||
* (bluefox) fix error with external commands
|
||||
* (bluefox) add types icon to preview
|
||||
* (bluefox) support edit on iPad1
|
||||
* (bluefox) change security settings
|
||||
|
||||
## License
|
||||
Copyright (c) 2013-2018 bluefox https://github.com/GermanBluefox <dogafox@gmail.com>,
|
||||
|
||||
Copyright (c) 2013-2014 hobbyquaker https://github.com/hobbyquaker
|
||||
|
||||
Creative Common Attribution-NonCommercial (CC BY-NC)
|
||||
|
||||
http://creativecommons.org/licenses/by-nc/4.0/
|
||||
|
||||
![CC BY-NC License](https://github.com/GermanBluefox/DashUI/raw/master/images/cc-nc-by.png)
|
||||
|
||||
Short content:
|
||||
Licensees may copy, distribute, display and perform the work and make derivative works based on it only if they give the author or licensor the credits in the manner specified by these.
|
||||
Licensees may copy, distribute, display, and perform the work and make derivative works based on it only for noncommercial purposes.
|
||||
(Free for non-commercial use).
|
13
ROADMAP.md
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
##notion:
|
||||
|
||||
* show last update time for most of widgets
|
||||
|
||||
* excpert mode
|
||||
|
||||
* Build in help for widgets
|
||||
|
||||
* Special Widgets
|
||||
for example: popups, soundplay,.....
|
||||
|
||||
* Write the instruction: how create previews and developing generally
|
7
admin/i18n/de/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Lizenz prüfen",
|
||||
"License:": "License Key:",
|
||||
"Service is offline. Please try later.": "Service ist momentan nicht erreichbar oder keine Internetverbindung vorhanden. Bitte fersuchen Sie später noch ein mal oder prüfen Sie die Internetverbindung.",
|
||||
"instruction": "Man braucht eine Lizenz um <b>vis</b> zu nutzen.<br><b>vis</b> ist kostenlos für private Nutzung. Nur für kommerzielle Gebrauch muss man für eine Lizenz bezahlen.<br>Man kann eine Lizenz auf <a href='https://iobroker.net' target='_blank'>iobroker.net</a> nach der Registrierung bekommen.",
|
||||
"vis adapter settings": "vis Adapter-Einstellungen"
|
||||
}
|
7
admin/i18n/en/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Check license",
|
||||
"License:": "License key:",
|
||||
"Service is offline. Please try later.": "Service is offline or no internet available. Please try later or check the internet connection.",
|
||||
"instruction": "To use <b>vis</b>, you must get the license key for it.<br><b>vis</b> is free for private use, but for commercial use it has a price.<br>You can get the license on <a href='https://iobroker.net' target='_blank'>iobroker.net</a> after short registration.",
|
||||
"vis adapter settings": "vis adapter settings"
|
||||
}
|
7
admin/i18n/es/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Verificar licencia",
|
||||
"License:": "Clave de licencia:",
|
||||
"Service is offline. Please try later.": "El servicio está fuera de línea o no hay internet disponible. Por favor intente más tarde o verifique la conexión a internet.",
|
||||
"instruction": "Para usar <b> vis </b>, debe obtener la clave de licencia correspondiente. <br> <b> vis </b> es gratuito para uso privado, pero para uso comercial tiene un precio. <br> Usted puede obtener la licencia en <a href='https://iobroker.net' target='_blank'>iobroker.net</a> después de un breve registro.",
|
||||
"vis adapter settings": "vis configuración del adaptador"
|
||||
}
|
7
admin/i18n/fr/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Vérifier la licence",
|
||||
"License:": "Clé de licence:",
|
||||
"Service is offline. Please try later.": "Le service est hors ligne ou pas disponible sur Internet. Veuillez réessayer plus tard ou vérifier la connexion Internet.",
|
||||
"instruction": "Pour utiliser <b> vis </b>, vous devez obtenir la clé de licence. <br> <b>vis</b> est libre pour un usage privé, mais pour un usage commercial, il a un prix. <br> Vous peut obtenir la licence sur <a href='https://iobroker.net' target='_blank'>iobroker.net</a> après une brève inscription.",
|
||||
"vis adapter settings": "paramètres de l'adaptateur vis"
|
||||
}
|
7
admin/i18n/it/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Controlla la licenza",
|
||||
"License:": "Chiave di licenza:",
|
||||
"Service is offline. Please try later.": "Il servizio è offline o non disponibile su Internet. Si prega di provare più tardi o controllare la connessione internet.",
|
||||
"instruction": "Per utilizzare <b> vis </b>, devi ottenere il codice di licenza per esso. <br> <b>vis</b> è gratuito per uso privato, ma per uso commerciale ha un prezzo. <br> Tu può ottenere la licenza su <a href='https://iobroker.net' target='_blank'>iobroker.net</a> dopo una breve registrazione.",
|
||||
"vis adapter settings": "impostazioni della scheda vis"
|
||||
}
|
7
admin/i18n/nl/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Controleer licentie",
|
||||
"License:": "Licentiesleutel:",
|
||||
"Service is offline. Please try later.": "Service is offline of geen internet beschikbaar. Probeer het later opnieuw of controleer de internetverbinding.",
|
||||
"instruction": "Als u <b> vis </b> wilt gebruiken, moet u hiervoor de licentiesleutel hebben. <br> <b> vis </b> is gratis voor privégebruik, maar voor commercieel gebruik heeft het een prijs. <br> You kan de licentie krijgen op <a href='https://iobroker.net' target='_blank'>iobroker.net</a> na een korte registratie.",
|
||||
"vis adapter settings": "vis adapter instellingen"
|
||||
}
|
7
admin/i18n/pl/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Sprawdź licencję",
|
||||
"License:": "Klucz licencyjny:",
|
||||
"Service is offline. Please try later.": "Usługa jest niedostępna lub nie ma dostępu do Internetu. Spróbuj później lub sprawdź połączenie internetowe.",
|
||||
"instruction": "Aby użyć <b> vis </b>, musisz uzyskać klucz licencyjny. <B> vis </b> jest bezpłatny do użytku prywatnego, ale do celów komercyjnych ma swoją cenę. może uzyskać licencję na <a href='https://iobroker.net' target='_blank'>iobroker.net</a> po krótkiej rejestracji.",
|
||||
"vis adapter settings": "ustawienia adaptera vis"
|
||||
}
|
7
admin/i18n/pt/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Verifique a licença",
|
||||
"License:": "Chave de licença:",
|
||||
"Service is offline. Please try later.": "O serviço está offline ou não há internet disponível. Por favor tente mais tarde ou confira a conexão com a internet.",
|
||||
"instruction": "Para usar <b> vis </b>, você deve obter a chave de licença para isso. <b>vis</b> é grátis para uso privado, mas para uso comercial, ele tem um preço. <br> Você pode obter a licença em <a href='https://iobroker.net' target='_blank'>iobroker.net</a> após curto registro.",
|
||||
"vis adapter settings": "vis as configurações do adaptador"
|
||||
}
|
7
admin/i18n/ru/translations.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"Check license": "Проверить лицензию",
|
||||
"License:": "Лицензионный ключ:",
|
||||
"Service is offline. Please try later.": "Сервис сейчас недоступен или нет интернет соединения. Попробуйте попозже или проверте интеренет соединение.",
|
||||
"instruction": "Для пользования <b>vis</b> необходимо получить лицензионный ключ.<br><b>vis</b> бесплатен для личного использования в некоммерческих целях. Для использования <b>vis</b> в коммерческих целях необходимо заплатить за лицензию.<br>Лицензионный ключ можно получить здесь <a href='https://iobroker.net/accountLicenses' target='_blank'>iobroker.net</a> после регистрации.",
|
||||
"vis adapter settings": "Настройки драйвера vis"
|
||||
}
|
119
admin/index.html
Normal file
@ -0,0 +1,119 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="../../lib/css/themes/jquery-ui/redmond/jquery-ui.min.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../../lib/css/jquery.multiselect-1.13.css"/>
|
||||
<script type="text/javascript" src="../../lib/js/jquery-1.11.1.min.js"></script>
|
||||
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="../../lib/js/jquery-ui-1.10.3.full.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../../css/adapter.css"/>
|
||||
<script type="text/javascript" src="../../js/translate.js"></script>
|
||||
<script type="text/javascript" src="../../js/adapter-settings.js"></script>
|
||||
<script type="text/javascript" src="words.js"></script>
|
||||
<style>
|
||||
.success {
|
||||
color: forestgreen;
|
||||
font-weight: bold;
|
||||
}
|
||||
.error {
|
||||
color: #ab0000;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function setValue(id, value, onChange) {
|
||||
var $value = $('#' + id + '.value');
|
||||
if ($value.attr('type') === 'checkbox') {
|
||||
$value.prop('checked', value).change(function() {
|
||||
onChange();
|
||||
});
|
||||
} else {
|
||||
$value.val(value).change(function() {
|
||||
if ($(this).attr('id') === 'license') {
|
||||
if ($(this).val()) {
|
||||
$('#check').button('enable');
|
||||
} else {
|
||||
$('#check').button('disable');
|
||||
}
|
||||
$('#checkResult').html();
|
||||
}
|
||||
onChange();
|
||||
}).keyup(function() {
|
||||
$(this).trigger('change');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function load(settings, onChange) {
|
||||
if (!settings) return;
|
||||
|
||||
if (settings.license === undefined) settings.license = '';
|
||||
|
||||
for (var key in settings) {
|
||||
if (settings.hasOwnProperty(key)) setValue(key, settings[key], onChange);
|
||||
}
|
||||
|
||||
$('#check').button({
|
||||
icons: {primary: 'ui-icon-folder-collapsed'},
|
||||
label: _('Check license')
|
||||
}).click(function () {
|
||||
$('#check').button('disable');
|
||||
$('#checkResult').html('...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'https://iobroker.net/cert/',
|
||||
data: $('#license').val(),
|
||||
contentType: 'text/plain',
|
||||
xhrFields: {
|
||||
withCredentials: false
|
||||
},
|
||||
headers: {},
|
||||
success: function(data, status, request) {
|
||||
$('#check').button('enable');
|
||||
$('#checkResult').html(data ? data.result : 'error').removeClass('error').addClass(data.result === 'OK' ? 'success': '');
|
||||
},
|
||||
error: function (res, error) {
|
||||
$('#check').button('enable');
|
||||
$('#checkResult').html(_('Service is offline. Please try later.')).addClass('error').removeClass('success');
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!settings.license) {
|
||||
$('#check').button('disable');
|
||||
}
|
||||
|
||||
onChange(false);
|
||||
}
|
||||
|
||||
function save(callback) {
|
||||
var obj = {};
|
||||
$('.value').each(function () {
|
||||
var $this = $(this);
|
||||
if ($this.attr('type') === 'checkbox') {
|
||||
obj[$this.attr('id')] = $this.prop('checked');
|
||||
} else {
|
||||
obj[$this.attr('id')] = $this.val();
|
||||
}
|
||||
});
|
||||
|
||||
callback(obj);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="adapter-container">
|
||||
|
||||
<table><tr>
|
||||
<td><img src="vis.png"></td>
|
||||
<td style="padding-top: 20px; padding-left: 10px;"><h3 class="translate">vis adapter settings</h3></td>
|
||||
</tr></table>
|
||||
|
||||
<table style="width: 100%; padding: 10px">
|
||||
<tr><td style="width: 50px"><label class="translate" for="license">License:</label></td><td class="admin-icon"></td><td><textarea class="value number" id="license" style="width: 100%; height: 100px; resize: none"></textarea></td></tr>
|
||||
<tr><td></td><td class="admin-icon"></td><td><button id="check" style="display: inline-block"></button><div id="checkResult" style="padding-left: 10px; display: inline-block"></div></td></tr>
|
||||
<tr><td colspan="3"> </td></tr>
|
||||
<tr><td></td><td></td><td class="translate" style="font-size: 16px;">instruction</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
149
admin/index_m.html
Normal file
@ -0,0 +1,149 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Materialze style -->
|
||||
<link rel="stylesheet" type="text/css" href="../../css/adapter.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css">
|
||||
|
||||
<script type="text/javascript" src="../../lib/js/jquery-1.11.1.min.js"></script>
|
||||
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../../js/translate.js"></script>
|
||||
<script type="text/javascript" src="../../lib/js/materialize.js"></script>
|
||||
<script type="text/javascript" src="../../js/adapter-settings.js"></script>
|
||||
<script type="text/javascript" src="words.js"></script>
|
||||
|
||||
<style>
|
||||
.success {
|
||||
color: forestgreen;
|
||||
font-weight: bold;
|
||||
}
|
||||
.error {
|
||||
color: #ab0000;
|
||||
}
|
||||
.license {
|
||||
height: 100px !important;
|
||||
}
|
||||
#check {
|
||||
display: inline-block;
|
||||
}
|
||||
#checkResult {
|
||||
padding-left: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
.instructions{
|
||||
font-size: 16px;
|
||||
}
|
||||
.m .col .select-wrapper+label {
|
||||
top: -26px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function setValue(id, value, onChange) {
|
||||
var $value = $('#' + id + '.value');
|
||||
if ($value.attr('type') === 'checkbox') {
|
||||
$value.prop('checked', value).change(function() {
|
||||
onChange();
|
||||
});
|
||||
} else {
|
||||
$value.val(value).change(function() {
|
||||
if ($(this).attr('id') === 'license') {
|
||||
if ($(this).val()) {
|
||||
$('#check').removeClass('disabled');
|
||||
} else {
|
||||
$('#check').addClass('disabled');
|
||||
}
|
||||
$('#checkResult').html();
|
||||
}
|
||||
onChange();
|
||||
}).keyup(function() {
|
||||
$(this).trigger('change');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function load(settings, onChange) {
|
||||
if (!settings) return;
|
||||
|
||||
if (settings.license === undefined) settings.license = '';
|
||||
|
||||
for (var key in settings) {
|
||||
if (settings.hasOwnProperty(key)) setValue(key, settings[key], onChange);
|
||||
}
|
||||
var $check = $('#check');
|
||||
$check.click(function () {
|
||||
$('#check').addClass('disabled');
|
||||
$('#checkResult').html('...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'https://iobroker.net/cert/',
|
||||
data: $('#license').val(),
|
||||
contentType: 'text/plain',
|
||||
xhrFields: {
|
||||
withCredentials: false
|
||||
},
|
||||
headers: {},
|
||||
success: function(data, status, request) {
|
||||
$('#check').removeClass('disabled');
|
||||
$('#checkResult').html(data ? data.result : 'error').removeClass('error').addClass(data.result === 'OK' ? 'success': '');
|
||||
},
|
||||
error: function (res, error) {
|
||||
$('#check').removeClass('disabled');
|
||||
$('#checkResult').html(_('Service is offline. Please try later.')).addClass('error').removeClass('success');
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!settings.license) {
|
||||
$check.addClass('disabled');
|
||||
}
|
||||
|
||||
M.updateTextFields();
|
||||
onChange(false);
|
||||
}
|
||||
|
||||
function save(callback) {
|
||||
var obj = {};
|
||||
$('.value').each(function () {
|
||||
var $this = $(this);
|
||||
if ($this.attr('type') === 'checkbox') {
|
||||
obj[$this.attr('id')] = $this.prop('checked');
|
||||
} else {
|
||||
obj[$this.attr('id')] = $this.val();
|
||||
}
|
||||
});
|
||||
|
||||
callback(obj);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="m adapter-container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="row">
|
||||
<div class="col s12 m3 l2">
|
||||
<img src="vis.png" class="logo">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s12">
|
||||
<textarea class="value materialize-textarea license" id="license"></textarea>
|
||||
<label class="translate" for="license">License:</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="input-field col s6">
|
||||
<a class="waves-effect waves-light btn" id="check"><i class="material-icons">help</i><span class="translate">Check license</span></a>
|
||||
<div id="checkResult"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12 m8">
|
||||
<span class="translate instructions">instruction</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
admin/vis.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
11
admin/words.js
Normal file
@ -0,0 +1,11 @@
|
||||
// DO NOT EDIT THIS FILE!!! IT WILL BE AUTOMATICALLY GENERATED FROM src/i18n
|
||||
/*global systemDictionary:true */
|
||||
'use strict';
|
||||
|
||||
systemDictionary = {
|
||||
"Check license": { "en": "Check license", "de": "Lizenz prüfen", "ru": "Проверить лицензию", "pt": "Verifique a licença", "nl": "Controleer licentie", "fr": "Vérifier la licence", "it": "Controlla la licenza", "es": "Verificar licencia", "pl": "Sprawdź licencję"},
|
||||
"License:": { "en": "License key:", "de": "License Key:", "ru": "Лицензионный ключ:", "pt": "Chave de licença:", "nl": "Licentiesleutel:", "fr": "Clé de licence:", "it": "Chiave di licenza:", "es": "Clave de licencia:", "pl": "Klucz licencyjny:"},
|
||||
"Service is offline. Please try later.": { "en": "Service is offline or no internet available. Please try later or check the internet connection.", "de": "Service ist momentan nicht erreichbar oder keine Internetverbindung vorhanden. Bitte fersuchen Sie später noch ein mal oder prüfen Sie die Internetverbindung.", "ru": "Сервис сейчас недоступен или нет интернет соединения. Попробуйте попозже или проверте интеренет соединение.", "pt": "O serviço está offline ou não há internet disponível. Por favor tente mais tarde ou confira a conexão com a internet.", "nl": "Service is offline of geen internet beschikbaar. Probeer het later opnieuw of controleer de internetverbinding.", "fr": "Le service est hors ligne ou pas disponible sur Internet. Veuillez réessayer plus tard ou vérifier la connexion Internet.", "it": "Il servizio è offline o non disponibile su Internet. Si prega di provare più tardi o controllare la connessione internet.", "es": "El servicio está fuera de línea o no hay internet disponible. Por favor intente más tarde o verifique la conexión a internet.", "pl": "Usługa jest niedostępna lub nie ma dostępu do Internetu. Spróbuj później lub sprawdź połączenie internetowe."},
|
||||
"instruction": { "en": "To use <b>vis</b>, you must get the license key for it.<br><b>vis</b> is free for private use, but for commercial use it has a price.<br>You can get the license on <a href='https://iobroker.net' target='_blank'>iobroker.net</a> after short registration.", "de": "Man braucht eine Lizenz um <b>vis</b> zu nutzen.<br><b>vis</b> ist kostenlos für private Nutzung. Nur für kommerzielle Gebrauch muss man für eine Lizenz bezahlen.<br>Man kann eine Lizenz auf <a href='https://iobroker.net' target='_blank'>iobroker.net</a> nach der Registrierung bekommen.", "ru": "Для пользования <b>vis</b> необходимо получить лицензионный ключ.<br><b>vis</b> бесплатен для личного использования в некоммерческих целях. Для использования <b>vis</b> в коммерческих целях необходимо заплатить за лицензию.<br>Лицензионный ключ можно получить здесь <a href='https://iobroker.net/accountLicenses' target='_blank'>iobroker.net</a> после регистрации.", "pt": "Para usar <b> vis </b>, você deve obter a chave de licença para isso. <b>vis</b> é grátis para uso privado, mas para uso comercial, ele tem um preço. <br> Você pode obter a licença em <a href='https://iobroker.net' target='_blank'>iobroker.net</a> após curto registro.", "nl": "Als u <b> vis </b> wilt gebruiken, moet u hiervoor de licentiesleutel hebben. <br> <b> vis </b> is gratis voor privégebruik, maar voor commercieel gebruik heeft het een prijs. <br> You kan de licentie krijgen op <a href='https://iobroker.net' target='_blank'>iobroker.net</a> na een korte registratie.", "fr": "Pour utiliser <b> vis </b>, vous devez obtenir la clé de licence. <br> <b>vis</b> est libre pour un usage privé, mais pour un usage commercial, il a un prix. <br> Vous peut obtenir la licence sur <a href='https://iobroker.net' target='_blank'>iobroker.net</a> après une brève inscription.", "it": "Per utilizzare <b> vis </b>, devi ottenere il codice di licenza per esso. <br> <b>vis</b> è gratuito per uso privato, ma per uso commerciale ha un prezzo. <br> Tu può ottenere la licenza su <a href='https://iobroker.net' target='_blank'>iobroker.net</a> dopo una breve registrazione.", "es": "Para usar <b> vis </b>, debe obtener la clave de licencia correspondiente. <br> <b> vis </b> es gratuito para uso privado, pero para uso comercial tiene un precio. <br> Usted puede obtener la licencia en <a href='https://iobroker.net' target='_blank'>iobroker.net</a> después de un breve registro.", "pl": "Aby użyć <b> vis </b>, musisz uzyskać klucz licencyjny. <B> vis </b> jest bezpłatny do użytku prywatnego, ale do celów komercyjnych ma swoją cenę. może uzyskać licencję na <a href='https://iobroker.net' target='_blank'>iobroker.net</a> po krótkiej rejestracji."},
|
||||
"vis adapter settings": { "en": "vis adapter settings", "de": "vis Adapter-Einstellungen", "ru": "Настройки драйвера vis", "pt": "vis as configurações do adaptador", "nl": "vis adapter instellingen", "fr": "paramètres de l'adaptateur vis", "it": "impostazioni della scheda vis", "es": "vis configuración del adaptador", "pl": "ustawienia adaptera vis"},
|
||||
};
|
26
appveyor.yml
Normal file
@ -0,0 +1,26 @@
|
||||
version: 'test-{build}'
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: '4'
|
||||
- nodejs_version: '6'
|
||||
- nodejs_version: '8'
|
||||
- nodejs_version: '10'
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
clone_folder: 'c:\projects\%APPVEYOR_PROJECT_NAME%'
|
||||
install:
|
||||
- ps: 'Install-Product node $env:nodejs_version $env:platform'
|
||||
- ps: '$NpmVersion = (npm -v).Substring(0,1)'
|
||||
- ps: 'if($NpmVersion -eq 5) { npm install -g npm@5 }'
|
||||
- ps: npm --version
|
||||
- npm install
|
||||
- npm install winston@2.3.1
|
||||
- 'npm install https://github.com/ioBroker/ioBroker.js-controller/tarball/master --production'
|
||||
- npm install iobroker.web --prefix ./node_modules/iobroker.js-controller/
|
||||
test_script:
|
||||
- echo %cd%
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
build: 'off'
|
459
gulpfile.js
Normal file
@ -0,0 +1,459 @@
|
||||
'use strict';
|
||||
|
||||
var gulp = require('gulp');
|
||||
var fs = require('fs');
|
||||
var replace = require('gulp-replace');
|
||||
var pkg = require('./package.json');
|
||||
var iopackage = require('./io-package.json');
|
||||
var version = (pkg && pkg.version) ? pkg.version : iopackage.common.version;
|
||||
/*var appName = getAppName();
|
||||
|
||||
function getAppName() {
|
||||
var parts = __dirname.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 1].split('.')[0].toLowerCase();
|
||||
}
|
||||
*/
|
||||
const fileName = 'words.js';
|
||||
var languages = {
|
||||
en: {},
|
||||
de: {},
|
||||
ru: {},
|
||||
pt: {},
|
||||
nl: {},
|
||||
fr: {},
|
||||
it: {},
|
||||
es: {},
|
||||
pl: {}
|
||||
};
|
||||
var srcDir = __dirname + '/';
|
||||
|
||||
function lang2data(lang, isFlat) {
|
||||
var str = isFlat ? '' : '{\n';
|
||||
var count = 0;
|
||||
for (var w in lang) {
|
||||
if (lang.hasOwnProperty(w)) {
|
||||
count++;
|
||||
if (isFlat) {
|
||||
str += (lang[w] === '' ? (isFlat[w] || w) : lang[w]) + '\n';
|
||||
} else {
|
||||
var key = ' "' + w.replace(/"/g, '\\"') + '": ';
|
||||
str += key + '"' + lang[w].replace(/"/g, '\\"') + '",\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!count) return isFlat ? '' : '{\n}';
|
||||
if (isFlat) {
|
||||
return str;
|
||||
} else {
|
||||
return str.substring(0, str.length - 2) + '\n}';
|
||||
}
|
||||
}
|
||||
|
||||
function readWordJs(src) {
|
||||
try {
|
||||
var words;
|
||||
if (fs.existsSync(src + 'js/' + fileName)) {
|
||||
words = fs.readFileSync(src + 'js/' + fileName).toString();
|
||||
} else {
|
||||
words = fs.readFileSync(src + fileName).toString();
|
||||
}
|
||||
|
||||
var lines = words.split(/\r\n|\r|\n/g);
|
||||
var i = 0;
|
||||
while (!lines[i].match(/^\$\.extend\(systemDictionary, {/)) {
|
||||
i++;
|
||||
}
|
||||
lines.splice(0, i);
|
||||
|
||||
// remove last empty lines
|
||||
i = lines.length - 1;
|
||||
while (!lines[i]) {
|
||||
i--;
|
||||
}
|
||||
if (i < lines.length - 1) {
|
||||
lines.splice(i + 1);
|
||||
}
|
||||
|
||||
lines[0] = lines[0].replace('$.extend(systemDictionary, ', '');
|
||||
lines[lines.length - 1] = lines[lines.length - 1].trim().replace(/}\);$/, '}');
|
||||
words = lines.join('\n');
|
||||
var resultFunc = new Function('return ' + words + ';');
|
||||
|
||||
return resultFunc();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function padRight(text, totalLength) {
|
||||
return text + (text.length < totalLength ? new Array(totalLength - text.length).join(' ') : '');
|
||||
}
|
||||
function writeWordJs(data, src) {
|
||||
var text = '// DO NOT EDIT THIS FILE!!! IT WILL BE AUTOMATICALLY GENERATED FROM src/i18n\n';
|
||||
text += '/*global systemDictionary:true */\n';
|
||||
text += '\'use strict\';\n\n';
|
||||
text += 'systemDictionary = {\n';
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
text += ' ' + padRight('"' + word.replace(/"/g, '\\"') + '": {', 50);
|
||||
var line = '';
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
line += '"' + lang + '": "' + padRight(data[word][lang].replace(/"/g, '\\"') + '",', 50) + ' ';
|
||||
}
|
||||
}
|
||||
if (line) {
|
||||
line = line.trim();
|
||||
line = line.substring(0, line.length - 1);
|
||||
}
|
||||
text += line + '},\n';
|
||||
}
|
||||
}
|
||||
text += '};';
|
||||
if (fs.existsSync(src + 'js/' + fileName)) {
|
||||
fs.writeFileSync(src + 'js/' + fileName, text);
|
||||
} else {
|
||||
fs.writeFileSync(src + '' + fileName, text);
|
||||
}
|
||||
}
|
||||
|
||||
const EMPTY = '';
|
||||
|
||||
function words2languages(src) {
|
||||
var langs = Object.assign({}, languages);
|
||||
var data = readWordJs(src);
|
||||
if (data) {
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
langs[lang][word] = data[word][lang];
|
||||
// pre-fill all other languages
|
||||
for (var j in langs) {
|
||||
if (langs.hasOwnProperty(j)) {
|
||||
langs[j][word] = langs[j][word] || EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/')) {
|
||||
fs.mkdirSync(src + 'i18n/');
|
||||
}
|
||||
for (var l in langs) {
|
||||
if (!langs.hasOwnProperty(l)) continue;
|
||||
var keys = Object.keys(langs[l]);
|
||||
//keys.sort();
|
||||
var obj = {};
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
obj[keys[k]] = langs[l][keys[k]];
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/' + l)) {
|
||||
fs.mkdirSync(src + 'i18n/' + l);
|
||||
}
|
||||
|
||||
fs.writeFileSync(src + 'i18n/' + l + '/translations.json', lang2data(obj));
|
||||
}
|
||||
} else {
|
||||
console.error('Cannot read or parse ' + fileName);
|
||||
}
|
||||
}
|
||||
function words2languagesFlat(src) {
|
||||
var langs = Object.assign({}, languages);
|
||||
var data = readWordJs(src);
|
||||
if (data) {
|
||||
for (var word in data) {
|
||||
if (data.hasOwnProperty(word)) {
|
||||
for (var lang in data[word]) {
|
||||
if (data[word].hasOwnProperty(lang)) {
|
||||
langs[lang][word] = data[word][lang];
|
||||
// pre-fill all other languages
|
||||
for (var j in langs) {
|
||||
if (langs.hasOwnProperty(j)) {
|
||||
langs[j][word] = langs[j][word] || EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var keys = Object.keys(langs.en);
|
||||
keys.sort();
|
||||
for (var l in langs) {
|
||||
if (!langs.hasOwnProperty(l)) continue;
|
||||
var obj = {};
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
obj[keys[k]] = langs[l][keys[k]];
|
||||
}
|
||||
langs[l] = obj;
|
||||
}
|
||||
if (!fs.existsSync(src + 'i18n/')) {
|
||||
fs.mkdirSync(src + 'i18n/');
|
||||
}
|
||||
for (var ll in langs) {
|
||||
if (!langs.hasOwnProperty(ll)) continue;
|
||||
if (!fs.existsSync(src + 'i18n/' + ll)) {
|
||||
fs.mkdirSync(src + 'i18n/' + ll);
|
||||
}
|
||||
|
||||
fs.writeFileSync(src + 'i18n/' + ll + '/flat.txt', lang2data(langs[ll], langs.en));
|
||||
}
|
||||
fs.writeFileSync(src + 'i18n/flat.txt', keys.join('\n'));
|
||||
} else {
|
||||
console.error('Cannot read or parse ' + fileName);
|
||||
}
|
||||
}
|
||||
function languagesFlat2words(src) {
|
||||
var dirs = fs.readdirSync(src + 'i18n/');
|
||||
var langs = {};
|
||||
var bigOne = {};
|
||||
var order = Object.keys(languages);
|
||||
dirs.sort(function (a, b) {
|
||||
var posA = order.indexOf(a);
|
||||
var posB = order.indexOf(b);
|
||||
if (posA === -1 && posB === -1) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
} else if (posA === -1) {
|
||||
return -1;
|
||||
} else if (posB === -1) {
|
||||
return 1;
|
||||
} else {
|
||||
if (posA > posB) return 1;
|
||||
if (posA < posB) return -1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
var keys = fs.readFileSync(src + 'i18n/flat.txt').toString().split('\n');
|
||||
|
||||
for (var l = 0; l < dirs.length; l++) {
|
||||
if (dirs[l] === 'flat.txt') continue;
|
||||
var lang = dirs[l];
|
||||
var values = fs.readFileSync(src + 'i18n/' + lang + '/flat.txt').toString().split('\n');
|
||||
langs[lang] = {};
|
||||
keys.forEach(function (word, i) {
|
||||
langs[lang][word] = values[i];
|
||||
});
|
||||
|
||||
var words = langs[lang];
|
||||
for (var word in words) {
|
||||
if (words.hasOwnProperty(word)) {
|
||||
bigOne[word] = bigOne[word] || {};
|
||||
if (words[word] !== EMPTY) {
|
||||
bigOne[word][lang] = words[word];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// read actual words.js
|
||||
var aWords = readWordJs();
|
||||
|
||||
var temporaryIgnore = ['pt', 'fr', 'nl', 'flat.txt'];
|
||||
if (aWords) {
|
||||
// Merge words together
|
||||
for (var w in aWords) {
|
||||
if (aWords.hasOwnProperty(w)) {
|
||||
if (!bigOne[w]) {
|
||||
console.warn('Take from actual words.js: ' + w);
|
||||
bigOne[w] = aWords[w]
|
||||
}
|
||||
dirs.forEach(function (lang) {
|
||||
if (temporaryIgnore.indexOf(lang) !== -1) return;
|
||||
if (!bigOne[w][lang]) {
|
||||
console.warn('Missing "' + lang + '": ' + w);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
writeWordJs(bigOne, src);
|
||||
}
|
||||
function languages2words(src) {
|
||||
var dirs = fs.readdirSync(src + 'i18n/');
|
||||
var langs = {};
|
||||
var bigOne = {};
|
||||
var order = Object.keys(languages);
|
||||
dirs.sort(function (a, b) {
|
||||
var posA = order.indexOf(a);
|
||||
var posB = order.indexOf(b);
|
||||
if (posA === -1 && posB === -1) {
|
||||
if (a > b) return 1;
|
||||
if (a < b) return -1;
|
||||
return 0;
|
||||
} else if (posA === -1) {
|
||||
return -1;
|
||||
} else if (posB === -1) {
|
||||
return 1;
|
||||
} else {
|
||||
if (posA > posB) return 1;
|
||||
if (posA < posB) return -1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
for (var l = 0; l < dirs.length; l++) {
|
||||
if (dirs[l] === 'flat.txt') continue;
|
||||
var lang = dirs[l];
|
||||
langs[lang] = fs.readFileSync(src + 'i18n/' + lang + '/translations.json').toString();
|
||||
langs[lang] = JSON.parse(langs[lang]);
|
||||
var words = langs[lang];
|
||||
for (var word in words) {
|
||||
if (words.hasOwnProperty(word)) {
|
||||
bigOne[word] = bigOne[word] || {};
|
||||
if (words[word] !== EMPTY) {
|
||||
bigOne[word][lang] = words[word];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// read actual words.js
|
||||
var aWords = readWordJs();
|
||||
|
||||
var temporaryIgnore = ['pt', 'fr', 'nl', 'it', 'es', 'pl'];
|
||||
if (aWords) {
|
||||
// Merge words together
|
||||
for (var w in aWords) {
|
||||
if (aWords.hasOwnProperty(w)) {
|
||||
if (!bigOne[w]) {
|
||||
console.warn('Take from actual words.js: ' + w);
|
||||
bigOne[w] = aWords[w]
|
||||
}
|
||||
dirs.forEach(function (lang) {
|
||||
if (temporaryIgnore.indexOf(lang) !== -1) return;
|
||||
if (!bigOne[w][lang]) {
|
||||
console.warn('Missing "' + lang + '": ' + w);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
writeWordJs(bigOne, src);
|
||||
}
|
||||
|
||||
gulp.task('wwwWords2languages', function (done) {
|
||||
words2languages('./www/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('wwwWords2languagesFlat', function (done) {
|
||||
words2languagesFlat('./www/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('wwwLanguagesFlat2words', function (done) {
|
||||
languagesFlat2words('./www/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('wwwLanguages2words', function (done) {
|
||||
languages2words('./www/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminWords2languages', function (done) {
|
||||
words2languages('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminWords2languagesFlat', function (done) {
|
||||
words2languagesFlat('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminLanguagesFlat2words', function (done) {
|
||||
languagesFlat2words('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('adminLanguages2words', function (done) {
|
||||
languages2words('./admin/');
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
gulp.task('replacePkg', function (done) {
|
||||
gulp.src([
|
||||
srcDir + 'package.json',
|
||||
srcDir + 'io-package.json'
|
||||
])
|
||||
.pipe(replace(/"version": *"[.0-9]*",/g, '"version": "' + version + '",'))
|
||||
.pipe(gulp.dest(srcDir));
|
||||
});
|
||||
gulp.task('replaceVis', function () {
|
||||
return gulp.src([
|
||||
srcDir + 'www/js/vis.js'
|
||||
])
|
||||
.pipe(replace(/var version = *'[.0-9]*';/g, 'var version = "' + version + '";'))
|
||||
.pipe(replace(/"version": *"[.0-9]*",/g, '"version": "' + version + '",'))
|
||||
.pipe(replace(/version: *"[.0-9]*",/g, 'version: "' + version + '",'))
|
||||
.pipe(replace(/version: *'[.0-9]*',/g, 'version: \'' + version + '\','))
|
||||
.pipe(replace(/<!-- vis Version [.0-9]+ -->/g, '<!-- vis Version ' + version + ' -->'))
|
||||
.pipe(replace(/# vis Version [.0-9]+/g, '# vis Version ' + version))
|
||||
.pipe(replace(/ dev build [.0-9]+/g, '# dev build 0'))
|
||||
.pipe(gulp.dest( srcDir + '/www/js'));
|
||||
});
|
||||
gulp.task('replaceHtml', function (done) {
|
||||
gulp.src([
|
||||
srcDir + 'www/cache.manifest',
|
||||
srcDir + 'www/index.html',
|
||||
srcDir + 'www/edit.html'
|
||||
])
|
||||
.pipe(replace(/<!-- vis Version [.0-9]+ -->/g, '<!-- vis Version ' + version + ' -->'))
|
||||
.pipe(replace(/var version = *'[.0-9]*';/g, 'var version = \'' + version + '\';'))
|
||||
.pipe(replace(/"version": *"[.0-9]*",/g, '"version": "' + version + '",'))
|
||||
.pipe(replace(/version: *"[.0-9]*",/g, 'version: "' + version + '",'))
|
||||
.pipe(replace(/version: *'[.0-9]*',/g, 'version: \'' + version + '\','))
|
||||
.pipe(replace(/# vis Version [.0-9]+/g, '# vis Version ' + version))
|
||||
.pipe(replace(/# dev build [.0-9]+/g, '# dev build 0'))
|
||||
.pipe(gulp.dest(srcDir + '/www'));
|
||||
});
|
||||
|
||||
gulp.task('updatePackages', function (done) {
|
||||
iopackage.common.version = pkg.version;
|
||||
iopackage.common.news = iopackage.common.news || {};
|
||||
if (!iopackage.common.news[pkg.version]) {
|
||||
var news = iopackage.common.news;
|
||||
var newNews = {};
|
||||
|
||||
newNews[pkg.version] = {
|
||||
en: 'news',
|
||||
de: 'neues',
|
||||
ru: 'новое'
|
||||
};
|
||||
iopackage.common.news = Object.assign(newNews, news);
|
||||
}
|
||||
fs.writeFileSync('io-package.json', JSON.stringify(iopackage, null, 4));
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('updateReadme', function (done) {
|
||||
var readme = fs.readFileSync('README.md').toString();
|
||||
var pos = readme.indexOf('## Changelog\n');
|
||||
if (pos !== -1) {
|
||||
var readmeStart = readme.substring(0, pos + '## Changelog\n'.length);
|
||||
var readmeEnd = readme.substring(pos + '## Changelog\n'.length);
|
||||
|
||||
if (readme.indexOf(version) === -1) {
|
||||
var timestamp = new Date();
|
||||
var date = timestamp.getFullYear() + '-' +
|
||||
('0' + (timestamp.getMonth() + 1).toString(10)).slice(-2) + '-' +
|
||||
('0' + (timestamp.getDate()).toString(10)).slice(-2);
|
||||
|
||||
var news = '';
|
||||
if (iopackage.common.news && iopackage.common.news[pkg.version]) {
|
||||
news += '* ' + iopackage.common.news[pkg.version].en;
|
||||
}
|
||||
|
||||
fs.writeFileSync('README.md', readmeStart + '### ' + version + ' (' + date + ')\n' + (news ? news + '\n\n' : '\n') + readmeEnd);
|
||||
}
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('replace', ['replacePkg', 'replaceVis', 'replaceHtml']);
|
||||
|
||||
gulp.task('default', ['updatePackages', 'updateReadme', 'replace']);
|
BIN
img/dark_screen.png
Normal file
After Width: | Height: | Size: 42 KiB |
240
io-package.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"common": {
|
||||
"name": "vis",
|
||||
"version": "1.1.7",
|
||||
"title": "Visualisation",
|
||||
"titleLang": {
|
||||
"en": "Visualisation",
|
||||
"de": "Visualisierung",
|
||||
"ru": "Визуализация",
|
||||
"pt": "Visualização",
|
||||
"nl": "Visualisatie",
|
||||
"fr": "Visualisation",
|
||||
"it": "Visualizzazione",
|
||||
"es": "Visualización",
|
||||
"pl": "Wizualizacja"
|
||||
},
|
||||
"news": {
|
||||
"1.1.7": {
|
||||
"en": "view8 corrected",
|
||||
"de": "view8 korrigiert",
|
||||
"ru": "view8 исправлено",
|
||||
"pt": "view8 corrigido",
|
||||
"nl": "view8 gecorrigeerd",
|
||||
"fr": "view8 corrigé",
|
||||
"it": "view8 corretta",
|
||||
"es": "view8 corregido",
|
||||
"pl": "view8 poprawiony"
|
||||
},
|
||||
"1.1.6": {
|
||||
"en": "New special bindings are supported\nError with fast view changes is fixed\nfix (jqui - ctrl - IconState / val - Icon Bool)",
|
||||
"de": "Neue spezielle Bindungen werden unterstützt\nFehler bei schnellen Ansichtsänderungen ist behoben\nfix (jqui - Strg - IconState / val - Icon Bool)",
|
||||
"ru": "Поддерживаются новые специальные привязки\nИсправлена ошибка с быстрым изменением вида\nfix (jqui - ctrl - IconState / val - Icon Bool)",
|
||||
"pt": "Novas ligações especiais são suportadas\nErro com alterações de visualização rápida corrigidas\ncorrigir (jqui - ctrl - IconState / val - Bool de ícone)",
|
||||
"nl": "Nieuwe speciale bindingen worden ondersteund\nFout bij snelle wijzigingen in weergave is opgelost\nfix (jqui - ctrl - IconState / val - Icon Bool)",
|
||||
"fr": "Les nouvelles liaisons spéciales sont prises en charge\nErreur avec les changements d'affichage rapide est fixée\ncorriger (jqui - ctrl - IconState / val - Icône Bool)",
|
||||
"it": "Sono supportati nuovi binding speciali\nL'errore con le modifiche veloci alla vista è stato risolto\ncorreggere (jqui - ctrl - IconState / val - Icon Bool)",
|
||||
"es": "Se admiten nuevos enlaces especiales\nSe corrigió el error con los cambios de vista rápida\ncorregir (jqui - ctrl - IconState / val - Icon Bool)",
|
||||
"pl": "Nowe powiązania specjalne są obsługiwane\nNaprawiono błąd związany z szybkimi zmianami widoku\nnapraw (jqui - ctrl - IconState / val - Icon Bool)"
|
||||
},
|
||||
"1.1.4": {
|
||||
"en": "Fixing the saving of project\nFixing the background selector\nFixing the null pointer problem\nFixing the selection helper\nUpdate translations",
|
||||
"de": "Die Projektspeicherung ist korrigiert\nHintergrundselektors ist korrigiert\nReparieren des Null-Zeiger-Problems\nAuswahlhelfer korrigiert\nÜbersetzungen",
|
||||
"ru": "исправлено сохранение проекта\nисправлен переключатель фона\nУстранение проблемы с нулевым указателем\nисправлен выбор виджетов\nпереводы",
|
||||
"pt": "Reparando a poupança do projeto\nCorrigindo o seletor de fundo\nCorrigindo o problema do ponteiro nulo\nReparando o auxiliar de seleção\nAtualizar traduções",
|
||||
"nl": "Het opslaan van het project bevestigen\nDe achtergrondkiezer bevestigen\nVaststelling van het probleem met de null-wijzer\nDe selectiehulp bevestigen\nUpdate vertalingen",
|
||||
"fr": "Fixer la sauvegarde du projet\nFixer le sélecteur d'arrière-plan\nCorrection du problème du pointeur nul\nCorrection de l'assistant de sélection\nMise à jour",
|
||||
"it": "Risolvendo il salvataggio del progetto\nRisolto il problema con il selettore dello sfondo\nRisolvere il problema con il puntatore nullo\nRiparare l'helper di selezione\nAggiorna traduzioni",
|
||||
"es": "Corregir el guardado del proyecto\nReparar el selector de fondo\nCorregir el problema del puntero nulo\nReparar el asistente de selección\nActualizar traducciones",
|
||||
"pl": "Naprawienie zapisu projektu\nNaprawianie wybieraka tła\nNaprawiono problem z pustym wskaźnikiem\nNaprawianie pomocnika wyboru\nZaktualizuj tłumaczenia"
|
||||
},
|
||||
"1.1.2": {
|
||||
"en": "Fixing the saving of project\nFixing the background selector\nFixing the null pointer problem\nFixing the selection helper\nUpdate translations",
|
||||
"de": "Die Projektspeicherung ist korrigiert\nHintergrundselektors ist korrigiert\nReparieren des Null-Zeiger-Problems\nAuswahlhelfer korrigiert\nÜbersetzungen",
|
||||
"ru": "исправлено сохранение проекта\nисправлен переключатель фона\nУстранение проблемы с нулевым указателем\nисправлен выбор виджетов\nпереводы",
|
||||
"pt": "Reparando a poupança do projeto\nCorrigindo o seletor de fundo\nCorrigindo o problema do ponteiro nulo\nReparando o auxiliar de seleção\nAtualizar traduções",
|
||||
"nl": "Het opslaan van het project bevestigen\nDe achtergrondkiezer bevestigen\nVaststelling van het probleem met de null-wijzer\nDe selectiehulp bevestigen\nUpdate vertalingen",
|
||||
"fr": "Fixer la sauvegarde du projet\nFixer le sélecteur d'arrière-plan\nCorrection du problème du pointeur nul\nCorrection de l'assistant de sélection\nMise à jour",
|
||||
"it": "Risolvendo il salvataggio del progetto\nRisolto il problema con il selettore dello sfondo\nRisolvere il problema con il puntatore nullo\nRiparare l'helper di selezione\nAggiorna traduzioni",
|
||||
"es": "Corregir el guardado del proyecto\nReparar el selector de fondo\nCorregir el problema del puntero nulo\nReparar el asistente de selección\nActualizar traducciones",
|
||||
"pl": "Naprawienie zapisu projektu\nNaprawianie wybieraka tła\nNaprawiono problem z pustym wskaźnikiem\nNaprawianie pomocnika wyboru\nZaktualizuj tłumaczenia"
|
||||
},
|
||||
"1.1.1": {
|
||||
"en": "The problem with view change on the touch devices fixed",
|
||||
"de": "Das Problem mit der Ansicht Änderung auf den Touch-Geräten behoben",
|
||||
"ru": "Проблема с изменением вида на сенсорных устройствах исправлена",
|
||||
"pt": "O problema com a mudança de exibição nos dispositivos de toque fixos",
|
||||
"nl": "Het probleem met de wijziging van weergave op de aanraakapparaten is opgelost",
|
||||
"fr": "Le problème avec le changement de vue sur les appareils tactiles fixés",
|
||||
"it": "Risolto il problema con il cambio di vista sui dispositivi touch",
|
||||
"es": "El problema con el cambio de vista en los dispositivos táctiles solucionó",
|
||||
"pl": "Naprawiono problem z zmianą widoku na urządzeniach dotykowych"
|
||||
},
|
||||
"1.0.5": {
|
||||
"en": "show number of datapoints in every project",
|
||||
"de": "Zeige die Anzahl von Datenpunkten in jedem Projekt",
|
||||
"ru": "Показывет количество используемых данных в каждом проекте"
|
||||
},
|
||||
"1.0.4": {
|
||||
"en": "Add autocomplete for view CSS options\nchange edit of view CSS background options",
|
||||
"de": "Automatische Vervollständigung für View-CSS-Optionen hinzufügen\nÄndern der CSS-Hintergrundoptionen für View",
|
||||
"ru": "Добавлено автозаполнение для CSS опций страницы\nИзменение редактирования background CSS страницы"
|
||||
},
|
||||
"1.0.3": {
|
||||
"en": "Release candidate\nFix parse of invalid bindings\nadd moment.js",
|
||||
"de": "Release candidate\nKorrigiere die Aufbau von falschen Bindings\nmoment.js hinzugefügt",
|
||||
"ru": "Release candidate\nПоправлен рендеринг неправильных bindings\nДобавлен moment.js"
|
||||
},
|
||||
"0.15.6": {
|
||||
"en": "Added array operator to bindings",
|
||||
"de": "Array Operator zu bindings hinzugefügt"
|
||||
},
|
||||
"0.15.5": {
|
||||
"en": "Fix widgets upload",
|
||||
"de": "Korrigiere Widgets uplaod",
|
||||
"ru": "Исправлено обновление виджетов"
|
||||
},
|
||||
"0.15.4": {
|
||||
"en": "Add swipe",
|
||||
"de": "Swipe hunzugefügt",
|
||||
"ru": "Добавлен swipe"
|
||||
},
|
||||
"0.15.3": {
|
||||
"en": "Add full screen widget\nFix timestamp widget",
|
||||
"de": "Full Screen Widget hunzugefügt\nKorrigiere timestamp widget",
|
||||
"ru": "Добавлен виджет full screen\nИсправлен виджет timestamp"
|
||||
},
|
||||
"0.15.2": {
|
||||
"en": "Fix binding if it has \"-\" in the OID",
|
||||
"de": "Korrigiere den fehler mit Binding und \"-\" in OID",
|
||||
"ru": "Исправлены bindings, если содержат минус в имени"
|
||||
},
|
||||
"0.15.1": {
|
||||
"en": "Fix error with context menu\nAllow add class to view",
|
||||
"de": "Korrigiere den fehler mit dem Kontext-Menu\nErlaube Klasse zur Seite hinzufügen",
|
||||
"ru": "Исправлено контекстное меню\nМожно добавлять классы к страницам"
|
||||
}
|
||||
},
|
||||
"desc": {
|
||||
"en": "Graphical user interface for iobroker",
|
||||
"de": "Grafische Benutzeroberfläche für iobroker",
|
||||
"ru": "Графический пользовательский интерфейс для iobroker",
|
||||
"pt": "Interface gráfica do usuário para iobroker",
|
||||
"nl": "Grafische gebruikersinterface voor iobroker",
|
||||
"fr": "Interface utilisateur graphique pour iobroker",
|
||||
"it": "Interfaccia utente grafica per iobroker",
|
||||
"es": "Interfaz gráfica de usuario para iobroker",
|
||||
"pl": "Graficzny interfejs użytkownika dla iobroker"
|
||||
},
|
||||
"platform": "Javascript/Node.js",
|
||||
"loglevel": "info",
|
||||
"icon": "vis.png",
|
||||
"enabled": true,
|
||||
"mode": "once",
|
||||
"extIcon": "https://raw.githubusercontent.com/iobroker/iobroker.vis/master/admin/vis.png",
|
||||
"keywords": [
|
||||
"DashUI",
|
||||
"GUI",
|
||||
"graphical",
|
||||
"scada"
|
||||
],
|
||||
"readme": "https://github.com/iobroker/iobroker.vis/blob/master/README.md",
|
||||
"authors": [
|
||||
"bluefox <dogafox@gmail.com>"
|
||||
],
|
||||
"localLink": "%web_protocol%://%ip%:%web_port%/vis/edit.html",
|
||||
"license": "CC BY-NC",
|
||||
"dependencies": [
|
||||
{
|
||||
"web": ">=1.5.4"
|
||||
}
|
||||
],
|
||||
"restartAdapters": [
|
||||
"vis"
|
||||
],
|
||||
"serviceStates": "lib/states.js",
|
||||
"singleton": true,
|
||||
"type": "visualization",
|
||||
"highlight": true,
|
||||
"noConfig": false,
|
||||
"materialize": true,
|
||||
"welcomeScreen": {
|
||||
"link": "vis/index.html",
|
||||
"name": "vis runtime",
|
||||
"img": "vis/img/favicon.png",
|
||||
"color": "#ffe9c8",
|
||||
"order": 0
|
||||
},
|
||||
"welcomeScreenPro": {
|
||||
"link": "vis/edit.html",
|
||||
"name": "vis editor",
|
||||
"img": "vis/img/faviconEdit.png",
|
||||
"color": "#c8ffe1",
|
||||
"order": 1
|
||||
}
|
||||
},
|
||||
"native": {
|
||||
"defaultFileMode": 1604,
|
||||
"license": ""
|
||||
},
|
||||
"instanceObjects": [
|
||||
{
|
||||
"_id": "",
|
||||
"type": "meta",
|
||||
"common": {
|
||||
"name": "user files and images for vis",
|
||||
"type": "meta.user"
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
{
|
||||
"_id": "control",
|
||||
"type": "channel",
|
||||
"common": {
|
||||
"name": "Control vis"
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
{
|
||||
"_id": "control.instance",
|
||||
"type": "state",
|
||||
"common": {
|
||||
"name": "Control vis",
|
||||
"type": "string",
|
||||
"desc": "Write here browser instance ID to control or 'FFFFFFFF' to control all instances"
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
{
|
||||
"_id": "control.command",
|
||||
"type": "state",
|
||||
"common": {
|
||||
"name": "Command for vis",
|
||||
"type": "string",
|
||||
"desc": "Writing this variable akt as the trigger. Instance and data must be preset before 'command' will be written. 'changedView' will be signalled too",
|
||||
"states": {
|
||||
"alert": "alert",
|
||||
"changeView": "changeView",
|
||||
"refresh": "refresh",
|
||||
"reload": "reload",
|
||||
"dialog": "dialog",
|
||||
"popup": "popup",
|
||||
"playSound": "playSound",
|
||||
"changedView": "changedView",
|
||||
"tts": "tts"
|
||||
}
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
{
|
||||
"_id": "control.data",
|
||||
"type": "state",
|
||||
"common": {
|
||||
"name": "Data for control vis",
|
||||
"type": "string",
|
||||
"desc": "Used for: alert, changeView, dialog, popup, playSound, changedView"
|
||||
},
|
||||
"native": {}
|
||||
}
|
||||
]
|
||||
}
|
9
lib/cloudCert.crt
Normal file
@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1C0AJ+H6KeRo77undcx
|
||||
kyKDn3edWDaTNrxvg4DhlGgCEBAcStoROu+6TKMw5bc/V+U4s7vqfz9vxh4GXtUk
|
||||
RwPsx2ggrhp08bUYeO9zA9EMFICD6Klva6FALqCLpwv4e8g1CzeKQqhxzAe7v/Ey
|
||||
dMW4foMyugGHGEO6ZCbHyPMdrg0A4NmpSV/TsWduBbjkq03D63ovAzM+u2lAHHrt
|
||||
84QShY1ZZoRCHD2F7bRQW906wiVZNfQYKSeTkfc9Ctatuz8JMIq57dlyAF/R6+jC
|
||||
UodEZvqO9ZTDRGbX2MWDdedRMAt8hPQxjxugiUheMCCrTbdZ5bxeXqyaTLYuzNyV
|
||||
bwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
100
lib/convert.js
Normal file
@ -0,0 +1,100 @@
|
||||
// this file is used by controller when build uploads
|
||||
function stringify(name, data, isConvert, files) {
|
||||
if (isConvert && name.match(/vis-views\.json$/)) {
|
||||
var parts = name.split('/');
|
||||
var project = parts.shift();
|
||||
data = data.toString();
|
||||
// detect: /vis/, /vis.0/, /icon-blabla/, ...
|
||||
var m = data.match(/": "\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+"/g);
|
||||
if (m) {
|
||||
for (var mm = 0; mm < m.length; mm++) {
|
||||
var fn = m[mm].substring(5); // remove ": "/
|
||||
var originalFileName = fn.replace(/"/g, ''); // remove last "
|
||||
var p = fn.split('/');
|
||||
var adapter = p.shift(); // remove vis.0 or whatever
|
||||
var _project = p.length > 1 ? p.shift() : '';
|
||||
fn = p.length ? p.shift() : ''; // keep only one subdirectory
|
||||
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
|
||||
|
||||
if (adapter !== 'vis.0' || _project !== project) {
|
||||
// add to files
|
||||
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
|
||||
files.push(originalFileName);
|
||||
}
|
||||
data = data.replace(m[mm], '": "/vis.0/' + project + '/' + fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to replace <img src="/vis.0/main...">
|
||||
m = data.match(/src=\\"\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+\\"/g);
|
||||
if (m) {
|
||||
for (var mm = 0; mm < m.length; mm++) {
|
||||
var fn = m[mm].substring(7); // remove src=\"/
|
||||
var originalFileName = fn.replace(/\\"/g, ''); // remove last "
|
||||
var p = fn.split('/');
|
||||
var adapter = p.shift(); // remove vis.0 or whatever
|
||||
var _project = p.length > 1 ? p.shift() : '';
|
||||
fn = p.length ? p.shift() : ''; // keep only one subdirectory
|
||||
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
|
||||
|
||||
if (adapter !== 'vis.0' || _project !== project) {
|
||||
// add to files
|
||||
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
|
||||
files.push(originalFileName);
|
||||
}
|
||||
data = data.replace(m[mm], 'src=\\"/vis.0/' + project + '/' + fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to replace <img src='/vis.0/main...'>
|
||||
m = data.match(/src='\/[-_0-9\w]+(\.[-_0-9\w]+)?\/.+\.(png|jpg|jpeg|gif|wav|mp3|bmp|svg)+'/g);
|
||||
if (m) {
|
||||
for (var mm = 0; mm < m.length; mm++) {
|
||||
var fn = m[mm].substring(6); // remove src="/
|
||||
var originalFileName = fn.replace(/'/g, ''); // remove last "
|
||||
var p = fn.split('/');
|
||||
var adapter = p.shift(); // remove vis.0 or whatever
|
||||
var _project = p.length > 1 ? p.shift() : '';
|
||||
fn = p.length ? p.shift() : ''; // keep only one subdirectory
|
||||
fn += p.length ? '/' + p.join('/') : '';// all other subdirectories combine again
|
||||
|
||||
if (adapter !== 'vis.0' || _project !== project) {
|
||||
// add to files
|
||||
if (files.indexOf(originalFileName) === -1) { // if "vis.0/dir/otherProject.png"
|
||||
files.push(originalFileName);
|
||||
}
|
||||
data = data.replace(m[mm], "src='/vis.0/" + project + '/' + fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to replace <img src='/vis.0/main...'>
|
||||
m = data.match(/\.[A-Z]{3}\d{7}\./g);
|
||||
if (m) {
|
||||
for (var t = 0; t < m.length; t++) {
|
||||
data = data.replace(m[t], '.ABC' + Math.round(Math.random() * 1000000) + '.');
|
||||
}
|
||||
}
|
||||
// try to replace 12.13.14.15
|
||||
data = data.replace(/\/\/(?:[0-9]{1,3}\.){3}[0-9]{1,3}\//g, '//127.0.0.1/');
|
||||
|
||||
// try to replace http://user:pass@address/
|
||||
data = data.replace(/((http|https):\/\/)?([-\w0-9_.]+?):([-\w0-9_*.]+)?@[-\w0-9.]+\//g, '//127.0.0.1/');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function parse(projectName, fileName, data, settings) {
|
||||
if (fileName.match(/vis-views\.json$/)) {
|
||||
// Check if all images are in the right directory
|
||||
var project = projectName;
|
||||
if (project[project.length - 1] === '/') project = project.substring(0, project.length - 1);
|
||||
data = data.toString();
|
||||
|
||||
// detect: "/vis.0/project/picture.png"
|
||||
data = data.replace(/"\/vis.0\/([-_0-9\w]+)\//g, '"/vis.0/' + project + '/');
|
||||
data = data.replace(/'\/vis.0\/([-_0-9\w]+)\//g, "'/vis.0/" + project + '/');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
module.exports.stringify = stringify;
|
||||
module.exports.parse = parse;
|
211
lib/install.js
Normal file
@ -0,0 +1,211 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
function copyFileSync(source, target) {
|
||||
var targetFile = target;
|
||||
|
||||
//if target is a directory a new file with the same name will be created
|
||||
if (fs.existsSync(target)) {
|
||||
if (fs.lstatSync(target).isDirectory()) {
|
||||
targetFile = path.join(target, path.basename(source));
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(targetFile, fs.readFileSync(source));
|
||||
}
|
||||
|
||||
function copyFolderRecursiveSync(source, target) {
|
||||
var files = [];
|
||||
|
||||
//check if folder needs to be created or integrated
|
||||
var targetFolder = path.join(target, path.basename(source));
|
||||
if (!fs.existsSync(targetFolder)) {
|
||||
fs.mkdirSync(targetFolder);
|
||||
}
|
||||
|
||||
//copy
|
||||
if (fs.lstatSync(source).isDirectory() ) {
|
||||
files = fs.readdirSync( source );
|
||||
files.forEach(function (file) {
|
||||
var curSource = path.join(source, file);
|
||||
if (fs.lstatSync(curSource).isDirectory()) {
|
||||
copyFolderRecursiveSync(curSource, targetFolder);
|
||||
} else {
|
||||
copyFileSync(curSource, targetFolder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deleteFolderRecursive (path) {
|
||||
var files = [];
|
||||
if (fs.existsSync(path)) {
|
||||
files = fs.readdirSync(path);
|
||||
files.forEach(function(file, index){
|
||||
var curPath = path + '/' + file;
|
||||
if(fs.lstatSync(curPath).isDirectory()) { // recurse
|
||||
deleteFolderRecursive(curPath);
|
||||
} else { // delete file
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(path);
|
||||
}
|
||||
}
|
||||
|
||||
var generic = [
|
||||
'basic',
|
||||
'jqplot',
|
||||
'jqui',
|
||||
'tabs',
|
||||
'swipe'
|
||||
];
|
||||
|
||||
var widgetSetsDependencies = {
|
||||
jqui: ['basic']
|
||||
};
|
||||
|
||||
function syncWidgetSets(onlyLocal, isLicenseError) {
|
||||
if (process.argv.indexOf('--beta') !== -1) return;
|
||||
|
||||
var pack = null;
|
||||
var changed = false;
|
||||
var found;
|
||||
var name;
|
||||
var path = __dirname + '/../../';
|
||||
|
||||
// find all installed widget sets
|
||||
if (onlyLocal) {
|
||||
path = __dirname + '/../node_modules/';
|
||||
} else {
|
||||
path = __dirname + '/../../';
|
||||
}
|
||||
var dirs = fs.readdirSync(path);
|
||||
var sets = [];
|
||||
for (var d = 0; d < dirs.length; d++) {
|
||||
if (dirs[d].match(/^iobroker\./i) && fs.existsSync(path + dirs[d] + '/widgets/')) {
|
||||
pack = null;
|
||||
try {
|
||||
pack = JSON.parse(fs.readFileSync(path + dirs[d] + '/io-package.json').toString());
|
||||
} catch (e) {
|
||||
console.warn('Cannot parse "' + path + dirs[d] + '/io-package.json": ' + e);
|
||||
}
|
||||
sets.push({path: path + dirs[d], name: dirs[d].toLowerCase(), pack: pack});
|
||||
}
|
||||
}
|
||||
if (!onlyLocal) {
|
||||
try {
|
||||
dirs = fs.readdirSync(__dirname + '/../../../../');
|
||||
for (d = 0; d < dirs.length; d++) {
|
||||
if (dirs[d].match(/^iobroker\./i) && fs.existsSync(__dirname + '/../../../../' + dirs[d] + '/widgets/')) {
|
||||
found = false;
|
||||
name = dirs[d].toLowerCase();
|
||||
for (var s = 0; s < sets.length; s++) {
|
||||
if (sets[s].name === name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
pack = null;
|
||||
try {
|
||||
pack = JSON.parse(fs.readFileSync(__dirname + '/../../../../' + dirs[d] + '/io-package.json').toString());
|
||||
} catch (e) {
|
||||
console.warn('Cannot parse "' + __dirname + '/../../../../' + dirs[d] + '/io-package.json": ' + e);
|
||||
}
|
||||
sets.push({path: __dirname + '/../../../../' + dirs[d], name: dirs[d].toLowerCase()});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have the list of widgets => copy them all to widgets directory
|
||||
for (d = 0; d < sets.length; d++) {
|
||||
copyFolderRecursiveSync(sets[d].path + '/widgets/', __dirname + '/../www/');
|
||||
}
|
||||
var widgetSets = [];
|
||||
|
||||
// Read the list of installed widgets
|
||||
var installed = fs.readdirSync(__dirname + '/../www/widgets/');
|
||||
for (d = 0; d < installed.length; d++) {
|
||||
if (installed[d].match(/\.html$/)) {
|
||||
name = installed[d].replace('.html', '');
|
||||
var isGeneric = generic.indexOf(name) !== -1;
|
||||
found = isGeneric;
|
||||
|
||||
if (!found) {
|
||||
for (var b = 0; b < sets.length; b++) {
|
||||
var ssName = sets[b].name.toLowerCase();
|
||||
if (ssName === 'iobroker.vis-' + name || ssName === 'iobroker.' + name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
changed = true;
|
||||
//delete
|
||||
fs.unlinkSync(__dirname + '/../www/widgets/' + name + '.html');
|
||||
if (fs.existsSync(__dirname + '/../www/widgets/' + name)) {
|
||||
deleteFolderRecursive(__dirname + '/../www/widgets/' + name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isGeneric) {
|
||||
if (widgetSetsDependencies[name] && widgetSetsDependencies[name].length) {
|
||||
widgetSets.push({name: name, depends: widgetSetsDependencies[name]});
|
||||
} else {
|
||||
widgetSets.push(name);
|
||||
}
|
||||
} else {
|
||||
for (var g = 0; g < sets.length; g++) {
|
||||
var sName = sets[g].name.toLowerCase();
|
||||
if (sName === 'iobroker.vis-' + name || sName === 'iobroker.' + name) {
|
||||
if (sets[g].pack && sets[g].pack.native && sets[g].pack.native.always) {
|
||||
widgetSets.push({name: name, always: true});
|
||||
} else if (sets[g].pack && sets[g].pack.native && sets[g].pack.native.dependencies) {
|
||||
widgetSets.push({name: name, depends: sets[g].pack.native.dependencies});
|
||||
} else {
|
||||
widgetSets.push(name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build config file
|
||||
var visConfig = {
|
||||
widgetSets: widgetSets
|
||||
};
|
||||
|
||||
var text = 'var visConfig = ' + JSON.stringify(visConfig, null, 4) + ';\n';
|
||||
if (isLicenseError) {
|
||||
text = text.replace('var visConfig = {', 'var visConfig = {license: false,');
|
||||
}
|
||||
text += 'if (typeof exports !== \'undefined\') {\n';
|
||||
text += ' exports.config = visConfig;\n';
|
||||
text += '} else {\n';
|
||||
text += ' visConfig.language = window.navigator.userLanguage || window.navigator.language;\n';
|
||||
text += '}\n';
|
||||
|
||||
var oldText = fs.readFileSync(__dirname + '/../www/js/config.js').toString();
|
||||
if (oldText !== text) {
|
||||
fs.writeFileSync(__dirname + '/../www/js/config.js', text);
|
||||
return text;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && module.parent) {
|
||||
module.exports = syncWidgetSets;
|
||||
} else {
|
||||
syncWidgetSets();
|
||||
}
|
53
lib/states.js
Normal file
@ -0,0 +1,53 @@
|
||||
var getUsedObjectIDs = require(__dirname + '/../www/js/visUtils').getUsedObjectIDs;
|
||||
|
||||
function calcProject(objects, projects, instance, result, callback) {
|
||||
if (!projects || !projects.length) {
|
||||
callback(null, result || []);
|
||||
return;
|
||||
}
|
||||
result = result || [];
|
||||
var project = projects.shift();
|
||||
if (!project || !project.isDir) {
|
||||
setImmediate(calcProject, objects, projects, instance, result, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate datapoints in one project
|
||||
objects.readFile('vis.' + instance, '/' + project.file + '/vis-views.json', function (err, data) {
|
||||
var json;
|
||||
try {
|
||||
json = JSON.parse(data);
|
||||
} catch (e) {
|
||||
console.error('Cannot parse "/' + project.file + '/vis-views.json');
|
||||
setImmediate(calcProject, objects, projects, instance, result, callback);
|
||||
return;
|
||||
}
|
||||
var dps = getUsedObjectIDs(json, false);
|
||||
if (dps && dps.IDs) {
|
||||
result.push({id: 'vis.' + instance + '.datapoints.' + project.file.replace(/[.\\s]/g, '_'), val: dps.IDs.length});
|
||||
}
|
||||
setImmediate(calcProject, objects, projects, instance, result, callback);
|
||||
});
|
||||
}
|
||||
|
||||
function calcProjects(objects, states, instance, config, callback) {
|
||||
objects.readDir('vis.' + instance, '/', function (err, projects) {
|
||||
if (err || !projects || !projects.length) {
|
||||
callback && callback(err || null, [{id: 'vis.' + instance + '.datapoints.total', val: 0}]);
|
||||
} else {
|
||||
calcProject(objects, projects, instance, [], function (err, result) {
|
||||
if (result && result.length) {
|
||||
var total = 0;
|
||||
for (var r = 0; r < result.length; r++) {
|
||||
total += result[r].val;
|
||||
}
|
||||
result.push({id: 'vis.' + instance + '.datapoints.total', val: total});
|
||||
}
|
||||
|
||||
callback && callback(err, result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = calcProjects;
|
83
lib/utils.js
Normal file
@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
let controllerDir;
|
||||
let appName;
|
||||
|
||||
/**
|
||||
* returns application name
|
||||
*
|
||||
* The name of the application can be different and this function finds it out.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function getAppName() {
|
||||
const parts = __dirname.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 2].split('.')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* looks for js-controller home folder
|
||||
*
|
||||
* @param {boolean} isInstall
|
||||
* @returns {string}
|
||||
*/
|
||||
function getControllerDir(isInstall) {
|
||||
// Find the js-controller location
|
||||
const possibilities = [
|
||||
'iobroker.js-controller',
|
||||
'ioBroker.js-controller',
|
||||
];
|
||||
/** @type {string} */
|
||||
let controllerPath;
|
||||
for (const pkg of possibilities) {
|
||||
try {
|
||||
const possiblePath = require.resolve(pkg);
|
||||
if (fs.existsSync(possiblePath)) {
|
||||
controllerPath = possiblePath;
|
||||
break;
|
||||
}
|
||||
} catch (e) { /* not found */ }
|
||||
}
|
||||
if (controllerPath == null) {
|
||||
if (!isInstall) {
|
||||
console.log('Cannot find js-controller');
|
||||
process.exit(10);
|
||||
} else {
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
// we found the controller
|
||||
return path.dirname(controllerPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* reads controller base settings
|
||||
*
|
||||
* @alias getConfig
|
||||
* @returns {object}
|
||||
*/
|
||||
function getConfig() {
|
||||
let configPath;
|
||||
if (fs.existsSync(
|
||||
configPath = path.join(controllerDir, 'conf', appName + '.json')
|
||||
)) {
|
||||
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
} else if (fs.existsSync(
|
||||
configPath = path.join(controllerDir, 'conf', + appName.toLowerCase() + '.json')
|
||||
)) {
|
||||
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
} else {
|
||||
throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
|
||||
}
|
||||
}
|
||||
appName = getAppName();
|
||||
controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);
|
||||
const adapter = require(path.join(controllerDir, 'lib/adapter.js'));
|
||||
|
||||
exports.controllerDir = controllerDir;
|
||||
exports.getConfig = getConfig;
|
||||
exports.Adapter = adapter;
|
||||
exports.appName = appName;
|
371
main.js
Normal file
@ -0,0 +1,371 @@
|
||||
/**
|
||||
*
|
||||
* iobroker vis Adapter
|
||||
*
|
||||
* (c) 2014-2017 bluefox, hobbyquaker
|
||||
*
|
||||
* CC-NC-BY 4.0 License
|
||||
*
|
||||
*/
|
||||
/* jshint -W097 */
|
||||
/* jshint strict:false */
|
||||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var adapterName = require(__dirname + '/package.json').name.split('.').pop();
|
||||
var isBeta = adapterName.indexOf('beta') !== -1;
|
||||
|
||||
var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
|
||||
var adapter = new utils.Adapter(adapterName);
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var syncWidgetSets = require(__dirname + '/lib/install.js');
|
||||
var https = require('https');
|
||||
var jwt = require('jsonwebtoken');
|
||||
//var minify = require('html-minifier').minify;
|
||||
|
||||
adapter.on('ready', function () {
|
||||
main();
|
||||
});
|
||||
|
||||
function writeFile(fileName, callback) {
|
||||
var config = require(__dirname + '/www/js/config.js').config;
|
||||
var index;
|
||||
var srcFileNameParts = fileName.split('.');
|
||||
var ext = srcFileNameParts.pop();
|
||||
var srcFileName = srcFileNameParts.join('.') + '.src.' + ext;
|
||||
if (fs.existsSync(__dirname + '/www/' + srcFileName)) {
|
||||
index = fs.readFileSync(__dirname + '/www/' + srcFileName).toString();
|
||||
} else {
|
||||
index = fs.readFileSync(__dirname + '/www/' + fileName).toString();
|
||||
fs.writeFileSync(__dirname + '/www/' + srcFileName, index);
|
||||
}
|
||||
|
||||
// enable cache
|
||||
index = index.replace('<!--html manifest="cache.manifest" xmlns="http://www.w3.org/1999/html"--><html>',
|
||||
'<html manifest="cache.manifest" xmlns="http://www.w3.org/1999/html">');
|
||||
|
||||
var begin = '<!-- --------------------------------------- DO NOT EDIT INSIDE THIS LINE - BEGIN ------------------------------------------- -->';
|
||||
var end = '<!-- --------------------------------------- DO NOT EDIT INSIDE THIS LINE - END ------------------------------------------- -->';
|
||||
var bigInsert = '';
|
||||
for (var w in config.widgetSets) {
|
||||
if (!config.widgetSets.hasOwnProperty(w)) continue;
|
||||
var file;
|
||||
var name;
|
||||
|
||||
if (typeof config.widgetSets[w] === 'object') {
|
||||
name = config.widgetSets[w].name + '.html';
|
||||
} else {
|
||||
name = config.widgetSets[w] + '.html';
|
||||
}
|
||||
file = fs.readFileSync(__dirname + '/www/widgets/' + name);
|
||||
// extract all css and js
|
||||
|
||||
|
||||
bigInsert += '<!-- --------------' + name + '--- START -->\n' + file.toString() + '\n<!-- --------------' + name + '--- END -->\n';
|
||||
}
|
||||
var pos = index.indexOf(begin);
|
||||
if (pos !== -1) {
|
||||
var start = index.substring(0, pos + begin.length);
|
||||
pos = index.indexOf(end);
|
||||
if (pos !== -1) {
|
||||
var _end = index.substring(pos);
|
||||
index = start + '\n' + bigInsert + '\n' + _end;
|
||||
|
||||
/*index = minify(index, {
|
||||
removeAttributeQuotes: true,
|
||||
removeComments: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
collapseWhitespace: true,
|
||||
decodeEntities: true,
|
||||
minifyCSS: true,
|
||||
minifyJS: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true
|
||||
});*/
|
||||
|
||||
adapter.readFile(adapterName, fileName, function (err, data) {
|
||||
if (data && data !== index) {
|
||||
fs.writeFileSync(__dirname + '/www/' + fileName, index);
|
||||
adapter.writeFile(adapterName, fileName, index, function () {
|
||||
if (callback) callback(true);
|
||||
});
|
||||
} else {
|
||||
if (callback) callback(false);
|
||||
}
|
||||
});
|
||||
} else if (callback) {
|
||||
callback(false);
|
||||
}
|
||||
} else if (callback) {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
|
||||
function upload(callback) {
|
||||
adapter.log.info('Upload ' + adapter.name + ' anew, while changes detected...');
|
||||
var file = utils.controllerDir + '/iobroker.js';
|
||||
var child = require('child_process').spawn('node', [file, 'upload', adapter.name, 'widgets']);
|
||||
var count = 0;
|
||||
child.stdout.on('data', function (data) {
|
||||
count++;
|
||||
adapter.log.debug(data.toString().replace('\n', ''));
|
||||
if ((count % 100) === 0) adapter.log.info(count + ' files uploaded...');
|
||||
});
|
||||
child.stderr.on('data', function (data) {
|
||||
adapter.log.error(data.toString().replace('\n', ''));
|
||||
});
|
||||
child.on('exit', function (exitCode) {
|
||||
adapter.log.info('Uploaded. ' + (exitCode ? 'Exit - ' + exitCode : 0));
|
||||
callback(exitCode);
|
||||
});
|
||||
}
|
||||
|
||||
function updateCacheManifest(callback) {
|
||||
adapter.log.info('Changes in index.html detected => update cache.manifest');
|
||||
var data = fs.readFileSync(__dirname + '/www/cache.manifest').toString();
|
||||
var build = data.match(/# dev build ([0-9]+)/);
|
||||
data = data.replace(/# dev build [0-9]+/, '# dev build ' + (parseInt(build[1] || 0, 10) + 1));
|
||||
fs.writeFileSync(__dirname + '/www/cache.manifest', data);
|
||||
|
||||
adapter.writeFile(adapterName, 'cache.manifest', data, function () {
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
// Update index.html
|
||||
function checkFiles(configChanged, isBeta) {
|
||||
if (isBeta) {
|
||||
adapter.stop();
|
||||
return;
|
||||
}
|
||||
writeFile('index.html', function (indexChanged) {
|
||||
// Update edit.html
|
||||
writeFile('edit.html', function (editChanged) {
|
||||
if (indexChanged || editChanged || configChanged) {
|
||||
updateCacheManifest(function () {
|
||||
upload(function () {
|
||||
adapter.stop();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
adapter.stop();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function copyFiles(root, filesOrDirs, callback) {
|
||||
if (!filesOrDirs) {
|
||||
adapter.readDir('vis.0', root, function (err, filesOrDirs) {
|
||||
copyFiles(root, filesOrDirs || [], callback);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!filesOrDirs.length) {
|
||||
if (typeof callback === 'function') callback();
|
||||
return;
|
||||
}
|
||||
|
||||
var task = filesOrDirs.shift();
|
||||
if (task.isDir) {
|
||||
copyFiles(root + task.file + '/', null, function () {
|
||||
setTimeout(copyFiles, 0, root, filesOrDirs, callback);
|
||||
})
|
||||
} else {
|
||||
adapter.readFile('vis.0', root + task.file, function (err, data) {
|
||||
if (data || data === 0 || data === '') {
|
||||
adapter.writeFile(adapterName + '.0', root + task.file, data, function () {
|
||||
setTimeout(copyFiles, 0, root, filesOrDirs, callback);
|
||||
});
|
||||
} else {
|
||||
setTimeout(copyFiles, 0, root, filesOrDirs, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function generatePages(isLicenseError) {
|
||||
var count = 0;
|
||||
var changed = false;
|
||||
|
||||
if (!isBeta) {
|
||||
changed = syncWidgetSets(false, isLicenseError);
|
||||
|
||||
if (changed) {
|
||||
// upload config.js
|
||||
count++;
|
||||
var config = changed;
|
||||
adapter.readFile(adapterName, 'js/config.js', function (err, data) {
|
||||
if (data && data !== config) {
|
||||
adapter.log.info('config.js changed. Upload.');
|
||||
adapter.writeFile(adapterName, 'js/config.js', config, function () {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
});
|
||||
} else {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
}
|
||||
});
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
// try to read vis-beta.0/files
|
||||
adapter.readDir(adapterName + '.0', '/', function (err, dirs) {
|
||||
if (!dirs || !dirs.length) {
|
||||
// copy all directories
|
||||
copyFiles('/', null, function () {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
})
|
||||
} else {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// create command variable
|
||||
count++;
|
||||
adapter.getObject('control.command', function (err, obj) {
|
||||
if (!obj) {
|
||||
adapter.setObject('control.command',
|
||||
{
|
||||
"type": "state",
|
||||
"common": {
|
||||
"name": "Command for vis",
|
||||
"type": "string",
|
||||
"desc": "Writing this variable akt as the trigger. Instance and data must be preset before 'command' will be written. 'changedView' will be signalled too",
|
||||
"states": {
|
||||
"alert": "alert",
|
||||
"changeView": "changeView",
|
||||
"refresh": "refresh",
|
||||
"reload": "reload",
|
||||
"dialog": "dialog",
|
||||
"popup": "popup",
|
||||
"playSound": "playSound",
|
||||
"changedView": "changedView",
|
||||
"tts": "tts"
|
||||
}
|
||||
},
|
||||
"native": {}
|
||||
},
|
||||
function () {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
}) ;
|
||||
} else {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
}
|
||||
});
|
||||
|
||||
// Create common user CSS file
|
||||
count++;
|
||||
adapter.readFile(adapterName, 'css/vis-common-user.css', function (err, data) {
|
||||
if (err || data === null || data === undefined) {
|
||||
adapter.writeFile(adapterName, 'css/vis-common-user.css', '', function () {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
});
|
||||
} else {
|
||||
if (!--count) checkFiles(changed, isBeta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function indicateError(callback) {
|
||||
var data = fs.readFileSync(__dirname + '/www/js/config.js').toString();
|
||||
if (data.indexOf('license: false,') === -1) {
|
||||
data = data.replace('var visConfig = {', 'var visConfig = {license: false,');
|
||||
fs.writeFileSync(__dirname + '/www/js/config.js', data);
|
||||
|
||||
adapter.writeFile(adapterName, 'js/config.js', data, function () {
|
||||
updateCacheManifest(callback);
|
||||
});
|
||||
} else {
|
||||
callback && callback();
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
// Check if noConfig = false
|
||||
if (adapter.common.noConfig) {
|
||||
adapter.getForeignObject('system.adapter.' + adapter.namespace, function (err, obj) {
|
||||
obj.common.noConfig = false;
|
||||
adapter.setForeignObject(obj._id, obj, function () {
|
||||
adapter.stop();
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// first of all check license
|
||||
if (!adapter.config.license || typeof adapter.config.license !== 'string') {
|
||||
indicateError(function () {
|
||||
adapter.log.error('No license found for vis. Please get one on https://iobroker.net !');
|
||||
//adapter.stop();
|
||||
generatePages(true);
|
||||
});
|
||||
} else {
|
||||
// An object of options to indicate where to post to
|
||||
var postOptions = {
|
||||
host: 'iobroker.net',
|
||||
path: '/cert/',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Length': Buffer.byteLength(adapter.config.license)
|
||||
}
|
||||
};
|
||||
|
||||
// Set up the request
|
||||
var postReq = https.request(postOptions, function (res) {
|
||||
res.setEncoding('utf8');
|
||||
var result = '';
|
||||
res.on('data', function (chunk) {
|
||||
result += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
try {
|
||||
var data = JSON.parse(result);
|
||||
if (data.result === 'OK') {
|
||||
adapter.log.info('vis license is OK.');
|
||||
generatePages();
|
||||
} else {
|
||||
indicateError(function () {
|
||||
adapter.log.error('License is invalid! Nothing updated. Error: ' + (data ? data.result: 'unknown'));
|
||||
//adapter.stop();
|
||||
generatePages(true);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
indicateError(function () {
|
||||
adapter.log.error('Cannot check license! Nothing updated. Error: ' + (data ? data.result: 'unknown'));
|
||||
//adapter.stop();
|
||||
generatePages(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
}).on('error', function (error) {
|
||||
jwt.verify(adapter.config.license, fs.readFileSync(__dirname + '/lib/cloudCert.crt'), function (err, decoded) {
|
||||
if (err) {
|
||||
adapter.log.error('Cannot check license: ' + error);
|
||||
//adapter.stop();
|
||||
generatePages(true);
|
||||
} else {
|
||||
if (decoded && decoded.expires * 1000 < new Date().getTime()) {
|
||||
adapter.log.error('Cannot check license: Expired on ' + new Date(decoded.expires * 1000).toString());
|
||||
adapter.stop();
|
||||
} else if (!decoded) {
|
||||
adapter.log.error('Cannot check license: License is empty');
|
||||
//adapter.stop();
|
||||
generatePages(true);
|
||||
} else {
|
||||
generatePages(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
postReq.write(adapter.config.license);
|
||||
postReq.end();
|
||||
}
|
||||
}
|
51
package.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "iobroker.vis",
|
||||
"description": "Graphical user interface for iobroker.",
|
||||
"version": "1.1.7",
|
||||
"author": {
|
||||
"name": "bluefox",
|
||||
"email": "dogafox@gmail.com"
|
||||
},
|
||||
"contributors": [
|
||||
"bluefox <dogafox@gmail.com>",
|
||||
"hobbyquaker <hq@ccu.io>"
|
||||
],
|
||||
"homepage": "https://github.com/iobroker/iobroker.vis",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/iobroker/iobroker.vis"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "CC-BY-NC-4.0",
|
||||
"url": "https://github.com/iobroker/iobroker.vis/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"iobroker",
|
||||
"GUI",
|
||||
"DashUI",
|
||||
"web interface",
|
||||
"home automation",
|
||||
"SCADA"
|
||||
],
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^8.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-replace": "^1.0.0",
|
||||
"iobroker.web": "*",
|
||||
"mocha": "^5.2.0",
|
||||
"chai": "^4.1.2"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/iobroker/iobroker.vis/issues"
|
||||
},
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "node node_modules/mocha/bin/mocha --exit",
|
||||
"install": "node main.js --install"
|
||||
},
|
||||
"license": "CC-BY-NC-4.0"
|
||||
}
|
728
test/lib/setup.js
Normal file
@ -0,0 +1,728 @@
|
||||
/* jshint -W097 */// jshint strict:false
|
||||
/*jslint node: true */
|
||||
// check if tmp directory exists
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var child_process = require('child_process');
|
||||
var rootDir = path.normalize(__dirname + '/../../');
|
||||
var pkg = require(rootDir + 'package.json');
|
||||
var debug = typeof v8debug === 'object';
|
||||
pkg.main = pkg.main || 'main.js';
|
||||
|
||||
var adapterName = path.normalize(rootDir).replace(/\\/g, '/').split('/');
|
||||
adapterName = adapterName[adapterName.length - 2];
|
||||
var adapterStarted = false;
|
||||
|
||||
function getAppName() {
|
||||
var parts = __dirname.replace(/\\/g, '/').split('/');
|
||||
return parts[parts.length - 3].split('.')[0];
|
||||
}
|
||||
|
||||
var appName = getAppName().toLowerCase();
|
||||
|
||||
var objects;
|
||||
var states;
|
||||
|
||||
var pid = null;
|
||||
|
||||
function copyFileSync(source, target) {
|
||||
|
||||
var targetFile = target;
|
||||
|
||||
//if target is a directory a new file with the same name will be created
|
||||
if (fs.existsSync(target)) {
|
||||
if ( fs.lstatSync( target ).isDirectory() ) {
|
||||
targetFile = path.join(target, path.basename(source));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
fs.writeFileSync(targetFile, fs.readFileSync(source));
|
||||
}
|
||||
catch (err) {
|
||||
console.log("file copy error: " +source +" -> " + targetFile + " (error ignored)");
|
||||
}
|
||||
}
|
||||
|
||||
function copyFolderRecursiveSync(source, target, ignore) {
|
||||
var files = [];
|
||||
|
||||
var base = path.basename(source);
|
||||
if (base === adapterName) {
|
||||
base = pkg.name;
|
||||
}
|
||||
//check if folder needs to be created or integrated
|
||||
var targetFolder = path.join(target, base);
|
||||
if (!fs.existsSync(targetFolder)) {
|
||||
fs.mkdirSync(targetFolder);
|
||||
}
|
||||
|
||||
//copy
|
||||
if (fs.lstatSync(source).isDirectory()) {
|
||||
files = fs.readdirSync(source);
|
||||
files.forEach(function (file) {
|
||||
if (ignore && ignore.indexOf(file) !== -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var curSource = path.join(source, file);
|
||||
var curTarget = path.join(targetFolder, file);
|
||||
if (fs.lstatSync(curSource).isDirectory()) {
|
||||
// ignore grunt files
|
||||
if (file.indexOf('grunt') !== -1) return;
|
||||
if (file === 'chai') return;
|
||||
if (file === 'mocha') return;
|
||||
copyFolderRecursiveSync(curSource, targetFolder, ignore);
|
||||
} else {
|
||||
copyFileSync(curSource, curTarget);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(rootDir + 'tmp')) {
|
||||
fs.mkdirSync(rootDir + 'tmp');
|
||||
}
|
||||
|
||||
function storeOriginalFiles() {
|
||||
console.log('Store original files...');
|
||||
var dataDir = rootDir + 'tmp/' + appName + '-data/';
|
||||
|
||||
var f = fs.readFileSync(dataDir + 'objects.json');
|
||||
var objects = JSON.parse(f.toString());
|
||||
if (objects['system.adapter.admin.0'] && objects['system.adapter.admin.0'].common) {
|
||||
objects['system.adapter.admin.0'].common.enabled = false;
|
||||
}
|
||||
if (objects['system.adapter.admin.1'] && objects['system.adapter.admin.1'].common) {
|
||||
objects['system.adapter.admin.1'].common.enabled = false;
|
||||
}
|
||||
|
||||
fs.writeFileSync(dataDir + 'objects.json.original', JSON.stringify(objects));
|
||||
try {
|
||||
f = fs.readFileSync(dataDir + 'states.json');
|
||||
fs.writeFileSync(dataDir + 'states.json.original', f);
|
||||
}
|
||||
catch (err) {
|
||||
console.log('no states.json found - ignore');
|
||||
}
|
||||
}
|
||||
|
||||
function restoreOriginalFiles() {
|
||||
console.log('restoreOriginalFiles...');
|
||||
var dataDir = rootDir + 'tmp/' + appName + '-data/';
|
||||
|
||||
var f = fs.readFileSync(dataDir + 'objects.json.original');
|
||||
fs.writeFileSync(dataDir + 'objects.json', f);
|
||||
try {
|
||||
f = fs.readFileSync(dataDir + 'states.json.original');
|
||||
fs.writeFileSync(dataDir + 'states.json', f);
|
||||
}
|
||||
catch (err) {
|
||||
console.log('no states.json.original found - ignore');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function checkIsAdapterInstalled(cb, counter, customName) {
|
||||
customName = customName || pkg.name.split('.').pop();
|
||||
counter = counter || 0;
|
||||
var dataDir = rootDir + 'tmp/' + appName + '-data/';
|
||||
console.log('checkIsAdapterInstalled...');
|
||||
|
||||
try {
|
||||
var f = fs.readFileSync(dataDir + 'objects.json');
|
||||
var objects = JSON.parse(f.toString());
|
||||
if (objects['system.adapter.' + customName + '.0']) {
|
||||
console.log('checkIsAdapterInstalled: ready!');
|
||||
setTimeout(function () {
|
||||
if (cb) cb();
|
||||
}, 100);
|
||||
return;
|
||||
} else {
|
||||
console.warn('checkIsAdapterInstalled: still not ready');
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
|
||||
if (counter > 20) {
|
||||
console.error('checkIsAdapterInstalled: Cannot install!');
|
||||
if (cb) cb('Cannot install');
|
||||
} else {
|
||||
console.log('checkIsAdapterInstalled: wait...');
|
||||
setTimeout(function() {
|
||||
checkIsAdapterInstalled(cb, counter + 1);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function checkIsControllerInstalled(cb, counter) {
|
||||
counter = counter || 0;
|
||||
var dataDir = rootDir + 'tmp/' + appName + '-data/';
|
||||
|
||||
console.log('checkIsControllerInstalled...');
|
||||
try {
|
||||
var f = fs.readFileSync(dataDir + 'objects.json');
|
||||
var objects = JSON.parse(f.toString());
|
||||
if (objects['system.adapter.admin.0']) {
|
||||
console.log('checkIsControllerInstalled: installed!');
|
||||
setTimeout(function () {
|
||||
if (cb) cb();
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
|
||||
if (counter > 20) {
|
||||
console.log('checkIsControllerInstalled: Cannot install!');
|
||||
if (cb) cb('Cannot install');
|
||||
} else {
|
||||
console.log('checkIsControllerInstalled: wait...');
|
||||
setTimeout(function() {
|
||||
checkIsControllerInstalled(cb, counter + 1);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function installAdapter(customName, cb) {
|
||||
if (typeof customName === 'function') {
|
||||
cb = customName;
|
||||
customName = null;
|
||||
}
|
||||
customName = customName || pkg.name.split('.').pop();
|
||||
console.log('Install adapter...');
|
||||
var startFile = 'node_modules/' + appName + '.js-controller/' + appName + '.js';
|
||||
// make first install
|
||||
if (debug) {
|
||||
child_process.execSync('node ' + startFile + ' add ' + customName + ' --enabled false', {
|
||||
cwd: rootDir + 'tmp',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
checkIsAdapterInstalled(function (error) {
|
||||
if (error) console.error(error);
|
||||
console.log('Adapter installed.');
|
||||
if (cb) cb();
|
||||
});
|
||||
} else {
|
||||
// add controller
|
||||
var _pid = child_process.fork(startFile, ['add', customName, '--enabled', 'false'], {
|
||||
cwd: rootDir + 'tmp',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
|
||||
waitForEnd(_pid, function () {
|
||||
checkIsAdapterInstalled(function (error) {
|
||||
if (error) console.error(error);
|
||||
console.log('Adapter installed.');
|
||||
if (cb) cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function waitForEnd(_pid, cb) {
|
||||
if (!_pid) {
|
||||
cb(-1, -1);
|
||||
return;
|
||||
}
|
||||
_pid.on('exit', function (code, signal) {
|
||||
if (_pid) {
|
||||
_pid = null;
|
||||
cb(code, signal);
|
||||
}
|
||||
});
|
||||
_pid.on('close', function (code, signal) {
|
||||
if (_pid) {
|
||||
_pid = null;
|
||||
cb(code, signal);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function installJsController(cb) {
|
||||
console.log('installJsController...');
|
||||
if (!fs.existsSync(rootDir + 'tmp/node_modules/' + appName + '.js-controller') ||
|
||||
!fs.existsSync(rootDir + 'tmp/' + appName + '-data')) {
|
||||
// try to detect appName.js-controller in node_modules/appName.js-controller
|
||||
// travis CI installs js-controller into node_modules
|
||||
if (fs.existsSync(rootDir + 'node_modules/' + appName + '.js-controller')) {
|
||||
console.log('installJsController: no js-controller => copy it from "' + rootDir + 'node_modules/' + appName + '.js-controller"');
|
||||
// copy all
|
||||
// stop controller
|
||||
console.log('Stop controller if running...');
|
||||
var _pid;
|
||||
if (debug) {
|
||||
// start controller
|
||||
_pid = child_process.exec('node ' + appName + '.js stop', {
|
||||
cwd: rootDir + 'node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
} else {
|
||||
_pid = child_process.fork(appName + '.js', ['stop'], {
|
||||
cwd: rootDir + 'node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
}
|
||||
|
||||
waitForEnd(_pid, function () {
|
||||
// copy all files into
|
||||
if (!fs.existsSync(rootDir + 'tmp')) fs.mkdirSync(rootDir + 'tmp');
|
||||
if (!fs.existsSync(rootDir + 'tmp/node_modules')) fs.mkdirSync(rootDir + 'tmp/node_modules');
|
||||
|
||||
if (!fs.existsSync(rootDir + 'tmp/node_modules/' + appName + '.js-controller')){
|
||||
console.log('Copy js-controller...');
|
||||
copyFolderRecursiveSync(rootDir + 'node_modules/' + appName + '.js-controller', rootDir + 'tmp/node_modules/');
|
||||
}
|
||||
|
||||
console.log('Setup js-controller...');
|
||||
var __pid;
|
||||
if (debug) {
|
||||
// start controller
|
||||
_pid = child_process.exec('node ' + appName + '.js setup first --console', {
|
||||
cwd: rootDir + 'tmp/node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
} else {
|
||||
__pid = child_process.fork(appName + '.js', ['setup', 'first', '--console'], {
|
||||
cwd: rootDir + 'tmp/node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
}
|
||||
waitForEnd(__pid, function () {
|
||||
checkIsControllerInstalled(function () {
|
||||
// change ports for object and state DBs
|
||||
var config = require(rootDir + 'tmp/' + appName + '-data/' + appName + '.json');
|
||||
config.objects.port = 19001;
|
||||
config.states.port = 19000;
|
||||
fs.writeFileSync(rootDir + 'tmp/' + appName + '-data/' + appName + '.json', JSON.stringify(config, null, 2));
|
||||
console.log('Setup finished.');
|
||||
|
||||
copyAdapterToController();
|
||||
|
||||
installAdapter(function () {
|
||||
storeOriginalFiles();
|
||||
if (cb) cb(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// check if port 9000 is free, else admin adapter will be added to running instance
|
||||
var client = new require('net').Socket();
|
||||
client.connect(9000, '127.0.0.1', function() {
|
||||
console.error('Cannot initiate fisrt run of test, because one instance of application is running on this PC. Stop it and repeat.');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
client.destroy();
|
||||
if (!fs.existsSync(rootDir + 'tmp/node_modules/' + appName + '.js-controller')) {
|
||||
console.log('installJsController: no js-controller => install from git');
|
||||
|
||||
child_process.execSync('npm install https://github.com/' + appName + '/' + appName + '.js-controller/tarball/master --prefix ./ --production', {
|
||||
cwd: rootDir + 'tmp/',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
} else {
|
||||
console.log('Setup js-controller...');
|
||||
var __pid;
|
||||
if (debug) {
|
||||
// start controller
|
||||
child_process.exec('node ' + appName + '.js setup first', {
|
||||
cwd: rootDir + 'tmp/node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
} else {
|
||||
child_process.fork(appName + '.js', ['setup', 'first'], {
|
||||
cwd: rootDir + 'tmp/node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// let npm install admin and run setup
|
||||
checkIsControllerInstalled(function () {
|
||||
var _pid;
|
||||
|
||||
if (fs.existsSync(rootDir + 'node_modules/' + appName + '.js-controller/' + appName + '.js')) {
|
||||
_pid = child_process.fork(appName + '.js', ['stop'], {
|
||||
cwd: rootDir + 'node_modules/' + appName + '.js-controller',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
}
|
||||
|
||||
waitForEnd(_pid, function () {
|
||||
// change ports for object and state DBs
|
||||
var config = require(rootDir + 'tmp/' + appName + '-data/' + appName + '.json');
|
||||
config.objects.port = 19001;
|
||||
config.states.port = 19000;
|
||||
fs.writeFileSync(rootDir + 'tmp/' + appName + '-data/' + appName + '.json', JSON.stringify(config, null, 2));
|
||||
|
||||
copyAdapterToController();
|
||||
|
||||
installAdapter(function () {
|
||||
storeOriginalFiles();
|
||||
if (cb) cb(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
console.log('installJsController: js-controller installed');
|
||||
if (cb) cb(false);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function copyAdapterToController() {
|
||||
console.log('Copy adapter...');
|
||||
// Copy adapter to tmp/node_modules/appName.adapter
|
||||
copyFolderRecursiveSync(rootDir, rootDir + 'tmp/node_modules/', ['.idea', 'test', 'tmp', '.git', appName + '.js-controller']);
|
||||
console.log('Adapter copied.');
|
||||
}
|
||||
|
||||
function clearControllerLog() {
|
||||
var dirPath = rootDir + 'tmp/log';
|
||||
var files;
|
||||
try {
|
||||
if (fs.existsSync(dirPath)) {
|
||||
console.log('Clear controller log...');
|
||||
files = fs.readdirSync(dirPath);
|
||||
} else {
|
||||
console.log('Create controller log directory...');
|
||||
files = [];
|
||||
fs.mkdirSync(dirPath);
|
||||
}
|
||||
} catch(e) {
|
||||
console.error('Cannot read "' + dirPath + '"');
|
||||
return;
|
||||
}
|
||||
if (files.length > 0) {
|
||||
try {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var filePath = dirPath + '/' + files[i];
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
console.log('Controller log cleared');
|
||||
} catch (err) {
|
||||
console.error('cannot clear log: ' + err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearDB() {
|
||||
var dirPath = rootDir + 'tmp/iobroker-data/sqlite';
|
||||
var files;
|
||||
try {
|
||||
if (fs.existsSync(dirPath)) {
|
||||
console.log('Clear sqlite DB...');
|
||||
files = fs.readdirSync(dirPath);
|
||||
} else {
|
||||
console.log('Create controller log directory...');
|
||||
files = [];
|
||||
fs.mkdirSync(dirPath);
|
||||
}
|
||||
} catch(e) {
|
||||
console.error('Cannot read "' + dirPath + '"');
|
||||
return;
|
||||
}
|
||||
if (files.length > 0) {
|
||||
try {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var filePath = dirPath + '/' + files[i];
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
console.log('Clear sqlite DB');
|
||||
} catch (err) {
|
||||
console.error('cannot clear DB: ' + err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupController(cb) {
|
||||
installJsController(function (isInited) {
|
||||
clearControllerLog();
|
||||
clearDB();
|
||||
|
||||
if (!isInited) {
|
||||
restoreOriginalFiles();
|
||||
copyAdapterToController();
|
||||
}
|
||||
// read system.config object
|
||||
var dataDir = rootDir + 'tmp/' + appName + '-data/';
|
||||
|
||||
var objs;
|
||||
try {
|
||||
objs = fs.readFileSync(dataDir + 'objects.json');
|
||||
objs = JSON.parse(objs);
|
||||
}
|
||||
catch (e) {
|
||||
console.log('ERROR reading/parsing system configuration. Ignore');
|
||||
objs = {'system.config': {}};
|
||||
}
|
||||
if (!objs || !objs['system.config']) {
|
||||
objs = {'system.config': {}};
|
||||
}
|
||||
|
||||
if (cb) cb(objs['system.config']);
|
||||
});
|
||||
}
|
||||
|
||||
function startAdapter(objects, states, callback) {
|
||||
if (adapterStarted) {
|
||||
console.log('Adapter already started ...');
|
||||
if (callback) callback(objects, states);
|
||||
return;
|
||||
}
|
||||
adapterStarted = true;
|
||||
console.log('startAdapter...');
|
||||
if (fs.existsSync(rootDir + 'tmp/node_modules/' + pkg.name + '/' + pkg.main)) {
|
||||
try {
|
||||
if (debug) {
|
||||
// start controller
|
||||
pid = child_process.exec('node node_modules/' + pkg.name + '/' + pkg.main + ' --console silly', {
|
||||
cwd: rootDir + 'tmp',
|
||||
stdio: [0, 1, 2]
|
||||
});
|
||||
} else {
|
||||
// start controller
|
||||
pid = child_process.fork('node_modules/' + pkg.name + '/' + pkg.main, ['--console', 'silly'], {
|
||||
cwd: rootDir + 'tmp',
|
||||
stdio: [0, 1, 2, 'ipc']
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(JSON.stringify(error));
|
||||
}
|
||||
} else {
|
||||
console.error('Cannot find: ' + rootDir + 'tmp/node_modules/' + pkg.name + '/' + pkg.main);
|
||||
}
|
||||
if (callback) callback(objects, states);
|
||||
}
|
||||
|
||||
function startController(isStartAdapter, onObjectChange, onStateChange, callback) {
|
||||
if (typeof isStartAdapter === 'function') {
|
||||
callback = onStateChange;
|
||||
onStateChange = onObjectChange;
|
||||
onObjectChange = isStartAdapter;
|
||||
isStartAdapter = true;
|
||||
}
|
||||
|
||||
if (onStateChange === undefined) {
|
||||
callback = onObjectChange;
|
||||
onObjectChange = undefined;
|
||||
}
|
||||
|
||||
if (pid) {
|
||||
console.error('Controller is already started!');
|
||||
} else {
|
||||
console.log('startController...');
|
||||
adapterStarted = false;
|
||||
var isObjectConnected;
|
||||
var isStatesConnected;
|
||||
|
||||
var Objects = require(rootDir + 'tmp/node_modules/' + appName + '.js-controller/lib/objects/objectsInMemServer');
|
||||
objects = new Objects({
|
||||
connection: {
|
||||
"type" : "file",
|
||||
"host" : "127.0.0.1",
|
||||
"port" : 19001,
|
||||
"user" : "",
|
||||
"pass" : "",
|
||||
"noFileCache": false,
|
||||
"connectTimeout": 2000
|
||||
},
|
||||
logger: {
|
||||
silly: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
debug: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
info: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
warn: function (msg) {
|
||||
console.warn(msg);
|
||||
},
|
||||
error: function (msg) {
|
||||
console.error(msg);
|
||||
}
|
||||
},
|
||||
connected: function () {
|
||||
isObjectConnected = true;
|
||||
if (isStatesConnected) {
|
||||
console.log('startController: started!');
|
||||
if (isStartAdapter) {
|
||||
startAdapter(objects, states, callback);
|
||||
} else {
|
||||
if (callback) {
|
||||
callback(objects, states);
|
||||
callback = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
change: onObjectChange
|
||||
});
|
||||
|
||||
// Just open in memory DB itself
|
||||
var States = require(rootDir + 'tmp/node_modules/' + appName + '.js-controller/lib/states/statesInMemServer');
|
||||
states = new States({
|
||||
connection: {
|
||||
type: 'file',
|
||||
host: '127.0.0.1',
|
||||
port: 19000,
|
||||
options: {
|
||||
auth_pass: null,
|
||||
retry_max_delay: 15000
|
||||
}
|
||||
},
|
||||
logger: {
|
||||
silly: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
debug: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
info: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
warn: function (msg) {
|
||||
console.log(msg);
|
||||
},
|
||||
error: function (msg) {
|
||||
console.log(msg);
|
||||
}
|
||||
},
|
||||
connected: function () {
|
||||
isStatesConnected = true;
|
||||
if (isObjectConnected) {
|
||||
console.log('startController: started!!');
|
||||
if (isStartAdapter) {
|
||||
startAdapter(objects, states, callback);
|
||||
} else {
|
||||
if (callback) {
|
||||
callback(objects, states);
|
||||
callback = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
change: onStateChange
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function stopAdapter(cb) {
|
||||
if (!pid) {
|
||||
console.error('Controller is not running!');
|
||||
if (cb) {
|
||||
setTimeout(function () {
|
||||
cb(false);
|
||||
}, 0);
|
||||
}
|
||||
} else {
|
||||
adapterStarted = false;
|
||||
pid.on('exit', function (code, signal) {
|
||||
if (pid) {
|
||||
console.log('child process terminated due to receipt of signal ' + signal);
|
||||
if (cb) cb();
|
||||
pid = null;
|
||||
}
|
||||
});
|
||||
|
||||
pid.on('close', function (code, signal) {
|
||||
if (pid) {
|
||||
if (cb) cb();
|
||||
pid = null;
|
||||
}
|
||||
});
|
||||
|
||||
pid.kill('SIGTERM');
|
||||
}
|
||||
}
|
||||
|
||||
function _stopController() {
|
||||
if (objects) {
|
||||
objects.destroy();
|
||||
objects = null;
|
||||
}
|
||||
if (states) {
|
||||
states.destroy();
|
||||
states = null;
|
||||
}
|
||||
}
|
||||
|
||||
function stopController(cb) {
|
||||
var timeout;
|
||||
if (objects) {
|
||||
console.log('Set system.adapter.' + pkg.name + '.0');
|
||||
objects.setObject('system.adapter.' + pkg.name + '.0', {
|
||||
common:{
|
||||
enabled: false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stopAdapter(function () {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
|
||||
_stopController();
|
||||
|
||||
if (cb) {
|
||||
cb(true);
|
||||
cb = null;
|
||||
}
|
||||
});
|
||||
|
||||
timeout = setTimeout(function () {
|
||||
timeout = null;
|
||||
console.log('child process NOT terminated');
|
||||
|
||||
_stopController();
|
||||
|
||||
if (cb) {
|
||||
cb(false);
|
||||
cb = null;
|
||||
}
|
||||
pid = null;
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// Setup the adapter
|
||||
function setAdapterConfig(common, native, instance) {
|
||||
var objects = JSON.parse(fs.readFileSync(rootDir + 'tmp/' + appName + '-data/objects.json').toString());
|
||||
var id = 'system.adapter.' + adapterName.split('.').pop() + '.' + (instance || 0);
|
||||
if (common) objects[id].common = common;
|
||||
if (native) objects[id].native = native;
|
||||
fs.writeFileSync(rootDir + 'tmp/' + appName + '-data/objects.json', JSON.stringify(objects));
|
||||
}
|
||||
|
||||
// Read config of the adapter
|
||||
function getAdapterConfig(instance) {
|
||||
var objects = JSON.parse(fs.readFileSync(rootDir + 'tmp/' + appName + '-data/objects.json').toString());
|
||||
var id = 'system.adapter.' + adapterName.split('.').pop() + '.' + (instance || 0);
|
||||
return objects[id];
|
||||
}
|
||||
|
||||
if (typeof module !== undefined && module.parent) {
|
||||
module.exports.getAdapterConfig = getAdapterConfig;
|
||||
module.exports.setAdapterConfig = setAdapterConfig;
|
||||
module.exports.startController = startController;
|
||||
module.exports.stopController = stopController;
|
||||
module.exports.setupController = setupController;
|
||||
module.exports.stopAdapter = stopAdapter;
|
||||
module.exports.startAdapter = startAdapter;
|
||||
module.exports.installAdapter = installAdapter;
|
||||
module.exports.appName = appName;
|
||||
module.exports.adapterName = adapterName;
|
||||
module.exports.adapterStarted = adapterStarted;
|
||||
}
|
142
test/testAdapter.js
Normal file
@ -0,0 +1,142 @@
|
||||
/* jshint -W097 */// jshint strict:false
|
||||
/*jslint node: true */
|
||||
var expect = require('chai').expect;
|
||||
var setup = require(__dirname + '/lib/setup');
|
||||
|
||||
var objects = null;
|
||||
var states = null;
|
||||
var onStateChanged = null;
|
||||
var onObjectChanged = null;
|
||||
var sendToID = 1;
|
||||
|
||||
var adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.') + 1);
|
||||
var runningMode = require(__dirname + '/../io-package.json').common.mode;
|
||||
|
||||
function checkConnectionOfAdapter(cb, counter) {
|
||||
counter = counter || 0;
|
||||
console.log('Try check #' + counter);
|
||||
if (counter > 30) {
|
||||
if (cb) cb('Cannot check connection');
|
||||
return;
|
||||
}
|
||||
|
||||
states.getState('system.adapter.' + adapterShortName + '.0.alive', function (err, state) {
|
||||
if (err) console.error(err);
|
||||
if (state && state.val) {
|
||||
if (cb) cb();
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
checkConnectionOfAdapter(cb, counter + 1);
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkValueOfState(id, value, cb, counter) {
|
||||
counter = counter || 0;
|
||||
if (counter > 20) {
|
||||
if (cb) cb('Cannot check value Of State ' + id);
|
||||
return;
|
||||
}
|
||||
|
||||
states.getState(id, function (err, state) {
|
||||
if (err) console.error(err);
|
||||
if (value === null && !state) {
|
||||
if (cb) cb();
|
||||
} else
|
||||
if (state && (value === undefined || state.val === value)) {
|
||||
if (cb) cb();
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
checkValueOfState(id, value, cb, counter + 1);
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendTo(target, command, message, callback) {
|
||||
onStateChanged = function (id, state) {
|
||||
if (id === 'messagebox.system.adapter.test.0') {
|
||||
callback(state.message);
|
||||
}
|
||||
};
|
||||
|
||||
states.pushMessage('system.adapter.' + target, {
|
||||
command: command,
|
||||
message: message,
|
||||
from: 'system.adapter.test.0',
|
||||
callback: {
|
||||
message: message,
|
||||
id: sendToID++,
|
||||
ack: false,
|
||||
time: (new Date()).getTime()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('Test ' + adapterShortName + ' adapter', function() {
|
||||
before('Test ' + adapterShortName + ' adapter: Start js-controller', function (_done) {
|
||||
this.timeout(600000); // because of first install from npm
|
||||
|
||||
setup.setupController(function () {
|
||||
var config = setup.getAdapterConfig();
|
||||
// enable adapter
|
||||
config.common.enabled = true;
|
||||
config.common.loglevel = 'debug';
|
||||
|
||||
//config.native.dbtype = 'sqlite';
|
||||
|
||||
setup.setAdapterConfig(config.common, config.native);
|
||||
|
||||
setup.startController(true, function(id, obj) {}, function (id, state) {
|
||||
if (onStateChanged) onStateChanged(id, state);
|
||||
},
|
||||
function (_objects, _states) {
|
||||
objects = _objects;
|
||||
states = _states;
|
||||
_done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Test ' + adapterShortName + ' instance object: it must exists', function (done) {
|
||||
objects.getObject('system.adapter.' + adapterShortName + '.0', function (err, obj) {
|
||||
expect(err).to.be.null;
|
||||
expect(obj).to.be.an('object');
|
||||
expect(obj).not.to.be.null;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Test ' + adapterShortName + ' adapter: Check if adapter started', function (done) {
|
||||
this.timeout(60000);
|
||||
checkConnectionOfAdapter(function (res) {
|
||||
if (res) console.log(res);
|
||||
if (runningMode === 'daemon') {
|
||||
expect(res).not.to.be.equal('Cannot check connection');
|
||||
} else {
|
||||
//??
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
/**/
|
||||
|
||||
/*
|
||||
PUT YOUR OWN TESTS HERE USING
|
||||
it('Testname', function ( done) {
|
||||
...
|
||||
});
|
||||
|
||||
You can also use "sendTo" method to send messages to the started adapter
|
||||
*/
|
||||
|
||||
after('Test ' + adapterShortName + ' adapter: Stop js-controller', function (done) {
|
||||
this.timeout(10000);
|
||||
|
||||
setup.stopController(function (normalTerminated) {
|
||||
console.log('Adapter normal terminated: ' + normalTerminated);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
91
test/testPackageFiles.js
Normal file
@ -0,0 +1,91 @@
|
||||
/* jshint -W097 */
|
||||
/* jshint strict:false */
|
||||
/* jslint node: true */
|
||||
/* jshint expr: true */
|
||||
var expect = require('chai').expect;
|
||||
var fs = require('fs');
|
||||
|
||||
describe('Test package.json and io-package.json', function() {
|
||||
it('Test package files', function (done) {
|
||||
console.log();
|
||||
|
||||
var fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8');
|
||||
var ioPackage = JSON.parse(fileContentIOPackage);
|
||||
|
||||
var fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8');
|
||||
var npmPackage = JSON.parse(fileContentNPMPackage);
|
||||
|
||||
expect(ioPackage).to.be.an('object');
|
||||
expect(npmPackage).to.be.an('object');
|
||||
|
||||
expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist;
|
||||
expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist;
|
||||
|
||||
expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version);
|
||||
|
||||
if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) {
|
||||
console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!');
|
||||
console.log();
|
||||
}
|
||||
|
||||
expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist;
|
||||
expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist;
|
||||
|
||||
if (ioPackage.common.name.indexOf('template') !== 0) {
|
||||
if (Array.isArray(ioPackage.common.authors)) {
|
||||
expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0);
|
||||
if (ioPackage.common.authors.length === 1) {
|
||||
expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
|
||||
}
|
||||
}
|
||||
else {
|
||||
expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name <my@email.com>');
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('WARNING: Testing for set authors field in io-package skipped because template adapter');
|
||||
console.log();
|
||||
}
|
||||
expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true;
|
||||
if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') {
|
||||
console.log('WARNING: titleLang is not existing in io-package.json. Please add');
|
||||
console.log();
|
||||
}
|
||||
if (
|
||||
ioPackage.common.title.indexOf('iobroker') !== -1 ||
|
||||
ioPackage.common.title.indexOf('ioBroker') !== -1 ||
|
||||
ioPackage.common.title.indexOf('adapter') !== -1 ||
|
||||
ioPackage.common.title.indexOf('Adapter') !== -1
|
||||
) {
|
||||
console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.');
|
||||
console.log();
|
||||
}
|
||||
|
||||
if (ioPackage.common.name.indexOf('vis-') !== 0) {
|
||||
if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) {
|
||||
console.log('WARNING: Admin3 support is missing! Please add it');
|
||||
console.log();
|
||||
}
|
||||
if (ioPackage.common.materialize) {
|
||||
expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true;
|
||||
}
|
||||
}
|
||||
|
||||
var licenseFileExists = fs.existsSync(__dirname + '/../LICENSE');
|
||||
var fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8');
|
||||
if (fileContentReadme.indexOf('## Changelog') === -1) {
|
||||
console.log('Warning: The README.md should have a section ## Changelog');
|
||||
console.log();
|
||||
}
|
||||
expect((licenseFileExists || fileContentReadme.indexOf('## License') !== -1), 'A LICENSE must exist as LICENSE file or as part of the README.md').to.be.true;
|
||||
if (!licenseFileExists) {
|
||||
console.log('Warning: The License should also exist as LICENSE file');
|
||||
console.log();
|
||||
}
|
||||
if (fileContentReadme.indexOf('## License') === -1) {
|
||||
console.log('Warning: The README.md should also have a section ## License to be shown in Admin3');
|
||||
console.log();
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
18
www/cache.manifest
Normal file
@ -0,0 +1,18 @@
|
||||
CACHE MANIFEST
|
||||
#
|
||||
# vis Version 1.1.7
|
||||
# dev build 0
|
||||
|
||||
|
||||
|
||||
NETWORK:
|
||||
*
|
||||
|
||||
|
||||
CACHE:
|
||||
./img/disconnect.png
|
||||
|
||||
FALLBACK:
|
||||
./index.html ./offline.html
|
||||
./edit.html ./offline.html
|
||||
|
1
www/cordova.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// do nothing
|
36
www/css/add_kian.css
Normal file
@ -0,0 +1,36 @@
|
||||
.ui-slider-vertical {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.ui-slider-horizontal {
|
||||
width: 93%;
|
||||
}
|
||||
|
||||
.ui-tabs-panel {
|
||||
margin-top: 1px !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar {
|
||||
margin: 5px !important;
|
||||
}
|
||||
|
||||
.dashui-steal-label {
|
||||
width: 0 !important;
|
||||
height: 10px !important;
|
||||
top: 5px !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
#css_view_inspector, #export_view, #import_view {
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
button.ui-dialog-titlebar-close {
|
||||
right: -22px !important;
|
||||
top: -8px !important;
|
||||
}
|
||||
|
||||
.vis-editor-dialog button.ui-dialog-titlebar-close {
|
||||
right: -5px !important;
|
||||
top: -1px !important;
|
||||
}
|
0
www/css/app.css
Normal file
522
www/css/backgrounds.css
Normal file
@ -0,0 +1,522 @@
|
||||
/* ------------------------ Backgrounds styles ---------------------------*/
|
||||
.hq-background-blue-marine-lines
|
||||
{
|
||||
background-image: url(../img/back/oblique-line-bk.png);
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyYWRpYWxHcmFkaWVudCBpZD0iZyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjNDI4Q0JEIi8+PHN0b3Agb2Zmc2V0PSIwLjIiIHN0b3AtY29sb3I9IiMyNzYyODYiLz48c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiMyMjRlNzIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAzMjkiLz48L3JhZGlhbEdyYWRpZW50PjxyZWN0IHg9IjAlIiB5PSIwJSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iIzAwMDMyOSIgLz48cmVjdCB4PSIwJSIgeT0iLTg5cHgiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjIxMC44MiUiIGZpbGw9InVybCgjZykiIC8+PC9zdmc+);
|
||||
background-image: url(../img/back/oblique-line-bk.png), -webkit-gradient(radial,50% 350,0,50% 350,156,color-stop(0%,#428CBD),color-stop(20%,#276286),color-stop(33%,#224e72),color-stop(100%,#000329));
|
||||
background-image:-webkit-radial-gradient(center 350px,50% 105.41%,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: url(../img/back/oblique-line-bk.png), -moz-radial-gradient(center 350px,circle,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: url(../img/back/oblique-line-bk.png), -ms-radial-gradient(center 350px,circle,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image:-o-radial-gradient(center 350px,50% 105.41%,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: url(../img/back/oblique-line-bk.png), radial-gradient(50% 105.41% at center 350px,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
}
|
||||
.hq-background-blue-marine
|
||||
{
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyYWRpYWxHcmFkaWVudCBpZD0iZyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjNDI4Q0JEIi8+PHN0b3Agb2Zmc2V0PSIwLjIiIHN0b3AtY29sb3I9IiMyNzYyODYiLz48c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiMyMjRlNzIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAzMjkiLz48L3JhZGlhbEdyYWRpZW50PjxyZWN0IHg9IjAlIiB5PSIwJSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iIzAwMDMyOSIgLz48cmVjdCB4PSIwJSIgeT0iLTg5cHgiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjIxMC44MiUiIGZpbGw9InVybCgjZykiIC8+PC9zdmc+);
|
||||
background-image: -webkit-gradient(radial,50% 350,0,50% 350,156,color-stop(0%,#428CBD),color-stop(20%,#276286),color-stop(33%,#224e72),color-stop(100%,#000329));
|
||||
background-image:-webkit-radial-gradient(center 350px,50% 105.41%,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: -moz-radial-gradient(center 350px,circle,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: -ms-radial-gradient(center 350px,circle,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image:-o-radial-gradient(center 350px,50% 105.41%,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
background-image: radial-gradient(50% 105.41% at center 350px,#428CBD 0,#276286 20%,#224e72 33%,#000329 100%);
|
||||
}
|
||||
.hq-background-radial-blue
|
||||
{
|
||||
background: rgb(160,199,229);
|
||||
background: -moz-linear-gradient(left, rgba(160,199,229,1) 1%, rgba(179,206,226,1) 46%, rgba(192,211,224,1) 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(1%,rgba(160,199,229,1)), color-stop(46%,rgba(179,206,226,1)), color-stop(100%,rgba(192,211,224,1)));
|
||||
background: -webkit-linear-gradient(left, rgba(160,199,229,1) 1%,rgba(179,206,226,1) 46%,rgba(192,211,224,1) 100%);
|
||||
background: -o-linear-gradient(left, rgba(160,199,229,1) 1%,rgba(179,206,226,1) 46%,rgba(192,211,224,1) 100%);
|
||||
background: -ms-linear-gradient(left, rgba(160,199,229,1) 1%,rgba(179,206,226,1) 46%,rgba(192,211,224,1) 100%);
|
||||
background: linear-gradient(left, rgba(160,199,229,1) 1%,rgba(179,206,226,1) 46%,rgba(192,211,224,1) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a0c7e5', endColorstr='#c0d3e0',GradientType=1 );
|
||||
}
|
||||
.hq-background-gradient-box
|
||||
{
|
||||
margin:0 0 16px 0;
|
||||
background-color:#e5edf6;
|
||||
background-image:url(../img/back/box-radial.png);
|
||||
background-position:0 0;
|
||||
background-repeat:no-repeat;
|
||||
border-top:1px solid #c7d1dc;
|
||||
border-right:1px solid #c8d2dd;
|
||||
border-bottom:1px solid #ced9e4;
|
||||
border-left:1px solid #c8d2dd
|
||||
}
|
||||
.hq-background-h-gradient-black-0
|
||||
{
|
||||
background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0.65) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.65))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#a6000000',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-black-1
|
||||
{
|
||||
background: -moz-linear-gradient(top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0.65)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6000000', endColorstr='#00000000',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-black-2
|
||||
{
|
||||
background: rgb(181,189,200); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(181,189,200,1) 0%, rgba(130,140,149,1) 36%, rgba(40,52,59,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(181,189,200,1)), color-stop(36%,rgba(130,140,149,1)), color-stop(100%,rgba(40,52,59,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b5bdc8', endColorstr='#28343b',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
}
|
||||
.hq-background-h-gradient-black-3
|
||||
{
|
||||
background: rgb(40,52,59); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(40,52,59,1) 0%, rgba(130,140,149,1) 64%, rgba(181,189,200,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(40,52,59,1)), color-stop(64%,rgba(130,140,149,1)), color-stop(100%,rgba(181,189,200,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(40,52,59,1) 0%,rgba(130,140,149,1) 64%,rgba(181,189,200,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(40,52,59,1) 0%,rgba(130,140,149,1) 64%,rgba(181,189,200,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(40,52,59,1) 0%,rgba(130,140,149,1) 64%,rgba(181,189,200,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(40,52,59,1) 0%,rgba(130,140,149,1) 64%,rgba(181,189,200,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#28343b', endColorstr='#b5bdc8',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-black-4
|
||||
{
|
||||
background: rgb(69,72,77); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(69,72,77,1) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(69,72,77,1)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(69,72,77,1) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(69,72,77,1) 0%,rgba(0,0,0,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(69,72,77,1) 0%,rgba(0,0,0,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(69,72,77,1) 0%,rgba(0,0,0,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#45484d', endColorstr='#000000',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
}
|
||||
.hq-background-h-gradient-black-5
|
||||
{
|
||||
background: rgb(0,0,0); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(0,0,0,1) 0%, rgba(69,72,77,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,1)), color-stop(100%,rgba(69,72,77,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(69,72,77,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(69,72,77,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(69,72,77,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(69,72,77,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#45484d',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-orange-0
|
||||
{
|
||||
background: rgb(250,198,149); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(250,198,149,1) 0%, rgba(245,171,102,1) 47%, rgba(239,141,49,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(250,198,149,1)), color-stop(47%,rgba(245,171,102,1)), color-stop(100%,rgba(239,141,49,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(250,198,149,1) 0%,rgba(245,171,102,1) 47%,rgba(239,141,49,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(250,198,149,1) 0%,rgba(245,171,102,1) 47%,rgba(239,141,49,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(250,198,149,1) 0%,rgba(245,171,102,1) 47%,rgba(239,141,49,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(250,198,149,1) 0%,rgba(245,171,102,1) 47%,rgba(239,141,49,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fac695', endColorstr='#ef8d31',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-orange-1
|
||||
{
|
||||
background: rgb(239,141,49); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(239,141,49,1) 0%, rgba(245,171,102,1) 53%, rgba(250,198,149,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(239,141,49,1)), color-stop(53%,rgba(245,171,102,1)), color-stop(100%,rgba(250,198,149,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(239,141,49,1) 0%,rgba(245,171,102,1) 53%,rgba(250,198,149,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(239,141,49,1) 0%,rgba(245,171,102,1) 53%,rgba(250,198,149,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(239,141,49,1) 0%,rgba(245,171,102,1) 53%,rgba(250,198,149,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(239,141,49,1) 0%,rgba(245,171,102,1) 53%,rgba(250,198,149,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ef8d31', endColorstr='#fac695',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-orange-2
|
||||
{
|
||||
background: rgb(255,168,76); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(255,168,76,1) 0%, rgba(255,123,13,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,168,76,1)), color-stop(100%,rgba(255,123,13,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(255,168,76,1) 0%,rgba(255,123,13,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(255,168,76,1) 0%,rgba(255,123,13,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(255,168,76,1) 0%,rgba(255,123,13,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(255,168,76,1) 0%,rgba(255,123,13,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffa84c', endColorstr='#ff7b0d',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
}
|
||||
.hq-background-h-gradient-orange-3
|
||||
{
|
||||
background: rgb(255,123,13); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(255,123,13,1) 0%, rgba(255,168,76,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,123,13,1)), color-stop(100%,rgba(255,168,76,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(255,123,13,1) 0%,rgba(255,168,76,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(255,123,13,1) 0%,rgba(255,168,76,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(255,123,13,1) 0%,rgba(255,168,76,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(255,123,13,1) 0%,rgba(255,168,76,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff7b0d', endColorstr='#ffa84c',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-0
|
||||
{
|
||||
background: rgb(240,249,255); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(240,249,255,1) 0%, rgba(203,235,255,1) 47%, rgba(161,219,255,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(240,249,255,1)), color-stop(47%,rgba(203,235,255,1)), color-stop(100%,rgba(161,219,255,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f0f9ff', endColorstr='#a1dbff',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-1
|
||||
{
|
||||
background: rgb(161,219,255); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(161,219,255,1) 0%, rgba(203,235,255,1) 53%, rgba(240,249,255,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(161,219,255,1)), color-stop(53%,rgba(203,235,255,1)), color-stop(100%,rgba(240,249,255,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(161,219,255,1) 0%,rgba(203,235,255,1) 53%,rgba(240,249,255,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(161,219,255,1) 0%,rgba(203,235,255,1) 53%,rgba(240,249,255,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(161,219,255,1) 0%,rgba(203,235,255,1) 53%,rgba(240,249,255,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(161,219,255,1) 0%,rgba(203,235,255,1) 53%,rgba(240,249,255,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a1dbff', endColorstr='#f0f9ff',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-2
|
||||
{
|
||||
background: rgb(184,198,223); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(184,198,223,1) 0%, rgba(109,136,183,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(184,198,223,1)), color-stop(100%,rgba(109,136,183,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(184,198,223,1) 0%,rgba(109,136,183,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(184,198,223,1) 0%,rgba(109,136,183,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(184,198,223,1) 0%,rgba(109,136,183,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(184,198,223,1) 0%,rgba(109,136,183,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b8c6df', endColorstr='#6d88b7',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-3
|
||||
{
|
||||
background: rgb(109,136,183); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(109,136,183,1) 0%, rgba(184,198,223,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(109,136,183,1)), color-stop(100%,rgba(184,198,223,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(109,136,183,1) 0%,rgba(184,198,223,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(109,136,183,1) 0%,rgba(184,198,223,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(109,136,183,1) 0%,rgba(184,198,223,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(109,136,183,1) 0%,rgba(184,198,223,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6d88b7', endColorstr='#b8c6df',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-4
|
||||
{
|
||||
background: rgb(207,231,250); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(207,231,250,1) 0%, rgba(99,147,193,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(207,231,250,1)), color-stop(100%,rgba(99,147,193,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cfe7fa', endColorstr='#6393c1',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-5
|
||||
{
|
||||
background: rgb(99,147,193); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(99,147,193,1) 0%, rgba(207,231,250,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(99,147,193,1)), color-stop(100%,rgba(207,231,250,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(99,147,193,1) 0%,rgba(207,231,250,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(99,147,193,1) 0%,rgba(207,231,250,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(99,147,193,1) 0%,rgba(207,231,250,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(99,147,193,1) 0%,rgba(207,231,250,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6393c1', endColorstr='#cfe7fa',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-6
|
||||
{
|
||||
background: rgb(167,207,223); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(167,207,223,1) 0%, rgba(35,83,138,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(167,207,223,1)), color-stop(100%,rgba(35,83,138,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(167,207,223,1) 0%,rgba(35,83,138,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(167,207,223,1) 0%,rgba(35,83,138,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(167,207,223,1) 0%,rgba(35,83,138,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(167,207,223,1) 0%,rgba(35,83,138,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a7cfdf', endColorstr='#23538a',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-blue-7
|
||||
{
|
||||
background: rgb(35,83,138); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(35,83,138,1) 0%, rgba(167,207,223,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(35,83,138,1)), color-stop(100%,rgba(167,207,223,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(35,83,138,1) 0%,rgba(167,207,223,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(35,83,138,1) 0%,rgba(167,207,223,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(35,83,138,1) 0%,rgba(167,207,223,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(35,83,138,1) 0%,rgba(167,207,223,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#23538a', endColorstr='#a7cfdf',GradientType=0 ); /* IE6-9 */
|
||||
|
||||
}
|
||||
.hq-background-h-gradient-yellow-0
|
||||
{
|
||||
background: rgb(254,252,234); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(254,252,234,1) 0%, rgba(241,218,54,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,1)), color-stop(100%,rgba(241,218,54,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefcea', endColorstr='#f1da36',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-yellow-1
|
||||
{
|
||||
background: rgb(241,218,54); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(241,218,54,1) 0%, rgba(254,252,234,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(241,218,54,1)), color-stop(100%,rgba(254,252,234,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f1da36', endColorstr='#fefcea',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-yellow-2
|
||||
{
|
||||
background: rgb(241,231,103); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(241,231,103,1) 0%, rgba(254,182,69,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(241,231,103,1)), color-stop(100%,rgba(254,182,69,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(241,231,103,1) 0%,rgba(254,182,69,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(241,231,103,1) 0%,rgba(254,182,69,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(241,231,103,1) 0%,rgba(254,182,69,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(241,231,103,1) 0%,rgba(254,182,69,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f1e767', endColorstr='#feb645',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-yellow-3
|
||||
{
|
||||
background: rgb(254,182,69); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(254,182,69,1) 0%, rgba(241,231,103,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,182,69,1)), color-stop(100%,rgba(241,231,103,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(254,182,69,1) 0%,rgba(241,231,103,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(254,182,69,1) 0%,rgba(241,231,103,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(254,182,69,1) 0%,rgba(241,231,103,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(254,182,69,1) 0%,rgba(241,231,103,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feb645', endColorstr='#f1e767',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-green-0
|
||||
{
|
||||
background: rgb(180,221,180); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(180,221,180,1) 0%, rgba(131,199,131,1) 17%, rgba(82,177,82,1) 33%, rgba(0,138,0,1) 67%, rgba(0,87,0,1) 83%, rgba(0,36,0,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(180,221,180,1)), color-stop(17%,rgba(131,199,131,1)), color-stop(33%,rgba(82,177,82,1)), color-stop(67%,rgba(0,138,0,1)), color-stop(83%,rgba(0,87,0,1)), color-stop(100%,rgba(0,36,0,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(180,221,180,1) 0%,rgba(131,199,131,1) 17%,rgba(82,177,82,1) 33%,rgba(0,138,0,1) 67%,rgba(0,87,0,1) 83%,rgba(0,36,0,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(180,221,180,1) 0%,rgba(131,199,131,1) 17%,rgba(82,177,82,1) 33%,rgba(0,138,0,1) 67%,rgba(0,87,0,1) 83%,rgba(0,36,0,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(180,221,180,1) 0%,rgba(131,199,131,1) 17%,rgba(82,177,82,1) 33%,rgba(0,138,0,1) 67%,rgba(0,87,0,1) 83%,rgba(0,36,0,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(180,221,180,1) 0%,rgba(131,199,131,1) 17%,rgba(82,177,82,1) 33%,rgba(0,138,0,1) 67%,rgba(0,87,0,1) 83%,rgba(0,36,0,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b4ddb4', endColorstr='#002400',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-green-1
|
||||
{
|
||||
background: rgb(0,36,0); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(0,36,0,1) 0%, rgba(0,87,0,1) 17%, rgba(0,138,0,1) 33%, rgba(82,177,82,1) 67%, rgba(131,199,131,1) 83%, rgba(180,221,180,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,36,0,1)), color-stop(17%,rgba(0,87,0,1)), color-stop(33%,rgba(0,138,0,1)), color-stop(67%,rgba(82,177,82,1)), color-stop(83%,rgba(131,199,131,1)), color-stop(100%,rgba(180,221,180,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(0,36,0,1) 0%,rgba(0,87,0,1) 17%,rgba(0,138,0,1) 33%,rgba(82,177,82,1) 67%,rgba(131,199,131,1) 83%,rgba(180,221,180,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(0,36,0,1) 0%,rgba(0,87,0,1) 17%,rgba(0,138,0,1) 33%,rgba(82,177,82,1) 67%,rgba(131,199,131,1) 83%,rgba(180,221,180,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(0,36,0,1) 0%,rgba(0,87,0,1) 17%,rgba(0,138,0,1) 33%,rgba(82,177,82,1) 67%,rgba(131,199,131,1) 83%,rgba(180,221,180,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(0,36,0,1) 0%,rgba(0,87,0,1) 17%,rgba(0,138,0,1) 33%,rgba(82,177,82,1) 67%,rgba(131,199,131,1) 83%,rgba(180,221,180,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#002400', endColorstr='#b4ddb4',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-green-2
|
||||
{
|
||||
background: rgb(205,235,142); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(205,235,142,1) 0%, rgba(165,201,86,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(205,235,142,1)), color-stop(100%,rgba(165,201,86,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(205,235,142,1) 0%,rgba(165,201,86,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(205,235,142,1) 0%,rgba(165,201,86,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(205,235,142,1) 0%,rgba(165,201,86,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(205,235,142,1) 0%,rgba(165,201,86,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cdeb8e', endColorstr='#a5c956',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-green-3
|
||||
{
|
||||
background: rgb(165,201,86); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(165,201,86,1) 0%, rgba(205,235,142,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(165,201,86,1)), color-stop(100%,rgba(205,235,142,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a5c956', endColorstr='#cdeb8e',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-green-4
|
||||
{
|
||||
background: rgb(254,254,253); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(254,254,253,1) 0%, rgba(220,227,196,1) 42%, rgba(174,191,118,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,254,253,1)), color-stop(42%,rgba(220,227,196,1)), color-stop(100%,rgba(174,191,118,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefefd', endColorstr='#aebf76',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-gray-0
|
||||
{
|
||||
background: rgb(63,76,107); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(63,76,107,1) 0%, rgba(63,76,107,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(63,76,107,1)), color-stop(100%,rgba(63,76,107,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(63,76,107,1) 0%,rgba(63,76,107,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(63,76,107,1) 0%,rgba(63,76,107,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(63,76,107,1) 0%,rgba(63,76,107,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(63,76,107,1) 0%,rgba(63,76,107,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3f4c6b', endColorstr='#3f4c6b',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-gray-1
|
||||
{
|
||||
background: rgb(238,238,238); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(238,238,238,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(238,238,238,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(238,238,238,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(238,238,238,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(238,238,238,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(238,238,238,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#eeeeee',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-0
|
||||
{
|
||||
background: rgb(206,220,231); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(206,220,231,1) 0%, rgba(89,106,114,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(206,220,231,1)), color-stop(100%,rgba(89,106,114,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(206,220,231,1) 0%,rgba(89,106,114,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(206,220,231,1) 0%,rgba(89,106,114,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(206,220,231,1) 0%,rgba(89,106,114,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(206,220,231,1) 0%,rgba(89,106,114,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cedce7', endColorstr='#596a72',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-1
|
||||
{
|
||||
background: rgb(89,106,114); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(89,106,114,1) 0%, rgba(206,220,231,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(89,106,114,1)), color-stop(100%,rgba(206,220,231,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(89,106,114,1) 0%,rgba(206,220,231,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(89,106,114,1) 0%,rgba(206,220,231,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(89,106,114,1) 0%,rgba(206,220,231,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(89,106,114,1) 0%,rgba(206,220,231,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#596a72', endColorstr='#cedce7',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-2
|
||||
{
|
||||
background: rgb(242,245,246); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 37%, rgba(200,215,220,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(37%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 37%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 37%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 37%,rgba(200,215,220,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 37%,rgba(200,215,220,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-3
|
||||
{
|
||||
background: rgb(200,215,220); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(200,215,220,1) 0%, rgba(227,234,237,1) 63%, rgba(242,245,246,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(200,215,220,1)), color-stop(63%,rgba(227,234,237,1)), color-stop(100%,rgba(242,245,246,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(200,215,220,1) 0%,rgba(227,234,237,1) 63%,rgba(242,245,246,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(200,215,220,1) 0%,rgba(227,234,237,1) 63%,rgba(242,245,246,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(200,215,220,1) 0%,rgba(227,234,237,1) 63%,rgba(242,245,246,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(200,215,220,1) 0%,rgba(227,234,237,1) 63%,rgba(242,245,246,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c8d7dc', endColorstr='#f2f5f6',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-4
|
||||
{
|
||||
background: rgb(216,224,222); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(216,224,222,1) 0%, rgba(174,191,188,1) 22%, rgba(153,175,171,1) 33%, rgba(142,166,162,1) 50%, rgba(130,157,152,1) 67%, rgba(78,92,90,1) 82%, rgba(14,14,14,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(216,224,222,1)), color-stop(22%,rgba(174,191,188,1)), color-stop(33%,rgba(153,175,171,1)), color-stop(50%,rgba(142,166,162,1)), color-stop(67%,rgba(130,157,152,1)), color-stop(82%,rgba(78,92,90,1)), color-stop(100%,rgba(14,14,14,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(216,224,222,1) 0%,rgba(174,191,188,1) 22%,rgba(153,175,171,1) 33%,rgba(142,166,162,1) 50%,rgba(130,157,152,1) 67%,rgba(78,92,90,1) 82%,rgba(14,14,14,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(216,224,222,1) 0%,rgba(174,191,188,1) 22%,rgba(153,175,171,1) 33%,rgba(142,166,162,1) 50%,rgba(130,157,152,1) 67%,rgba(78,92,90,1) 82%,rgba(14,14,14,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(216,224,222,1) 0%,rgba(174,191,188,1) 22%,rgba(153,175,171,1) 33%,rgba(142,166,162,1) 50%,rgba(130,157,152,1) 67%,rgba(78,92,90,1) 82%,rgba(14,14,14,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(216,224,222,1) 0%,rgba(174,191,188,1) 22%,rgba(153,175,171,1) 33%,rgba(142,166,162,1) 50%,rgba(130,157,152,1) 67%,rgba(78,92,90,1) 82%,rgba(14,14,14,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d8e0de', endColorstr='#0e0e0e',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-5
|
||||
{
|
||||
background: rgb(254,255,232); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(254,255,232,1) 0%, rgba(214,219,191,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,255,232,1)), color-stop(100%,rgba(214,219,191,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feffe8', endColorstr='#d6dbbf',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-h-gradient-gray-6
|
||||
{
|
||||
background: rgb(214,219,191); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(214,219,191,1) 0%, rgba(254,255,232,1) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(214,219,191,1)), color-stop(100%,rgba(254,255,232,1))); /* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(214,219,191,1) 0%,rgba(254,255,232,1) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(214,219,191,1) 0%,rgba(254,255,232,1) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(214,219,191,1) 0%,rgba(254,255,232,1) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, rgba(214,219,191,1) 0%,rgba(254,255,232,1) 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d6dbbf', endColorstr='#feffe8',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
.hq-background-aluminium1
|
||||
{
|
||||
background: -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -moz-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -ms-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -o-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background-size: 10px 10px, 10px 10px, 100% 100%;
|
||||
background-position: 1px 1px, 0px 0px, center center;
|
||||
}
|
||||
.hq-background-aluminium2 {
|
||||
background: -webkit-radial-gradient(center, circle farthest-corner, rgba(255,255,255,0) 50%, rgba(200,200,200,1)), -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -moz-radial-gradient(center, circle farthest-corner, rgba(255,255,255,0) 50%, rgba(200,200,200,1)), -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -ms-radial-gradient(center, circle farthest-corner, rgba(255,255,255,0) 50%, rgba(200,200,200,1)), -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: -o-radial-gradient(center, circle farthest-corner, rgba(255,255,255,0) 50%, rgba(200,200,200,1)), -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background: radial-gradient(center, circle farthest-corner, rgba(255,255,255,0) 50%, rgba(200,200,200,1)), -webkit-radial-gradient(center, circle, rgba(255,255,255,.35), rgba(255,255,255,0) 20%, rgba(255,255,255,0) 21%), -webkit-radial-gradient(center, circle, rgba(0,0,0,.2), rgba(0,0,0,0) 20%, rgba(0,0,0,0) 21%), -webkit-radial-gradient(center, circle farthest-corner, #f0f0f0, #c0c0c0);
|
||||
background-size: 100% 100%, 10px 10px, 10px 10px, 100% 100%;
|
||||
background-position: top center, 1px 1px, 0px 0px, top center;
|
||||
}
|
||||
.hq-background-colorful {
|
||||
background:
|
||||
linear-gradient(limegreen, transparent),
|
||||
linear-gradient(90deg, skyblue, transparent),
|
||||
linear-gradient(-90deg, coral, transparent);
|
||||
background-blend-mode: screen;
|
||||
}
|
||||
/* by Atle Mo (design), Lea Verou */
|
||||
.hq-background-carbon-fibre1 {
|
||||
background:
|
||||
radial-gradient(black 15%, transparent 16%) 0 0,
|
||||
radial-gradient(black 15%, transparent 16%) 8px 8px,
|
||||
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
|
||||
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
|
||||
background-color:#282828;
|
||||
background-size:16px 16px;
|
||||
}
|
||||
/* by Atle Mo (design), Sébastien Grosjean */
|
||||
.hq-background-carbon-fibre {
|
||||
background:
|
||||
linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px,
|
||||
linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px,
|
||||
linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px,
|
||||
linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px,
|
||||
linear-gradient(90deg, #1b1b1b 10px, transparent 10px),
|
||||
linear-gradient(#1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424);
|
||||
background-color: #131313;
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
/* by Tab Atkins Jr */
|
||||
.hq-background-bricks {
|
||||
background-color: silver;
|
||||
background-image: linear-gradient(335deg, #b00 23px, transparent 23px),
|
||||
linear-gradient(155deg, #d00 23px, transparent 23px),
|
||||
linear-gradient(335deg, #b00 23px, transparent 23px),
|
||||
linear-gradient(155deg, #d00 23px, transparent 23px);
|
||||
background-size: 58px 58px;
|
||||
background-position: 0px 2px, 4px 35px, 29px 31px, 34px 6px;
|
||||
}
|
||||
/* by Sarah Backhouse */
|
||||
.hq-background-lined-paper {
|
||||
background-color: #fff;
|
||||
background-image:
|
||||
linear-gradient(90deg, transparent 79px, #abced4 79px, #abced4 81px, transparent 81px),
|
||||
linear-gradient(#eee .1em, transparent .1em);
|
||||
background-size: 100% 1.2em;
|
||||
}
|
||||
.hq-background-blueprint-grid {
|
||||
background-color:#269;
|
||||
background-image: linear-gradient(white 2px, transparent 2px),
|
||||
linear-gradient(90deg, white 2px, transparent 2px),
|
||||
linear-gradient(rgba(255,255,255,.3) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255,255,255,.3) 1px, transparent 1px);
|
||||
background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px;
|
||||
background-position:-2px -2px, -2px -2px, -1px -1px, -1px -1px
|
||||
}
|
||||
.hq-background-blue-flowers
|
||||
{
|
||||
background-image: url(../img/back/flowers.jpg);
|
||||
}
|
162
www/css/doc.css
Normal file
@ -0,0 +1,162 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
Global Reset
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
* {
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p, pre, blockquote, label, ul, ol, dl, fieldset, address { margin:1em 0; }
|
||||
|
||||
|
||||
li, dd { margin-left:5%; }
|
||||
fieldset { padding: .5em; }
|
||||
select option{ padding:0 5px; }
|
||||
a{ outline:none; }
|
||||
a img{ border:none; }
|
||||
|
||||
p {
|
||||
display: block;
|
||||
-webkit-margin-before: 0.5em;
|
||||
-webkit-margin-after: 1em;
|
||||
-webkit-margin-start: 0px;
|
||||
-webkit-margin-end: 0px;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Main Layout
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
body {
|
||||
font-family: "proxima-nova-1", "proxima-nova-2", Arial, sans-serif;
|
||||
font-size: 17px;
|
||||
line-height: 1.4;
|
||||
color: #333;
|
||||
background: #f7f7fa;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,1.0);
|
||||
border-top: 4px solid #556270;
|
||||
padding-bottom: 400px;
|
||||
margin-left: 8px;
|
||||
margin-top: -6px;
|
||||
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2382c8;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: none;
|
||||
}
|
||||
hr:before {
|
||||
content: '\2022 \2022 \2022 \2022 \2022';
|
||||
}
|
||||
|
||||
header {
|
||||
margin: 0 0 20px 0;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
ul.nav {
|
||||
margin: 0;
|
||||
padding: 12px 0 10px 0;
|
||||
list-style-type: none;
|
||||
line-height: 30px;
|
||||
border-bottom: 1px solid #dfe4ea;
|
||||
}
|
||||
ul.nav li {
|
||||
margin: 0 20px;
|
||||
display: inline-block;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
ul.nav li a {
|
||||
color: #bbb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Post Styles
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
h2 {
|
||||
padding-left:1em;
|
||||
font-family: 'lucida sans unicode', 'lucida grande', sans-serif;
|
||||
color: #C90000;
|
||||
font-size: 2.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
padding-left:1em;
|
||||
font-size: 1.5em;
|
||||
color: #333;
|
||||
font-family: 'lucida sans unicode', 'lucida grande', sans-serif;
|
||||
width: 100%;
|
||||
background: blanchedalmond;
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
h3 a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding-left:1em;
|
||||
font-size: 1em;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
-webkit-margin-after: 0.1em;
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1.0em 0;
|
||||
padding: 0 0 0 15px;
|
||||
font-size: 16px;
|
||||
border-left: 2px solid #aaa;
|
||||
}
|
||||
blockquote p {
|
||||
margin: 12px 0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
table {
|
||||
border-top: 1px solid #CCCCCC;
|
||||
border-bottom: 2px solid #CCC;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
border-collapse: separate;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding: 10px 10px 5px 0;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
table.data th, table.data td {
|
||||
text-align: left;
|
||||
}
|
||||
|
BIN
www/css/montserrat-regular-webfont.woff
Normal file
67
www/css/styles.css
Normal file
@ -0,0 +1,67 @@
|
||||
/* ---------------- green - gray style -------------------- */
|
||||
|
||||
body .vis-style-green-gray {
|
||||
font-family: Montserrat, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
color: #444;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(montserrat-regular-webfont.woff);
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
.vis-style-green-gray .vis-widget-body {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.vis-style-green-gray .vis-widget-body,
|
||||
.vis-style-green-gray .editmode-helper {
|
||||
width: calc(100% - 1em);
|
||||
height: calc(100% - 1em);
|
||||
}
|
||||
|
||||
.vis-style-green-gray .vis-image {
|
||||
width: calc(100% - 1em) !important;
|
||||
height: calc(100% - 1em) !important;
|
||||
}
|
||||
|
||||
/* table */
|
||||
.vis-style-green-gray table {
|
||||
background: #34495E;
|
||||
color: #fff;
|
||||
border-radius: .4em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vis-style-green-gray table {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vis-style-green-gray tr {
|
||||
border-top: 1px solid #46637f;
|
||||
border-bottom: 1px solid #46637f;
|
||||
}
|
||||
|
||||
.vis-style-green-gray th {
|
||||
color: #dd5;
|
||||
}
|
||||
.vis-style-green-gray th, .vis-style-green-gray td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* headers */
|
||||
.vis-style-green-gray h1 {
|
||||
font-weight: normal;
|
||||
letter-spacing: -1px;
|
||||
color: #34495E;
|
||||
}
|
||||
|
||||
|
||||
|
1110
www/css/vis-editor.css
Normal file
652
www/css/vis.css
Normal file
@ -0,0 +1,652 @@
|
||||
/* Reset all fonts settings */
|
||||
body, html {
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
text-shadow: none;
|
||||
text-transform: none;
|
||||
text-rendering: auto;
|
||||
color: initial;
|
||||
letter-spacing: normal;
|
||||
word-spacing: normal;
|
||||
text-indent: 0;
|
||||
display: inline-block;
|
||||
text-align: start;
|
||||
font: 1em Arial;
|
||||
}
|
||||
|
||||
/* set font as in editor */
|
||||
#vis_container {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
.vis-widget {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vis-view {
|
||||
top: 0;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
.vis-no-user-select {
|
||||
-webkit-touch-callout: none;
|
||||
-ms-touch-select: none;
|
||||
-ms-touch-action: none;
|
||||
|
||||
touch-callout: none;
|
||||
touch-select: none;
|
||||
touch-action: none;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.vis-no-pointer-events {
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.tplSpanOnOff {
|
||||
border: 1px solid blue;
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.tplSpanOnOff-on {
|
||||
background-color: green;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.tplSpanOnOff-off {
|
||||
|
||||
}
|
||||
|
||||
.ui-slider-vertical {
|
||||
|
||||
height: 93%;
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-content {
|
||||
padding: .5em 0;
|
||||
}
|
||||
|
||||
.vis-widget-button {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.vis-widget-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.vis-widget-prev-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.vis-signals-blink {
|
||||
animation: vis-blink-animation 1s steps(5, start) infinite;
|
||||
-webkit-animation: vis-blink-animation 1s steps(5, start) infinite;
|
||||
}
|
||||
@keyframes vis-blink-animation {
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes vis-blink-animation {
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes vis-waitico-rotate {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
#vis-waitico {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -24px 0 0 -24px;
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
text-indent: 250px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
background: url(../img/gear-icon-md.png);
|
||||
background-size: 100% auto;
|
||||
-webkit-animation-duration: 2s;
|
||||
-webkit-animation-name: vis-waitico-rotate;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
-webkit-animation-timing-function: linear;
|
||||
}
|
||||
|
||||
#dialog-message {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.ui-selectable-helper {
|
||||
opacity: 0.1 !important;
|
||||
background: red !important;
|
||||
}
|
||||
.noTitle .ui-dialog-titlebar {
|
||||
display: none;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
button.ui-dialog-titlebar-close {
|
||||
width: 30px !important;
|
||||
height: 30px !important;
|
||||
margin-top: -14px !important;
|
||||
}
|
||||
|
||||
div.vis-editor-dialog {
|
||||
/* min-width: 440px !important;
|
||||
max-width: 440px !important;*/
|
||||
}
|
||||
|
||||
div.vis-editor-dialog div div button.ui-dialog-titlebar-close {
|
||||
margin-left: 1px !important;
|
||||
margin-top: -4px !important;
|
||||
}
|
||||
|
||||
a.ui-dialog-titlebar-minimize {
|
||||
width: 26px !important;
|
||||
height: 26px !important;
|
||||
padding: 1px !important;
|
||||
margin-top: -4px !important;
|
||||
}
|
||||
|
||||
a.ui-dialog-titlebar-restore {
|
||||
width: 26px !important;
|
||||
height: 26px !important;
|
||||
padding: 1px !important;
|
||||
margin-top: -4px !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar-restore span {
|
||||
margin-top: 5px !important;
|
||||
margin-left: 5px !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar-minimize span {
|
||||
margin-top: 5px !important;
|
||||
margin-left: 5px !important;
|
||||
}
|
||||
|
||||
.vis-panel h4 {
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 12pt;
|
||||
font-weight: bold;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 6px;
|
||||
width: calc(100% - 7px);
|
||||
}
|
||||
|
||||
.vis-no-spaces {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.vis-wait-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 5000;
|
||||
/* background: -moz-linear-gradient(top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0) 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0.65)), color-stop(100%,rgba(0,0,0,0)));
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%);
|
||||
background: -o-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%);
|
||||
background: -ms-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%);
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6000000', endColorstr='#00000000',GradientType=0 ); */
|
||||
}
|
||||
|
||||
.vis-progressbar {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 38%;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.vis-wait-text {
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
left: 38%;
|
||||
font-family: 'trebuchet MS', sans-serif;
|
||||
color: #525252;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.vis-show-new {
|
||||
border: 3px dotted rgba(167, 232, 226, 0.9);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.vis-edit-td-caption {
|
||||
}
|
||||
|
||||
.vis-edit-td-field {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.vis-edit-textbox {
|
||||
width: calc(100% - 4px);
|
||||
}
|
||||
|
||||
.vis-edit-select {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.vis-wizard-select {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.vis-group-button-width {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.vis-user-disabled {
|
||||
background: gray !important;
|
||||
opacity: 0.3 !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
.vis-view-disabled-text {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
left: calc(50% - 150px);
|
||||
top: calc(50% - 12px);
|
||||
}
|
||||
.vis-view-disabled {
|
||||
position: absolute;
|
||||
z-index: 10000;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: 0.4;
|
||||
background: black;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
div#tabs {
|
||||
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
div#vis_editor {
|
||||
min-width: 440px !important;
|
||||
max-width: 440px !important;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.vis-steal-css, .vis-clear-css {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.vis-steal-cursor {
|
||||
cursor: crosshair !important;
|
||||
}
|
||||
|
||||
.vis-inspect-css {
|
||||
font-size: 11px !important;
|
||||
}
|
||||
|
||||
.vis-steal-label {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
#css_table {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.editmode-helper {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url(../img/editmode-pattern.png);
|
||||
/*z-index: 89*/
|
||||
}
|
||||
|
||||
.vis-wait-screen {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vis-clipboard {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 14px;
|
||||
padding-right: 14px;
|
||||
background-color: rgb(55, 169, 232);
|
||||
opacity: 0.8;
|
||||
z-index: 1003;
|
||||
-webkit-border-bottom-right-radius: 7px;
|
||||
-webkit-border-bottom-left-radius: 7px;
|
||||
-moz-border-radius-bottomright: 7px;
|
||||
-moz-border-radius-bottomleft: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
border-bottom-left-radius: 7px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.vis-stealmode {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 14px;
|
||||
padding-right: 14px;
|
||||
background-color: orange;
|
||||
opacity: 0.8;
|
||||
z-index: 1003;
|
||||
-webkit-border-bottom-right-radius: 7px;
|
||||
-webkit-border-bottom-left-radius: 7px;
|
||||
-moz-border-radius-bottomright: 7px;
|
||||
-moz-border-radius-bottomleft: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
border-bottom-left-radius: 7px;
|
||||
}
|
||||
|
||||
/*--------------------------------------------- Authentication dialog ------------------------------- */
|
||||
/* Mask for background, by default is not display */
|
||||
#login-mask {
|
||||
display: none;
|
||||
background: #000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.8;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* You can customize to your needs */
|
||||
.login-popup {
|
||||
display: none;
|
||||
background: #333;
|
||||
padding: 10px;
|
||||
border: 2px solid #ddd;
|
||||
float: left;
|
||||
font-size: 1.2em;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 99999;
|
||||
box-shadow: 0 0 20px #999;
|
||||
/* CSS3 */
|
||||
-moz-box-shadow: 0 0 20px #999;
|
||||
/* Firefox */
|
||||
-webkit-box-shadow: 0 0 20px #999;
|
||||
/* Safari, Chrome */
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
-moz-border-radius: 3px;
|
||||
/* Firefox */
|
||||
-webkit-border-radius: 3px;
|
||||
/* Safari, Chrome */;
|
||||
}
|
||||
|
||||
.login-input-field label {
|
||||
display: block;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
.login-input-field span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login-input-field span {
|
||||
color: #999;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.login-input-field {
|
||||
text-align: center;
|
||||
background: #666666;
|
||||
border-bottom: 1px solid #333;
|
||||
border-left: 1px solid #000;
|
||||
border-right: 1px solid #333;
|
||||
border-top: 1px solid #000;
|
||||
color: #fff;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
font: 13px Arial, Helvetica, sans-serif;
|
||||
padding: 6px 6px 4px;
|
||||
}
|
||||
|
||||
#login-password {
|
||||
width: 205px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#login-username {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.login-message {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding-bottom: 10px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#login-box input:-moz-placeholder {
|
||||
color: #bbb;
|
||||
text-shadow: 0 0 2px #000;
|
||||
}
|
||||
|
||||
#login-box input::-webkit-input-placeholder {
|
||||
color: #bbb;
|
||||
text-shadow: 0 0 2px #000;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
background: -moz-linear-gradient(center top, #f3f3f3, #dddddd);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#f3f3f3), to(#dddddd));
|
||||
background: -o-linear-gradient(top, #f3f3f3, #dddddd);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f3f3f3', EndColorStr='#dddddd');
|
||||
border-color: #000;
|
||||
border-width: 1px;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 6px 6px 4px;
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.login-button:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Notifications themes (info, warn)--------------------------- */
|
||||
|
||||
div.jGrowl div.info {
|
||||
background-color: #FFF1C2;
|
||||
color: navy;
|
||||
}
|
||||
|
||||
div.jGrowl div.info {
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
width: 280px;
|
||||
height: 55px;
|
||||
overflow: hidden;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
div.jGrowl div.warn {
|
||||
background-color: #FFF1C2;
|
||||
color: red;
|
||||
}
|
||||
|
||||
div.jGrowl div.warn {
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
width: 280px;
|
||||
height: 55px;
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ------------------ connecting -------------------------- */
|
||||
#server-disconnect {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
z-index: 5000;
|
||||
}
|
||||
.disconnect-light {
|
||||
background-color: rgba(231,231,231,0.9);
|
||||
}
|
||||
.disconnect-dark {
|
||||
background-color: rgba(25,25,25,0.9);
|
||||
}
|
||||
#server-disconnect > * {
|
||||
/* center child divs */
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
/* x-border-box */
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
/* x-unselectable */
|
||||
user-select: none;
|
||||
-o-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-moz-user-select: -moz-none;
|
||||
-webkit-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
.splash-screen-circle-outer {
|
||||
z-index: 20000;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 100px;
|
||||
margin-top: -50px;
|
||||
margin-left: -50px;
|
||||
border: 5px solid rgba(87, 113, 145, 0.9);
|
||||
opacity: .9;
|
||||
border-right: 5px solid rgba(0, 0, 0, 0);
|
||||
border-left: 5px solid rgba(0, 0, 0, 0);
|
||||
box-shadow: 0 0 35px #577191;
|
||||
-moz-animation: spinPulse 5s infinite ease-in-out;
|
||||
-webkit-animation: spinPulse 5s infinite linear;
|
||||
}
|
||||
.splash-screen-circle-inner {
|
||||
z-index: 20001;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 80px;
|
||||
margin-top: -40px;
|
||||
margin-left: -40px;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border: 5px solid rgba(87, 113, 145, 0.9);
|
||||
opacity: .9;
|
||||
border-left: 5px solid rgba(0, 0, 0, 0);
|
||||
border-right: 5px solid rgba(0, 0, 0, 0);
|
||||
box-shadow: 0 0 15px #577191;
|
||||
-moz-animation: spinoffPulse 5s infinite linear;
|
||||
-webkit-animation: spinoffPulse 5s infinite linear;
|
||||
}
|
||||
.splash-screen-text {
|
||||
z-index: 20002;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
margin-top: -50px;
|
||||
margin-left: -50px;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px #cccccc;
|
||||
vertical-align: middle;
|
||||
color: #002951;
|
||||
}
|
||||
@-moz-keyframes spinPulse {
|
||||
0% {
|
||||
-moz-transform: rotate(160deg);
|
||||
opacity: 0;
|
||||
box-shadow: 0 0 1px #577191;
|
||||
}
|
||||
50% {
|
||||
-moz-transform: rotate(145deg);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
-moz-transform: rotate(-320deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes spinoffPulse {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-moz-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spinPulse {
|
||||
0% {
|
||||
-webkit-transform: rotate(160deg);
|
||||
opacity: 0;
|
||||
box-shadow: 0 0 1px #577191;
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: rotate(145deg);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(-320deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes spinoffPulse {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
1147
www/edit.html
Normal file
BIN
www/icon/add.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
www/icon/align-height.png
Normal file
After Width: | Height: | Size: 947 B |
BIN
www/icon/align-horizontal-center-2.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
www/icon/align-horizontal-left.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/icon/align-horizontal-right-2.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/icon/align-vertical-bottom-2.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/icon/align-vertical-center-2.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
www/icon/align-vertical-top-2.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www/icon/align-width.png
Normal file
After Width: | Height: | Size: 934 B |
BIN
www/icon/bar.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
www/icon/cancel.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
www/icon/checkbox.png
Normal file
After Width: | Height: | Size: 512 B |
BIN
www/icon/container.png
Normal file
After Width: | Height: | Size: 476 B |
BIN
www/icon/control.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
www/icon/copy.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
www/icon/delete.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
www/icon/dialog.png
Normal file
After Width: | Height: | Size: 431 B |
BIN
www/icon/distribute-horizontal-equal.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
www/icon/distribute-vertical-equal.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
www/icon/door.png
Normal file
After Width: | Height: | Size: 384 B |
BIN
www/icon/filter.png
Normal file
After Width: | Height: | Size: 453 B |
BIN
www/icon/groupFixed.png
Normal file
After Width: | Height: | Size: 453 B |
BIN
www/icon/groupVisibility.png
Normal file
After Width: | Height: | Size: 620 B |
BIN
www/icon/info.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
www/icon/lamp.png
Normal file
After Width: | Height: | Size: 580 B |
BIN
www/icon/lock.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
www/icon/lockIcon.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
www/icon/navigation.png
Normal file
After Width: | Height: | Size: 634 B |
BIN
www/icon/ok.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
www/icon/refresh-4.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
www/icon/rename.png
Normal file
After Width: | Height: | Size: 953 B |
BIN
www/icon/rgb.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
www/icon/shutter.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
www/icon/state.png
Normal file
After Width: | Height: | Size: 366 B |
BIN
www/icon/stateful.png
Normal file
After Width: | Height: | Size: 368 B |
BIN
www/icon/static.png
Normal file
After Width: | Height: | Size: 482 B |
BIN
www/icon/table.png
Normal file
After Width: | Height: | Size: 280 B |
BIN
www/icon/temperature.png
Normal file
After Width: | Height: | Size: 510 B |
BIN
www/icon/timestamp.png
Normal file
After Width: | Height: | Size: 540 B |
BIN
www/icon/tools.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
www/icon/value.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
www/icon/window.png
Normal file
After Width: | Height: | Size: 349 B |
BIN
www/img/Heating.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
www/img/Lamp.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
www/img/OutsideTemp.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
www/img/Window.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
www/img/back/box-radial.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
www/img/back/flowers.jpg
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
www/img/back/oblique-line-bk.png
Normal file
After Width: | Height: | Size: 14 KiB |
6
www/img/bg-dots-10.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="10" height="10" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect height="0.5" width="0.5" y="0" x="0" stroke-width="1" stroke="#000000" fill="#000000"/>
|
||||
<rect height="0.5" width="0.5" y="9" x="9" stroke-width="1" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |
6
www/img/bg-dots-15.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="15" height="15" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect height="0.5" width="0.5" y="0" x="0" stroke-width="1" stroke="#000000" fill="#000000"/>
|
||||
<rect height="0.5" width="0.5" y="14" x="14" stroke-width="1" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |
6
www/img/bg-dots-20.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect height="0.5" width="0.5" y="0" x="0" stroke-width="1" stroke="#000000" fill="#000000"/>
|
||||
<rect height="0.5" width="0.5" y="19" x="19" stroke-width="1" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |
6
www/img/bg-dots-25.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect height="0.5" width="0.5" y="0" x="0" stroke-width="1" stroke="#000000" fill="#000000"/>
|
||||
<rect height="0.5" width="0.5" y="24" x="24" stroke-width="1" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |
6
www/img/bg-dots-30.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect height="0.5" width="0.5" y="0" x="0" stroke-width="1" stroke="#000000" fill="#000000"/>
|
||||
<rect height="0.5" width="0.5" y="29" x="29" stroke-width="1" stroke="#ffffff" fill="#ffffff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 277 B |