Fully end to end encrypted anonymous chat program. Server only stores public key lookup for users and the encrypted messages. No credentials are transfered to the server, but kept in local browser storage. This allows 100% safe chatting.
https://safechat.ch
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
4.4 KiB
215 lines
4.4 KiB
9 years ago
|
|
||
|
/*!
|
||
|
* Stylus - Unit
|
||
|
* Copyright (c) Automattic <developer.wordpress.com>
|
||
|
* MIT Licensed
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var Node = require('./node')
|
||
|
, nodes = require('./');
|
||
|
|
||
|
/**
|
||
|
* Unit conversion table.
|
||
|
*/
|
||
|
|
||
|
var FACTOR_TABLE = {
|
||
|
'mm': {val: 1, label: 'mm'},
|
||
|
'cm': {val: 10, label: 'mm'},
|
||
|
'in': {val: 25.4, label: 'mm'},
|
||
|
'pt': {val: 25.4/72, label: 'mm'},
|
||
|
'ms': {val: 1, label: 'ms'},
|
||
|
's': {val: 1000, label: 'ms'},
|
||
|
'Hz': {val: 1, label: 'Hz'},
|
||
|
'kHz': {val: 1000, label: 'Hz'}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Initialize a new `Unit` with the given `val` and unit `type`
|
||
|
* such as "px", "pt", "in", etc.
|
||
|
*
|
||
|
* @param {String} val
|
||
|
* @param {String} type
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
var Unit = module.exports = function Unit(val, type){
|
||
|
Node.call(this);
|
||
|
this.val = val;
|
||
|
this.type = type;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Inherit from `Node.prototype`.
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.__proto__ = Node.prototype;
|
||
|
|
||
|
/**
|
||
|
* Return Boolean based on the unit value.
|
||
|
*
|
||
|
* @return {Boolean}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.toBoolean = function(){
|
||
|
return nodes.Boolean(this.type
|
||
|
? true
|
||
|
: this.val);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return unit string.
|
||
|
*
|
||
|
* @return {String}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.toString = function(){
|
||
|
return this.val + (this.type || '');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return a clone of this node.
|
||
|
*
|
||
|
* @return {Node}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.clone = function(){
|
||
|
var clone = new Unit(this.val, this.type);
|
||
|
clone.lineno = this.lineno;
|
||
|
clone.column = this.column;
|
||
|
clone.filename = this.filename;
|
||
|
return clone;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return a JSON representation of this node.
|
||
|
*
|
||
|
* @return {Object}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.toJSON = function(){
|
||
|
return {
|
||
|
__type: 'Unit',
|
||
|
val: this.val,
|
||
|
type: this.type,
|
||
|
lineno: this.lineno,
|
||
|
column: this.column,
|
||
|
filename: this.filename
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Operate on `right` with the given `op`.
|
||
|
*
|
||
|
* @param {String} op
|
||
|
* @param {Node} right
|
||
|
* @return {Node}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.operate = function(op, right){
|
||
|
var type = this.type || right.first.type;
|
||
|
|
||
|
// swap color
|
||
|
if ('rgba' == right.nodeName || 'hsla' == right.nodeName) {
|
||
|
return right.operate(op, this);
|
||
|
}
|
||
|
|
||
|
// operate
|
||
|
if (this.shouldCoerce(op)) {
|
||
|
right = right.first;
|
||
|
// percentages
|
||
|
if ('%' != this.type && ('-' == op || '+' == op) && '%' == right.type) {
|
||
|
right = new Unit(this.val * (right.val / 100), '%');
|
||
|
} else {
|
||
|
right = this.coerce(right);
|
||
|
}
|
||
|
|
||
|
switch (op) {
|
||
|
case '-':
|
||
|
return new Unit(this.val - right.val, type);
|
||
|
case '+':
|
||
|
// keyframes interpolation
|
||
|
type = type || (right.type == '%' && right.type);
|
||
|
return new Unit(this.val + right.val, type);
|
||
|
case '/':
|
||
|
return new Unit(this.val / right.val, type);
|
||
|
case '*':
|
||
|
return new Unit(this.val * right.val, type);
|
||
|
case '%':
|
||
|
return new Unit(this.val % right.val, type);
|
||
|
case '**':
|
||
|
return new Unit(Math.pow(this.val, right.val), type);
|
||
|
case '..':
|
||
|
case '...':
|
||
|
var start = this.val
|
||
|
, end = right.val
|
||
|
, expr = new nodes.Expression
|
||
|
, inclusive = '..' == op;
|
||
|
if (start < end) {
|
||
|
do {
|
||
|
expr.push(new nodes.Unit(start));
|
||
|
} while (inclusive ? ++start <= end : ++start < end);
|
||
|
} else {
|
||
|
do {
|
||
|
expr.push(new nodes.Unit(start));
|
||
|
} while (inclusive ? --start >= end : --start > end);
|
||
|
}
|
||
|
return expr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Node.prototype.operate.call(this, op, right);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Coerce `other` unit to the same type as `this` unit.
|
||
|
*
|
||
|
* Supports:
|
||
|
*
|
||
|
* mm -> cm | in
|
||
|
* cm -> mm | in
|
||
|
* in -> mm | cm
|
||
|
*
|
||
|
* ms -> s
|
||
|
* s -> ms
|
||
|
*
|
||
|
* Hz -> kHz
|
||
|
* kHz -> Hz
|
||
|
*
|
||
|
* @param {Unit} other
|
||
|
* @return {Unit}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
Unit.prototype.coerce = function(other){
|
||
|
if ('unit' == other.nodeName) {
|
||
|
var a = this
|
||
|
, b = other
|
||
|
, factorA = FACTOR_TABLE[a.type]
|
||
|
, factorB = FACTOR_TABLE[b.type];
|
||
|
|
||
|
if (factorA && factorB && (factorA.label == factorB.label)) {
|
||
|
var bVal = b.val * (factorB.val / factorA.val);
|
||
|
return new nodes.Unit(bVal, a.type);
|
||
|
} else {
|
||
|
return new nodes.Unit(b.val, a.type);
|
||
|
}
|
||
|
} else if ('string' == other.nodeName) {
|
||
|
// keyframes interpolation
|
||
|
if ('%' == other.val) return new nodes.Unit(0, '%');
|
||
|
var val = parseFloat(other.val);
|
||
|
if (isNaN(val)) Node.prototype.coerce.call(this, other);
|
||
|
return new nodes.Unit(val);
|
||
|
} else {
|
||
|
return Node.prototype.coerce.call(this, other);
|
||
|
}
|
||
|
};
|