@ -17,11 +17,9 @@
|
||||
"API"
|
||||
],
|
||||
"scripts": {
|
||||
"postinstall": "run-p install-server install-app",
|
||||
"install-server": "cd server && npm install",
|
||||
"postinstall": "run-s install-app",
|
||||
"install-app": "cd app && npm install",
|
||||
"start": "run-p start-server watch-app",
|
||||
"start-server": "cd server && npm start",
|
||||
"start": "run-s watch-app",
|
||||
"watch-app": "cd app && npm start"
|
||||
},
|
||||
"dependencies": {},
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
{
|
||||
"extends": "airbnb-base",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"no-multi-spaces": 0,
|
||||
"no-use-before-define": 1,
|
||||
"object-shorthand": 1,
|
||||
"key-spacing": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-unused-vars": 1,
|
||||
"no-param-reassign": 1
|
||||
}
|
||||
}
|
||||
61
server/.gitignore
vendored
@ -1,61 +0,0 @@
|
||||
## Default gitignore below this line
|
||||
chain.ldb
|
||||
|
||||
# Logs
|
||||
logs/*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
# Bitcore - Bcoin - Insight
|
||||
Rebuilt Bitcore with Bcoin engine and Insight API sitting on top of Mongo.
|
||||
|
||||
### Requirements
|
||||
Mongodb running on your system.
|
||||
|
||||
node >=7.6.0 - This requirement comes from Bcoin. Developed under 8.2.0.
|
||||
|
||||
### Usage
|
||||
```
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
A Full Bcoin node will start in console.
|
||||
|
||||
http://localhost:3000
|
||||
|
||||
### Configuration
|
||||
|
||||
A configuration object exists in /config/index.js
|
||||
|
||||
Bcoin accepts a config object per Bcoin docs. Same for Mongo/Mongoose
|
||||
|
||||
### Resetting Application State
|
||||
```
|
||||
mongo
|
||||
use bitcore
|
||||
db.blocks.drop()
|
||||
db.transactions.drop()
|
||||
|
||||
Ctrl+D out of mongo
|
||||
|
||||
rm -rf ${bcoin-prefix-in-config.js}/chain.ldb
|
||||
```
|
||||
|
||||
### Contributing
|
||||
|
||||
1. Fork
|
||||
2. Branch
|
||||
3. Send a PR
|
||||
@ -1,28 +0,0 @@
|
||||
const config = {
|
||||
start_node: true,
|
||||
logging: 'debug',
|
||||
bcoin: {
|
||||
network: 'main',
|
||||
db: 'leveldb',
|
||||
prefix: '.',
|
||||
checkpoints: true,
|
||||
workers: true,
|
||||
logLevel: 'info',
|
||||
'max-inbound': 10,
|
||||
'max-outbound': 10,
|
||||
},
|
||||
mongodb: {
|
||||
uri: 'mongodb://localhost/bitcore',
|
||||
options: {
|
||||
useMongoClient: true,
|
||||
},
|
||||
},
|
||||
api: {
|
||||
port: 3000,
|
||||
json_spaces: 2,
|
||||
currency_refresh: 60,
|
||||
ticker_url: 'https://www.bitstamp.net/api/ticker/',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
@ -1,37 +0,0 @@
|
||||
const config = {
|
||||
start_node: true,
|
||||
logging: 'debug',
|
||||
bcoin_http: 'localhost',
|
||||
bcoin: {
|
||||
network: 'main',
|
||||
db: 'leveldb',
|
||||
prefix: '.',
|
||||
checkpoints: true,
|
||||
workers: false,
|
||||
logLevel: 'info',
|
||||
'max-inbound': 10,
|
||||
'max-outbound': 10,
|
||||
'index-tx': true,
|
||||
'index-address': true,
|
||||
'http-port': 8332,
|
||||
},
|
||||
mongodb: {
|
||||
uri: 'mongodb://localhost/bitcore',
|
||||
options: {
|
||||
useMongoClient: true,
|
||||
},
|
||||
},
|
||||
api: {
|
||||
port: 3000,
|
||||
json_spaces: 2,
|
||||
currency_refresh: 60,
|
||||
ticker_url: 'https://www.bitstamp.net/api/ticker/',
|
||||
ticker_prop: 'bitstamp',
|
||||
max_blocks: 72,
|
||||
max_txs: 10,
|
||||
max_page_txs: 10,
|
||||
request_ttl: 100000,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
@ -1,25 +0,0 @@
|
||||
const Bcoin = require('./lib/node');
|
||||
const config = require('./config');
|
||||
const logger = require('./lib/logger');
|
||||
const Api = require('./lib/api').server;
|
||||
const db = require('./lib/db');
|
||||
|
||||
logger.log('debug',
|
||||
'Debug mode started');
|
||||
|
||||
db.connect(config.mongodb.uri, config.mongodb.options);
|
||||
|
||||
db.connection.once('open', () => {
|
||||
db.blocks.getBestBlockHeight((err, bestBlockHeight) => {
|
||||
// Pass height to node to start Sync
|
||||
logger.log('debug',
|
||||
`Starting Bcoin from best height: ${bestBlockHeight}`);
|
||||
|
||||
if (config.start_node) Bcoin.start(bestBlockHeight);
|
||||
|
||||
Api.listen(config.api.port, () => {
|
||||
logger.log('debug',
|
||||
'listening on port 3000');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,84 +0,0 @@
|
||||
const logger = require('../logger');
|
||||
const db = require('../db');
|
||||
|
||||
module.exports = function AddressAPI(router) {
|
||||
router.get('/addr/:addr', (req, res) => {
|
||||
const addr = req.params.addr || '';
|
||||
|
||||
return db.txs.getTxByAddress(addr, 0, 999999999, (err, txs) => {
|
||||
if (err || txs.length === 0) {
|
||||
logger.log('error',
|
||||
`getTxByBlock ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
|
||||
// Sum the matching outputs for every tx
|
||||
const totalReceived = txs.reduce((total, tx) => total + tx.outputs.reduce((sum, output) => {
|
||||
if (output.address === req.params.addr) {
|
||||
return sum + output.value;
|
||||
}
|
||||
return sum;
|
||||
}, 0), 0) || 0;
|
||||
|
||||
// Sum the matching inputs for every tx
|
||||
const totalSpent = txs.reduce((total, tx) => total + tx.inputs.reduce((sum, input) => {
|
||||
if (input.coin && input.coin.address === req.params.addr) {
|
||||
return sum + input.coin.value;
|
||||
}
|
||||
return sum;
|
||||
}, 0), 0) || 0;
|
||||
|
||||
// Match Insight API
|
||||
return res.json({
|
||||
addrStr: req.params.addr,
|
||||
balance: (totalReceived - totalSpent) / 1e8,
|
||||
balanceSat: totalReceived - totalSpent,
|
||||
totalReceived: totalReceived / 1e8,
|
||||
totalReceivedSat: totalReceived,
|
||||
totalSent: totalSpent / 1e8,
|
||||
totalSentSat: totalSpent,
|
||||
unconfirmedBalance: 0,
|
||||
unconfirmedBalanceSat: 0,
|
||||
unconfirmedTxApperances: 0,
|
||||
txApperances: txs.length,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Stubbed by # to help with tasking
|
||||
router.get('/addr/:addr/utxo', (req, res) => {
|
||||
res.send('1');
|
||||
});
|
||||
|
||||
router.get('/addr/:addr/balance', (req, res) => {
|
||||
res.send('2');
|
||||
});
|
||||
|
||||
router.get('/addr/:addr/totalReceived', (req, res) => {
|
||||
res.send('3');
|
||||
});
|
||||
|
||||
router.get('/addr/:addr/totalSent', (req, res) => {
|
||||
res.send('4');
|
||||
});
|
||||
|
||||
router.get('/addr/:addr/unconfirmedBalance', (req, res) => {
|
||||
res.send('5');
|
||||
});
|
||||
|
||||
router.get('/addrs/:addrs/utxo', (req, res) => {
|
||||
res.send('6');
|
||||
});
|
||||
|
||||
router.post('/addrs/utxo', (req, res) => {
|
||||
res.send('7');
|
||||
});
|
||||
|
||||
router.get('/addrs/:addrs/txs', (req, res) => {
|
||||
res.send('8');
|
||||
});
|
||||
|
||||
router.post('/addrs/txs', (req, res) => {
|
||||
res.send('9');
|
||||
});
|
||||
};
|
||||
@ -1,93 +0,0 @@
|
||||
const logger = require('../logger');
|
||||
const db = require('../db');
|
||||
|
||||
module.exports = function BlockAPI(router) {
|
||||
router.get('/block/:blockHash', (req, res) => {
|
||||
const blockHash = req.params.blockHash;
|
||||
|
||||
// Pass Mongo params, fields and limit to db api.
|
||||
return db.blocks.getByHash(blockHash,
|
||||
(err, block) => {
|
||||
if (err || !block) {
|
||||
logger.log('err', err);
|
||||
return res.status(404).send();
|
||||
}
|
||||
// Format the request for insight ui
|
||||
return res.json({
|
||||
hash: block.hash,
|
||||
size: block.size,
|
||||
height: block.height,
|
||||
version: block.version,
|
||||
merkleroot: block.merkleRoot,
|
||||
tx: block.txs,
|
||||
time: block.ts,
|
||||
nonce: block.nonce,
|
||||
bits: block.bits.toString(16),
|
||||
difficulty: 1,
|
||||
chainwork: block.chainwork.toString(16),
|
||||
confirmations: 0,
|
||||
previousblockhash: block.prevBlock,
|
||||
nextblockhash: 0,
|
||||
reward: block.reward / 1e8,
|
||||
isMainChain: true,
|
||||
poolInfo: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/blocks', (req, res) => {
|
||||
// Pass Mongo params, fields and limit to db api.
|
||||
db.blocks.getTopBlocks(
|
||||
(err, blocks) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`/blocks: ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
// Format the request for insight ui
|
||||
return res.json({
|
||||
blocks: blocks.map(block => ({
|
||||
hash: block.hash,
|
||||
height: block.height,
|
||||
size: block.size,
|
||||
time: block.ts,
|
||||
txlength: block.txs.length,
|
||||
poolInfo: {},
|
||||
})),
|
||||
length: blocks.length,
|
||||
pagination: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/rawblock/:blockHash', (req, res) => {
|
||||
const blockHash = req.params.blockHash || '';
|
||||
|
||||
// Pass Mongo params, fields and limit to db api.
|
||||
return db.blocks.getRawBlock(blockHash,
|
||||
(err, block) => {
|
||||
if (err || !block) {
|
||||
logger.log('error',
|
||||
`/rawblock/:blockHash: ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
return res.json(block);
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/block-index/:height', (req, res) => {
|
||||
const height = parseInt(req.params.height, 10) || 1;
|
||||
// Pass Mongo params, fields and limit to db api.
|
||||
return db.blocks.byHeight(height,
|
||||
(err, block) => {
|
||||
if (err || !block) {
|
||||
logger.log('error',
|
||||
`/block-index/:height: ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
return res.json({
|
||||
blockHash: block.hash,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1,52 +0,0 @@
|
||||
const config = require('../../config');
|
||||
const logger = require('../logger');
|
||||
const request = require('request');
|
||||
|
||||
// Retrieve the configured endpoint's ticker rate at a
|
||||
// set interval
|
||||
|
||||
const refreshInterval = config.api.currency_refresh >= 1 ?
|
||||
config.api.currency_refresh * 1000 :
|
||||
60 * 1000;
|
||||
let lastRate = 0;
|
||||
|
||||
init();
|
||||
|
||||
function init() {
|
||||
getRate();
|
||||
|
||||
setInterval(() => {
|
||||
getRate();
|
||||
}, refreshInterval);
|
||||
}
|
||||
|
||||
// Make the request to the remote API
|
||||
function getRate() {
|
||||
request(config.api.ticker_url, (err, res, body) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`${err}`);
|
||||
}
|
||||
try {
|
||||
const ticker = JSON.parse(body);
|
||||
lastRate = ticker.last;
|
||||
logger.log('debug',
|
||||
`getRate: ${lastRate}`);
|
||||
} catch (error) {
|
||||
logger.log('error',
|
||||
`getRate: ${error}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function currencyAPI(app) {
|
||||
// Return the ticker price
|
||||
app.get('/currency', (req, res) => {
|
||||
const data = {};
|
||||
data[config.api.ticker_prop] = lastRate;
|
||||
|
||||
res.json({
|
||||
data,
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1,43 +0,0 @@
|
||||
const express = require('express');
|
||||
const config = require('../../config');
|
||||
const bodyParser = require('body-parser');
|
||||
const helmet = require('helmet');
|
||||
const sanitizer = require('./middleware/sanitizer');
|
||||
|
||||
const app = express();
|
||||
const api = express.Router();
|
||||
const cors = require('./middleware/cors');
|
||||
|
||||
app.use(cors);
|
||||
app.use(helmet());
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(bodyParser.json());
|
||||
app.use(sanitizer);
|
||||
// Serve insight ui front end from root dir public folder
|
||||
app.use(express.static('../app/www', { maxage: '1w' }));
|
||||
|
||||
app.set('json spaces', config.api.json_spaces);
|
||||
|
||||
// Pass router to register the routes
|
||||
const AddressAPI = require('./address')(api);
|
||||
const BlockAPI = require('./block')(api);
|
||||
const CurrencyAPI = require('./currency')(api);
|
||||
const StatusAPI = require('./status')(api);
|
||||
const TransactionAPI = require('./transaction')(api);
|
||||
const MessageAPI = require('./message')(api);
|
||||
|
||||
app.use('/api', api);
|
||||
|
||||
// 404
|
||||
app.use((req, res) => res.status(404).send({
|
||||
status: 404,
|
||||
url: req.originalUrl,
|
||||
error: 'Not found',
|
||||
}));
|
||||
|
||||
const server = require('http').Server(app);
|
||||
|
||||
module.exports = {
|
||||
server,
|
||||
api,
|
||||
};
|
||||
@ -1,36 +0,0 @@
|
||||
const Message = require('bitcore-message');
|
||||
// Copied from previous source
|
||||
function verifyMessage(req, res) {
|
||||
const address = req.body.address || req.query.address;
|
||||
const signature = req.body.signature || req.query.signature;
|
||||
const message = req.body.message || req.query.message;
|
||||
|
||||
if (!address || !signature || !message) {
|
||||
return res.json({
|
||||
message: 'Missing parameters (expected "address", "signature" and "message")',
|
||||
code: 1,
|
||||
});
|
||||
}
|
||||
let valid;
|
||||
try {
|
||||
valid = new Message(message).verify(address, signature);
|
||||
} catch (err) {
|
||||
return res.json({
|
||||
message: `Unexpected error: ${err.message}`,
|
||||
code: 1,
|
||||
});
|
||||
}
|
||||
return res.json({ result: valid });
|
||||
}
|
||||
|
||||
module.exports = function messageAPI(router) {
|
||||
router.get('/messages/verify', (req, res) => {
|
||||
verifyMessage(req, res);
|
||||
});
|
||||
|
||||
router.post('/messages/verify', (req, res) => {
|
||||
verifyMessage(req, res);
|
||||
});
|
||||
|
||||
router.get('/utils/estimatefee', (req, res) => res.send('estimate fees'));
|
||||
};
|
||||
@ -1,37 +0,0 @@
|
||||
module.exports = function (req, res, next) {
|
||||
const allowed = {
|
||||
|
||||
origins: [
|
||||
'*',
|
||||
],
|
||||
|
||||
methods: [
|
||||
'HEAD',
|
||||
'GET',
|
||||
'POST',
|
||||
'PUT',
|
||||
'DELETE',
|
||||
'OPTIONS',
|
||||
],
|
||||
|
||||
headers: [
|
||||
'Content-Type',
|
||||
'Authorization',
|
||||
'Content-Length',
|
||||
'X-Requested-With',
|
||||
'Cache-Control',
|
||||
'X-Accept-Version',
|
||||
'x-signature',
|
||||
'x-pubkey',
|
||||
'x-identity',
|
||||
'cf-connecting-ip',
|
||||
],
|
||||
|
||||
};
|
||||
|
||||
res.header('Access-Control-Allow-Origin', allowed.origins.join());
|
||||
res.header('Access-Control-Allow-Methods', allowed.methods.join());
|
||||
res.header('Access-Control-Allow-Headers', allowed.headers.join());
|
||||
|
||||
next();
|
||||
};
|
||||
@ -1,140 +0,0 @@
|
||||
const util = require('../../util');
|
||||
|
||||
// Strip the request, sanitize inputs, rebuild
|
||||
module.exports = function sanitize(req, res, next) {
|
||||
const params = req.params || null;
|
||||
const body = req.body || null;
|
||||
const query = req.query || null;
|
||||
|
||||
let cleanParams = null;
|
||||
let cleanBody = null;
|
||||
let cleanQuery = null;
|
||||
|
||||
// req.params
|
||||
if (params) {
|
||||
// Transaction Id
|
||||
if (params.txid && !util.isTxid(params.txid)) {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Transaction Id',
|
||||
});
|
||||
}
|
||||
// Address
|
||||
if (params.addr && typeof (params.addr) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Bitcoin Address',
|
||||
});
|
||||
}
|
||||
// Block Hash
|
||||
if (params.blockHash && typeof (params.blockHash) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Block Hash',
|
||||
});
|
||||
}
|
||||
// Height
|
||||
if (params.height) {
|
||||
if (typeof (params.height) !== 'number') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Block Hash',
|
||||
});
|
||||
}
|
||||
params.height = parseInt(params.height, 10);
|
||||
}
|
||||
|
||||
cleanParams = {
|
||||
txid: params.txid || null,
|
||||
addr: params.addr || null,
|
||||
blockHash: params.blockHash || null,
|
||||
height: params.height || null,
|
||||
};
|
||||
}
|
||||
|
||||
// req.body
|
||||
if (body) {
|
||||
// Signature
|
||||
if (body.signature && typeof (body.signature) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Signature',
|
||||
});
|
||||
}
|
||||
// Message
|
||||
if (body.message && typeof (body.message) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Message',
|
||||
});
|
||||
}
|
||||
// Address
|
||||
if (body.address && !util.isBitcoinAddress(body.address)) {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Bitcoin Address',
|
||||
});
|
||||
}
|
||||
cleanBody = {
|
||||
signature: body.signature || null,
|
||||
message: body.message || null,
|
||||
address: body.address || null,
|
||||
};
|
||||
}
|
||||
|
||||
if (query) {
|
||||
// Address
|
||||
if (query.address && !util.isBitcoinAddress(query.address)) {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Bitcoin Address',
|
||||
});
|
||||
}
|
||||
// Signature
|
||||
if (query.signature && typeof (query.signature) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Signature',
|
||||
});
|
||||
}
|
||||
// Message
|
||||
if (query.message && typeof (query.message) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Message',
|
||||
});
|
||||
}
|
||||
// q
|
||||
if (query.q && typeof (query.q) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Q',
|
||||
});
|
||||
}
|
||||
// Page Number
|
||||
if (query.pageNum && typeof (query.pageNum) !== 'number') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Page Number',
|
||||
});
|
||||
}
|
||||
// Block (hash - implicit)
|
||||
if (query.block && typeof (query.block) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Block',
|
||||
});
|
||||
}
|
||||
// Raw Tx
|
||||
if (query.rawtx && typeof (query.rawtx) !== 'string') {
|
||||
return res.status(404).send({
|
||||
error: 'Invalid Bitcoin Address',
|
||||
});
|
||||
}
|
||||
|
||||
cleanQuery = {
|
||||
address: query.address || null,
|
||||
signature: query.signature || null,
|
||||
message: query.message || null,
|
||||
q: query.q || null,
|
||||
pageNum: query.pageNum || null,
|
||||
block: query.block || null,
|
||||
rawtx: query.rawtx || null,
|
||||
};
|
||||
}
|
||||
|
||||
// Strip off unexpected params
|
||||
req.params = cleanParams;
|
||||
req.body = cleanBody;
|
||||
req.query = cleanQuery;
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
@ -1,108 +0,0 @@
|
||||
const request = require('request');
|
||||
const pkg = require('../../package.json');
|
||||
const config = require('../../config');
|
||||
const netCfg = require('bcoin/lib/net/common');
|
||||
const logger = require('../logger');
|
||||
const db = require('../db');
|
||||
|
||||
const API_URL = `http://${config.bcoin_http}:${config.bcoin['http-port']}/`;
|
||||
|
||||
// Retrieve Bcoin status
|
||||
function getStatus(cb) {
|
||||
request(`${API_URL}`, (err, localRes, status) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`getStatus ${err}`);
|
||||
return cb(err);
|
||||
}
|
||||
try {
|
||||
status = JSON.parse(status);
|
||||
} catch (e) {
|
||||
logger.log('error',
|
||||
`getStatus JSON.parse: ${e}`);
|
||||
return cb(e);
|
||||
}
|
||||
return cb(null, status);
|
||||
});
|
||||
}
|
||||
// UI assigns Multiple Responsibilities depending on params
|
||||
module.exports = function statusAPI(router) {
|
||||
// Get last block hash or node status
|
||||
router.get('/status', (req, res) => {
|
||||
if (req.query.q === 'getLastBlockHash') {
|
||||
db.blocks.getLastBlock(
|
||||
(err, block) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`${err}`);
|
||||
return res.status(404).send(err);
|
||||
}
|
||||
return res.send({
|
||||
syncTipHash: block.hash,
|
||||
lastblockhash: block.hash,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
getStatus((err, status) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`/status getStatus: ${err}`);
|
||||
return res.status(404).send(err);
|
||||
}
|
||||
if (!status) {
|
||||
logger.log('error',
|
||||
'/status getStatus: no Status');
|
||||
return res.status(404).send();
|
||||
}
|
||||
return res.json({
|
||||
info: {
|
||||
version: status.version,
|
||||
protocolversion: netCfg.PROTOCOL_VERSION,
|
||||
blocks: status.chain.height,
|
||||
timeoffset: status.time.offset,
|
||||
connections: status.pool.outbound,
|
||||
proxy: '',
|
||||
difficulty: 0,
|
||||
testnet: status.network !== 'main',
|
||||
relayfee: 0,
|
||||
errors: '',
|
||||
network: status.network,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
// Get Bcoin sync status
|
||||
router.get('/sync', (req, res) => {
|
||||
getStatus((err, status) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`/sync: ${err}`);
|
||||
return res.status(404).send(err);
|
||||
}
|
||||
if (!status) {
|
||||
logger.log('error',
|
||||
'/sync: no status');
|
||||
return res.status(404).send();
|
||||
}
|
||||
return res.json({
|
||||
status: status.chain.progress === 100 ? 'synced' : 'syncing',
|
||||
blockChainHeight: status.chain.height,
|
||||
syncPercentage: Math.round(status.chain.progress * 100),
|
||||
height: status.chain.height,
|
||||
error: null,
|
||||
type: 'bcoin node',
|
||||
});
|
||||
});
|
||||
});
|
||||
// Copied from previous source
|
||||
router.get('/peer', (req, res) => res.json({
|
||||
connected: true,
|
||||
host: '127.0.0.1',
|
||||
port: null,
|
||||
}));
|
||||
|
||||
router.get('/version', (req, res) => res.json({
|
||||
version: pkg.version,
|
||||
}));
|
||||
};
|
||||
@ -1,196 +0,0 @@
|
||||
const logger = require('../logger');
|
||||
const request = require('request');
|
||||
const config = require('../../config');
|
||||
const db = require('../db');
|
||||
|
||||
const API_URL = `http://${config.bcoin_http}:${config.bcoin['http-port']}`;
|
||||
const MAX_TXS = config.api.max_txs;
|
||||
|
||||
module.exports = function transactionAPI(router) {
|
||||
// Txs by txid
|
||||
router.get('/tx/:txid', (req, res) => {
|
||||
// Get max block height for calculating confirmations
|
||||
const height = db.blocks.bestHeight();
|
||||
const txid = req.params.txid || '';
|
||||
|
||||
return db.txs.getTxById(txid, (err, tx) => {
|
||||
if (err || !tx) {
|
||||
logger.log('error',
|
||||
`/tx/:tid getTxById: ${err ? err.err : ''}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
|
||||
return res.send({
|
||||
txid: tx.hash,
|
||||
version: tx.version,
|
||||
time: tx.ps,
|
||||
blocktime: tx.ps,
|
||||
locktime: tx.locktime,
|
||||
blockhash: tx.block,
|
||||
fees: tx.fee / 1e8,
|
||||
size: tx.size,
|
||||
confirmations: (height - tx.height) + 1,
|
||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||
vin: tx.inputs.map(input => ({
|
||||
addr: input.address,
|
||||
value: input.value / 1e8,
|
||||
})),
|
||||
vout: tx.outputs.map(output => ({
|
||||
scriptPubKey: {
|
||||
addresses: [output.address],
|
||||
},
|
||||
value: output.value / 1e8,
|
||||
})),
|
||||
isCoinBase: tx.inputs[0].prevout.hash === '0000000000000000000000000000000000000000000000000000000000000000',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// /txs is overloaded. Next ver separate concerns
|
||||
// query by block
|
||||
// query by address
|
||||
router.get('/txs', (req, res) => {
|
||||
const pageNum = parseInt(req.query.pageNum, 10) || 0;
|
||||
const height = db.blocks.bestHeight();
|
||||
// get txs for blockhash, start with best height to calc confirmations
|
||||
if (req.query.block) {
|
||||
return db.txs.getTxCountByBlock(req.query.block, (err, count) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`getTxByBlock ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
const totalPages = Math.ceil(count / MAX_TXS);
|
||||
|
||||
return db.txs.getTxByBlock(req.query.block, pageNum, MAX_TXS, (error, txs) => {
|
||||
if (error) {
|
||||
logger.log('error',
|
||||
`getTxByBlock ${error}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
|
||||
return res.send({
|
||||
pagesTotal: totalPages,
|
||||
txs: txs.map(tx => ({
|
||||
txid: tx.hash,
|
||||
fees: tx.fee / 1e8,
|
||||
size: tx.size,
|
||||
confirmations: (height - tx.height) + 1,
|
||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||
vin: tx.inputs.map(input => ({
|
||||
scriptSig: {
|
||||
asm: input.script,
|
||||
},
|
||||
addr: input.address,
|
||||
value: input.value / 1e8,
|
||||
})),
|
||||
vout: tx.outputs.map(output => ({
|
||||
scriptPubKey: {
|
||||
asm: output.script,
|
||||
addresses: [output.address],
|
||||
},
|
||||
value: output.value / 1e8,
|
||||
})),
|
||||
isCoinBase: tx.inputs[0].prevout.hash === '0000000000000000000000000000000000000000000000000000000000000000',
|
||||
})),
|
||||
});
|
||||
});
|
||||
});
|
||||
} else if (req.query.address) {
|
||||
// Get txs by address, start with best height to calc confirmations
|
||||
const addr = req.query.address || '';
|
||||
|
||||
return db.txs.getTxCountByAddress(addr, (err, count) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`getTxByBlock ${err}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
const totalPages = Math.ceil(count / MAX_TXS);
|
||||
|
||||
return db.txs.getTxByAddress(addr, pageNum, MAX_TXS, (error, txs) => {
|
||||
if (error) {
|
||||
logger.log('error',
|
||||
`getTxByBlock ${error}`);
|
||||
return res.status(404).send();
|
||||
}
|
||||
return res.send({
|
||||
pagesTotal: totalPages,
|
||||
txs: txs.map(tx => ({
|
||||
txid: tx.hash,
|
||||
fees: tx.fee / 1e8,
|
||||
size: tx.size,
|
||||
confirmations: (height - tx.height) + 1,
|
||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||
vin: tx.inputs.map(input => ({
|
||||
scriptSig: {
|
||||
asm: input.script,
|
||||
},
|
||||
addr: input.address,
|
||||
value: input.value / 1e8,
|
||||
})),
|
||||
vout: tx.outputs.map(output => ({
|
||||
scriptPubKey: {
|
||||
asm: output.script,
|
||||
addresses: [output.address],
|
||||
},
|
||||
value: output.value / 1e8,
|
||||
})),
|
||||
isCoinBase: tx.inputs[0].prevout.hash === '0000000000000000000000000000000000000000000000000000000000000000',
|
||||
})),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
// Get last n txs
|
||||
return db.txs.getTopTransactions((err, txs) => {
|
||||
if (err) {
|
||||
logger.log('err',
|
||||
`/txs getTopTransactions ${err}`);
|
||||
return res.status(404).send(err);
|
||||
}
|
||||
return res.send(txs.map(tx => ({
|
||||
txid: tx.hash,
|
||||
fees: tx.fee / 1e8,
|
||||
size: tx.size,
|
||||
confirmations: (height - tx.height) + 1,
|
||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||
vin: tx.inputs.map(input => ({
|
||||
scriptSig: {
|
||||
asm: input.script,
|
||||
},
|
||||
addr: input.address,
|
||||
value: input.value / 1e8,
|
||||
})),
|
||||
vout: tx.outputs.map(output => ({
|
||||
scriptPubKey: {
|
||||
asm: output.script,
|
||||
addresses: [output.address],
|
||||
},
|
||||
value: output.value / 1e8,
|
||||
})),
|
||||
isCoinBase: tx.inputs[0].prevout.hash === '0000000000000000000000000000000000000000000000000000000000000000',
|
||||
})),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/rawtx/:txid', (req, res) => res.send(req.params.txid));
|
||||
|
||||
router.post('/tx/send', (req, res) => {
|
||||
const rawtx = req.body.rawtx || '';
|
||||
request.post({
|
||||
url: `${API_URL}/broadcast`,
|
||||
body: { tx: rawtx },
|
||||
json: true,
|
||||
}, (err, localRes, body) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`${err}`);
|
||||
return res.status(404).send(err);
|
||||
}
|
||||
|
||||
return res.json(true);
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -1,74 +0,0 @@
|
||||
const Block = require('../models/block.js');
|
||||
const logger = require('../logger');
|
||||
const config = require('../../config');
|
||||
|
||||
|
||||
let bestBlockHeight = 0;
|
||||
|
||||
// 1e9 limit = ~2M years from now
|
||||
// Mostly for sync to set height
|
||||
function bestHeight(height) {
|
||||
height = parseInt(height, 10) || 0;
|
||||
if (Number.isInteger(height) &&
|
||||
height > 0 &&
|
||||
height < 1 * 1e9) {
|
||||
bestBlockHeight = height;
|
||||
return bestBlockHeight;
|
||||
}
|
||||
return bestBlockHeight;
|
||||
}
|
||||
|
||||
function getRawBlock(hash, cb) {
|
||||
return Block.getRawBlock(hash, cb);
|
||||
}
|
||||
|
||||
function byHeight(height, cb) {
|
||||
return Block.byHeight(height, cb);
|
||||
}
|
||||
|
||||
function getTopBlocks(cb) {
|
||||
return Block.last(cb);
|
||||
}
|
||||
|
||||
function getByHash(hash, cb) {
|
||||
return Block.byHash(hash, cb);
|
||||
}
|
||||
|
||||
function getLastBlock(cb) {
|
||||
return Block.last(cb)
|
||||
.limit(1);
|
||||
}
|
||||
|
||||
function saveBcoinBlock(entry, block, cb) {
|
||||
return Block.saveBcoinBlock(entry, block, cb);
|
||||
}
|
||||
|
||||
// Returns highest consecutive block height
|
||||
function getBestBlockHeight(cb) {
|
||||
logger.log('debug',
|
||||
'Verifying Mongo Blockchain');
|
||||
return Block.getHeights((err, blocks) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
// Blocks are in ascending order
|
||||
let lastGoodHeight = 0;
|
||||
blocks.forEach((block) => {
|
||||
if (lastGoodHeight === block.height - 1) {
|
||||
lastGoodHeight = block.height;
|
||||
}
|
||||
});
|
||||
return cb(null, lastGoodHeight);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getBestBlockHeight,
|
||||
getRawBlock,
|
||||
getTopBlocks,
|
||||
getLastBlock,
|
||||
getByHash,
|
||||
byHeight,
|
||||
bestHeight,
|
||||
saveBcoinBlock,
|
||||
};
|
||||
@ -1,30 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
const logger = require('../logger');
|
||||
const Blocks = require('./blocks');
|
||||
const Txs = require('./transactions');
|
||||
|
||||
mongoose.connection.on('error', (err) => {
|
||||
logger.log('error',
|
||||
`Failed to connect to Mongo Database
|
||||
${err}`);
|
||||
});
|
||||
|
||||
process.on('SIGINT', gracefulExit).on('SIGTERM', gracefulExit);
|
||||
|
||||
// Catastrophic Fails can still result in data loss
|
||||
function gracefulExit() {
|
||||
logger.log('debug',
|
||||
'Graceful Shutdown Starting...');
|
||||
mongoose.connection.close(() => {
|
||||
logger.log('debug',
|
||||
'Mongoose connection with DB disconnected through app termination');
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
connect: mongoose.connect,
|
||||
connection: mongoose.connection,
|
||||
blocks: Blocks,
|
||||
txs: Txs,
|
||||
};
|
||||
@ -1,47 +0,0 @@
|
||||
const Transactions = require('../models/transaction.js');
|
||||
const config = require('../../config');
|
||||
const logger = require('../logger');
|
||||
|
||||
const MAX_PAGE_TXS = config.api.max_page_txs;
|
||||
|
||||
function getTopTransactions(cb) {
|
||||
return Transactions.last(cb);
|
||||
}
|
||||
|
||||
function getTxById(txid, cb) {
|
||||
return Transactions.byId(txid, cb);
|
||||
}
|
||||
|
||||
function getTxByBlock(blockHash, page, limit, cb) {
|
||||
return Transactions.byBlockHash(blockHash, cb)
|
||||
.skip(limit * page);
|
||||
}
|
||||
|
||||
function getTxByAddress(address, page, limit, cb) {
|
||||
return Transactions.byAddress(address, cb)
|
||||
.limit(limit)
|
||||
.skip(limit * page);
|
||||
}
|
||||
|
||||
function getTxCountByBlock(blockHash, cb) {
|
||||
return Transactions.countByBlock(blockHash, cb);
|
||||
}
|
||||
|
||||
function getTxCountByAddress(address, cb) {
|
||||
return Transactions.countByAddress(address, cb);
|
||||
}
|
||||
|
||||
function saveBcoinTransactions(entry, txs, cb) {
|
||||
return Transactions.saveBcoinTransactions(entry, txs, cb);
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
getTopTransactions,
|
||||
getTxById,
|
||||
getTxByBlock,
|
||||
getTxCountByBlock,
|
||||
getTxByAddress,
|
||||
getTxCountByAddress,
|
||||
saveBcoinTransactions,
|
||||
};
|
||||
@ -1,19 +0,0 @@
|
||||
const winston = require('winston');
|
||||
const config = require('../../config');
|
||||
|
||||
const logfile = new Date().toISOString().split('T')[0];
|
||||
|
||||
const logger = new (winston.Logger)({
|
||||
transports: [
|
||||
new (winston.transports.Console)({
|
||||
timestamp: true,
|
||||
}),
|
||||
new (winston.transports.File)({
|
||||
filename: `logs/${logfile}.log`,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
logger.level = process.env.LOG || config.logging;
|
||||
|
||||
module.exports = logger;
|
||||
@ -1,15 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Input = require('./input');
|
||||
const Output = require('./output');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const AddressSchema = new Schema({
|
||||
address: { type: String, default: '' },
|
||||
inputs: [Input.schema],
|
||||
outputs: [Output.schema],
|
||||
});
|
||||
|
||||
const Address = mongoose.model('Address', AddressSchema);
|
||||
|
||||
module.exports = Address;
|
||||
@ -1,98 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
const config = require('../../config');
|
||||
const util = require('../util');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
// These limits can be overriden higher up the stack
|
||||
const MAX_BLOCKS = config.api.max_blocks;
|
||||
|
||||
const BlockSchema = new Schema({
|
||||
hash: { type: String, default: '' },
|
||||
height: { type: Number, default: 0 },
|
||||
size: { type: Number, default: 0 },
|
||||
version: { type: Number, default: 0 },
|
||||
prevBlock: { type: String, default: '' },
|
||||
merkleRoot: { type: String, default: '' },
|
||||
ts: { type: Number, default: 0 },
|
||||
bits: { type: Number, default: 0 },
|
||||
nonce: { type: Number, default: 0 },
|
||||
txs: [{ type: String, default: '' }],
|
||||
chainwork: { type: Number, default: 0 },
|
||||
reward: { type: Number, default: 0 },
|
||||
network: { type: String, default: '' },
|
||||
poolInfo: { type: Object, default: {} },
|
||||
rawBlock: { type: String, default: '' },
|
||||
}, {
|
||||
toJSON: {
|
||||
virtuals: true,
|
||||
},
|
||||
id: false,
|
||||
});
|
||||
|
||||
BlockSchema.index({ hash: 1 });
|
||||
BlockSchema.index({ height: 1 });
|
||||
|
||||
BlockSchema.statics.byHeight = function blockByHeight(height, cb) {
|
||||
return this.model('Block').findOne(
|
||||
{ height },
|
||||
cb);
|
||||
};
|
||||
|
||||
BlockSchema.statics.byHash = function byHash(hash, cb) {
|
||||
return this.model('Block').findOne(
|
||||
{ hash },
|
||||
cb);
|
||||
};
|
||||
|
||||
BlockSchema.statics.getRawBlock = function getRawBlock(hash, cb) {
|
||||
return this.model('Block').findOne(
|
||||
{ hash },
|
||||
{ rawBlock: 1 },
|
||||
cb);
|
||||
};
|
||||
|
||||
BlockSchema.statics.last = function lastBlocks(cb) {
|
||||
return this.model('Block').find(
|
||||
{},
|
||||
cb)
|
||||
.limit(MAX_BLOCKS)
|
||||
.sort({ height: -1 });
|
||||
};
|
||||
|
||||
BlockSchema.statics.getHeights = function findMissing(cb) {
|
||||
return this.model('Block').find(
|
||||
{},
|
||||
{ height: 1 },
|
||||
cb)
|
||||
.sort({ height: 1 });
|
||||
};
|
||||
|
||||
BlockSchema.statics.saveBcoinBlock = function saveBcoinBlock(entry, block, cb) {
|
||||
const Block = this.model('Block');
|
||||
const rawBlock = block.toRaw().toString('hex');
|
||||
const blockJSON = block.toJSON();
|
||||
const reward = util.calcBlockReward(entry.height);
|
||||
|
||||
return new Block({
|
||||
hash: blockJSON.hash,
|
||||
height: entry.height,
|
||||
size: block.getSize(),
|
||||
version: blockJSON.version,
|
||||
prevBlock: blockJSON.prevBlock,
|
||||
merkleRoot: blockJSON.merkleRoot,
|
||||
ts: blockJSON.ts,
|
||||
bits: blockJSON.bits,
|
||||
nonce: blockJSON.nonce,
|
||||
txs: block.txs.map((tx) => {
|
||||
const txJSON = tx.toJSON();
|
||||
return txJSON.hash;
|
||||
}),
|
||||
chainwork: entry.chainwork,
|
||||
reward,
|
||||
network: config.bcoin.network,
|
||||
poolInfo: {},
|
||||
rawBlock,
|
||||
}).save(cb);
|
||||
};
|
||||
|
||||
module.exports = mongoose.model('Block', BlockSchema);
|
||||
@ -1,16 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const InputSchema = new Schema({
|
||||
value: { type: Number, default: 0 },
|
||||
prevout: { type: Object, default: {} },
|
||||
script: { type: String, default: '' },
|
||||
witness: { type: String, default: '' },
|
||||
sequence: { type: Number, default: 0 },
|
||||
address: { type: String, default: '' },
|
||||
});
|
||||
|
||||
const Input = mongoose.model('Input', InputSchema);
|
||||
|
||||
module.exports = Input;
|
||||
@ -1,14 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const OutputSchema = new Schema({
|
||||
address: { type: String, default: '' },
|
||||
script: { type: String, default: '' },
|
||||
value: { type: Number, default: 0 },
|
||||
type: { type: String, default: '' },
|
||||
});
|
||||
|
||||
const Output = mongoose.model('Output', OutputSchema);
|
||||
|
||||
module.exports = Output;
|
||||
@ -1,128 +0,0 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Input = require('./input');
|
||||
const Output = require('./output');
|
||||
const logger = require('../logger');
|
||||
const config = require('../../config');
|
||||
const util = require('../util');
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
// These limits can be overriden higher up the stack
|
||||
const MAX_TXS = config.api.max_txs;
|
||||
|
||||
const TransactionSchema = new Schema({
|
||||
hash: { type: String, default: '' },
|
||||
witnessHash: { type: String, default: '' },
|
||||
fee: { type: Number, default: 0 },
|
||||
rate: { type: Number, default: 0 },
|
||||
ps: { type: Number, default: 0 },
|
||||
height: { type: Number, default: 0 },
|
||||
block: { type: String, default: '' },
|
||||
index: { type: Number, default: 0 },
|
||||
version: { type: Number, default: 0 },
|
||||
flag: { type: Number, default: 0 },
|
||||
lockTime: { type: Number, default: 0 },
|
||||
inputs: [Input.schema],
|
||||
outputs: [Output.schema],
|
||||
size: { type: Number, default: 0 },
|
||||
network: { type: String, default: '' },
|
||||
});
|
||||
|
||||
TransactionSchema.index({ hash: 1 });
|
||||
TransactionSchema.index({ block: 1 });
|
||||
TransactionSchema.index({ 'outputs.address': 1 });
|
||||
TransactionSchema.index({ 'inputs.address': 1 });
|
||||
|
||||
|
||||
TransactionSchema.statics.byId = function txById(txid, cb) {
|
||||
return this.model('Transaction').findOne(
|
||||
{ hash: txid },
|
||||
cb);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.byHash = function txByHash(hash, cb) {
|
||||
return this.byId(hash, cb);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.byBlockHash = function txByBlockHash(hash, cb) {
|
||||
return this.model('Transaction').find(
|
||||
{ block: hash },
|
||||
cb)
|
||||
.limit(MAX_TXS);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.byAddress = function txByAddress(address, cb) {
|
||||
return this.model('Transaction').find(
|
||||
{
|
||||
$or: [
|
||||
{ 'inputs.address': address },
|
||||
{ 'outputs.address': address }],
|
||||
},
|
||||
cb)
|
||||
.limit(MAX_TXS);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.countByBlock = function txByAddress(hash, cb) {
|
||||
return this.model('Transaction').count(
|
||||
{ block: hash },
|
||||
cb);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.countByAddress = function txByAddress(address, cb) {
|
||||
return this.model('Transaction').count(
|
||||
{
|
||||
$or: [
|
||||
{ 'inputs.address': address },
|
||||
{ 'outputs.address': address }],
|
||||
},
|
||||
cb);
|
||||
};
|
||||
|
||||
TransactionSchema.statics.last = function lastTx(cb) {
|
||||
return this.model('Transaction').find(
|
||||
{},
|
||||
cb)
|
||||
.limit(MAX_TXS)
|
||||
.sort({ height: -1 });
|
||||
};
|
||||
|
||||
TransactionSchema.statics.saveBcoinTransactions = function saveBcoinTransactions(entry, txs, cb) {
|
||||
txs.forEach((tx) => {
|
||||
this.saveBcoinTransaction(entry, tx, cb);
|
||||
});
|
||||
};
|
||||
|
||||
TransactionSchema.statics.saveBcoinTransaction = function saveBcoinTransaction(entry, tx, cb) {
|
||||
const Transaction = this.model('Transaction');
|
||||
return new Transaction({
|
||||
hash: tx.hash,
|
||||
witnessHash: tx.witnessHash,
|
||||
fee: tx.fee,
|
||||
rate: tx.rate,
|
||||
ps: tx.ps,
|
||||
height: entry.height,
|
||||
block: util.revHex(entry.hash),
|
||||
ts: entry.ts,
|
||||
date: entry.tx,
|
||||
index: tx.index,
|
||||
version: tx.version,
|
||||
flag: tx.flag,
|
||||
inputs: tx.inputs.map(input => new Input({
|
||||
value: input.coin ? input.coin.value : 0,
|
||||
prevout: input.prevout,
|
||||
script: input.script,
|
||||
witness: input.witness,
|
||||
sequence: input.sequence,
|
||||
address: input.coin ? input.coin.address : '',
|
||||
})),
|
||||
outputs: tx.outputs.map(output => new Output({
|
||||
address: output.address,
|
||||
script: output.script,
|
||||
value: output.value,
|
||||
})),
|
||||
lockTime: tx.locktime,
|
||||
chain: config.bcoin.network,
|
||||
})
|
||||
.save(cb);
|
||||
};
|
||||
|
||||
module.exports = mongoose.model('Transaction', TransactionSchema);
|
||||
@ -1,53 +0,0 @@
|
||||
const FullNode = require('bcoin/lib/node/fullnode');
|
||||
const logger = require('../../lib/logger');
|
||||
const config = require('../../config');
|
||||
const db = require('../../lib/db');
|
||||
|
||||
const node = new FullNode(config.bcoin);
|
||||
|
||||
function start(bestBlockHeight) {
|
||||
node.open()
|
||||
.then(() => {
|
||||
node.connect()
|
||||
.then(() => {
|
||||
node.chain.reset(bestBlockHeight);
|
||||
node.startSync();
|
||||
});
|
||||
});
|
||||
|
||||
node.chain.on('connect', (entry, block) => {
|
||||
db.blocks.bestHeight(entry.height);
|
||||
// Assemble Bcoin block data
|
||||
node.chain.db.getBlockView(block)
|
||||
.then((view) => {
|
||||
const fullBlock = block.getJSON(node.network, view, entry.height);
|
||||
// Save the block
|
||||
db.blocks.saveBcoinBlock(entry, block, (err) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`Error saving block ${err}`);
|
||||
}
|
||||
});
|
||||
// Save the Txs
|
||||
db.txs.saveBcoinTransactions(entry, fullBlock.txs, (err) => {
|
||||
if (err) {
|
||||
logger.log('error',
|
||||
`Error saving txs ${err}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
node.chain.on('full', () => {
|
||||
|
||||
});
|
||||
|
||||
node.on('error', (err) => {
|
||||
logger.log('error',
|
||||
`${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start,
|
||||
};
|
||||
@ -1,39 +0,0 @@
|
||||
function revHex(hex) {
|
||||
let rev = '';
|
||||
for (let i = 0; i < hex.length; i += 2) {
|
||||
rev = hex.slice(i, i + 2) + rev;
|
||||
}
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
function calcBlockReward(height) {
|
||||
let halvenings = Math.floor(height / 210000);
|
||||
let reward = 50 * 1e8;
|
||||
if (halvenings >= 64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (halvenings > 0) {
|
||||
halvenings -= 1;
|
||||
reward /= 2;
|
||||
}
|
||||
return reward;
|
||||
}
|
||||
|
||||
function is64HexString(value) {
|
||||
return /^[0-9a-f]{64}$/i.test(value);
|
||||
}
|
||||
|
||||
function isBitcoinAddress(value) {
|
||||
return /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(value);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
revHex,
|
||||
calcBlockReward,
|
||||
isBlockHash: is64HexString,
|
||||
isTxid: is64HexString,
|
||||
isBitcoinAddress,
|
||||
};
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "bitcore-bcoin-insight",
|
||||
"version": "1.0.0",
|
||||
"description": "Full node with extended capabilities using Bitcore and Bcoin",
|
||||
"engines": {
|
||||
"node": ">=7.6.0"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bcoin": "^1.0.0-beta.14",
|
||||
"bitcore-message": "^1.0.4",
|
||||
"body-parser": "^1.17.2",
|
||||
"express": "^4.15.3",
|
||||
"helmet": "^3.8.1",
|
||||
"mongoose": "^4.11.5",
|
||||
"request": "^2.81.0",
|
||||
"winston": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^4.4.1",
|
||||
"eslint-config-airbnb-base": "^11.3.1",
|
||||
"eslint-plugin-import": "^2.7.0"
|
||||
}
|
||||
}
|
||||
5
server/public/css/main.min.css
vendored
@ -1,229 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata></metadata>
|
||||
<defs>
|
||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
||||
<missing-glyph horiz-adv-x="500" />
|
||||
<glyph />
|
||||
<glyph />
|
||||
<glyph unicode="
" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
|
||||
<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="434" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="163" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="72" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode="€" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
|
||||
<glyph unicode="−" d="M200 400h900v300h-900v-300z" />
|
||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
||||
<glyph unicode="☁" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
|
||||
<glyph unicode="✉" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
|
||||
<glyph unicode="✏" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
|
||||
<glyph unicode="" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
|
||||
<glyph unicode="" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
|
||||
<glyph unicode="" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
|
||||
<glyph unicode="" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
|
||||
<glyph unicode="" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
|
||||
<glyph unicode="" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
|
||||
<glyph unicode="" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
|
||||
<glyph unicode="" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
|
||||
<glyph unicode="" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
|
||||
<glyph unicode="" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
|
||||
<glyph unicode="" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
|
||||
<glyph unicode="" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
|
||||
<glyph unicode="" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
|
||||
<glyph unicode="" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
|
||||
<glyph unicode="" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
|
||||
<glyph unicode="" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
|
||||
<glyph unicode="" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
|
||||
<glyph unicode="" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
|
||||
<glyph unicode="" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
|
||||
<glyph unicode="" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
|
||||
<glyph unicode="" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
|
||||
<glyph unicode="" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
|
||||
<glyph unicode="" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
|
||||
<glyph unicode="" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
|
||||
<glyph unicode="" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
|
||||
<glyph unicode="" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
|
||||
<glyph unicode="" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
|
||||
<glyph unicode="" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
|
||||
<glyph unicode="" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
|
||||
<glyph unicode="" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
|
||||
<glyph unicode="" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
|
||||
<glyph unicode="" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
|
||||
<glyph unicode="" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
|
||||
<glyph unicode="" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
|
||||
<glyph unicode="" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
|
||||
<glyph unicode="" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
|
||||
<glyph unicode="" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
|
||||
<glyph unicode="" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
|
||||
<glyph unicode="" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
|
||||
<glyph unicode="" d="M200 0l900 550l-900 550v-1100z" />
|
||||
<glyph unicode="" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
|
||||
<glyph unicode="" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
|
||||
<glyph unicode="" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
|
||||
<glyph unicode="" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
|
||||
<glyph unicode="" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
|
||||
<glyph unicode="" d="M0 547l600 453v-300h600v-300h-600v-301z" />
|
||||
<glyph unicode="" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
|
||||
<glyph unicode="" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
|
||||
<glyph unicode="" d="M104 600h296v600h300v-600h298l-449 -600z" />
|
||||
<glyph unicode="" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
|
||||
<glyph unicode="" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
|
||||
<glyph unicode="" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
|
||||
<glyph unicode="" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
|
||||
<glyph unicode="" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
|
||||
<glyph unicode="" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
|
||||
<glyph unicode="" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
|
||||
<glyph unicode="" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
|
||||
<glyph unicode="" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
|
||||
<glyph unicode="" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
|
||||
<glyph unicode="" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
|
||||
<glyph unicode="" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
|
||||
<glyph unicode="" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
|
||||
<glyph unicode="" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
|
||||
<glyph unicode="" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
|
||||
<glyph unicode="" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
|
||||
<glyph unicode="" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
|
||||
<glyph unicode="" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
|
||||
<glyph unicode="" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
|
||||
<glyph unicode="" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
|
||||
<glyph unicode="" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
|
||||
<glyph unicode="" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
|
||||
<glyph unicode="" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
|
||||
<glyph unicode="" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
|
||||
<glyph unicode="" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
|
||||
<glyph unicode="" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
|
||||
<glyph unicode="" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
|
||||
<glyph unicode="" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
|
||||
<glyph unicode="" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
|
||||
<glyph unicode="" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
|
||||
<glyph unicode="" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
|
||||
<glyph unicode="" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
|
||||
<glyph unicode="" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
|
||||
<glyph unicode="" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
|
||||
<glyph unicode="" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
|
||||
<glyph unicode="" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
|
||||
<glyph unicode="" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
|
||||
<glyph unicode="" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
|
||||
<glyph unicode="" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
|
||||
<glyph unicode="" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
|
||||
<glyph unicode="" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
|
||||
<glyph unicode="" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
|
||||
<glyph unicode="" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
|
||||
<glyph unicode="" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
|
||||
<glyph unicode="" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
Before Width: | Height: | Size: 62 KiB |
0
server/public/img/.gitignore
vendored
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 148 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 723 B |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
@ -1,74 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-ng-app="insight" data-ng-csp>
|
||||
<head>
|
||||
<base href="/" />
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<meta name="fragment" content="!">
|
||||
<title data-ng-bind="$root.title + $root.titleDetail + ' | Insight'">Insight</title>
|
||||
<meta name="keywords" content="bitcoins, transactions, blocks, address, block chain, best block, mining difficulty, hash serialized">
|
||||
<meta name="description" content="Bitcoin Insight. View detailed information on all bitcoin transactions and blocks.">
|
||||
<link rel="shortcut icon" href="img/icons/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700,400italic">
|
||||
<link rel="stylesheet" href="css/main.min.css">
|
||||
</head>
|
||||
<body ng-cloak class="ng-cloak">
|
||||
<div>
|
||||
<script type="text/ng-template" id="scannerModal.html">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Scan Code</h3>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<canvas id="qr-canvas" width="200" height="150"></canvas>
|
||||
<div data-ng-show="isMobile">
|
||||
<div id="file-input-wrapper" class="btn btn-primary">
|
||||
<span class="pull-left text-center">
|
||||
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
|
||||
Get QR code
|
||||
</span>
|
||||
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
<div data-ng-hide="isMobile">
|
||||
<video id="qrcode-scanner-video" width="300" height="225" data-ng-hide="isMobile"></video>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-ng-click="cancel()" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div id="wrap">
|
||||
<div class="navbar navbar-default navbar-fixed-top" data-ng-include="'views/includes/header.html'" role='navigation'></div>
|
||||
<section class="container" data-ng-view></section>
|
||||
</div>
|
||||
<div id="footer" role="navigation">
|
||||
<div class="container" data-ng-controller="FooterController">
|
||||
<div class="links m20t pull-left">
|
||||
<span class="languages" ng-show="availableLanguages.0">
|
||||
[
|
||||
<a href="#"
|
||||
ng-click="setLanguage(l.isoCode)"
|
||||
ng-class="{'selected': defaultLanguage == l.isoCode}"
|
||||
ng-repeat="l in availableLanguages">
|
||||
<span ng-show="!$first"> · </span> {{l.name}}
|
||||
</a>
|
||||
]
|
||||
</span>
|
||||
|
||||
[
|
||||
<a href="messages/verify" translate>verify message</a>
|
||||
<span> · </span>
|
||||
<a href="tx/send" translate>broadcast transaction</a>
|
||||
]
|
||||
</div>
|
||||
<a class="insight m10v pull-right" target="_blank" href="http://insight.is">insight <small>API v{{version}}</small></a>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
|
||||
<script src="js/vendors.min.js"></script>
|
||||
<script src="js/angularjs-all.min.js"></script>
|
||||
<script src="js/main.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
7555
server/public/js/angularjs-all.js
vendored
11
server/public/js/angularjs-all.min.js
vendored
3
server/public/js/main.min.js
vendored
5
server/public/js/vendors.min.js
vendored
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "angular-animate",
|
||||
"version": "1.2.32",
|
||||
"license": "MIT",
|
||||
"main": "./angular-animate.js",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"angular": "1.2.32"
|
||||
},
|
||||
"homepage": "https://github.com/angular/bower-angular-animate",
|
||||
"_release": "1.2.32",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.2.32",
|
||||
"commit": "8ce2578f2fba61d1334424c0708776b1f7a33068"
|
||||
},
|
||||
"_source": "https://github.com/angular/bower-angular-animate.git",
|
||||
"_target": "~1.2.13",
|
||||
"_originalSource": "angular-animate"
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Angular
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,68 +0,0 @@
|
||||
# packaged angular-animate
|
||||
|
||||
This repo is for distribution on `npm` and `bower`. The source for this module is in the
|
||||
[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngAnimate).
|
||||
Please file issues and pull requests against that repo.
|
||||
|
||||
## Install
|
||||
|
||||
You can install this package either with `npm` or with `bower`.
|
||||
|
||||
### npm
|
||||
|
||||
```shell
|
||||
npm install angular-animate
|
||||
```
|
||||
|
||||
Then add `ngAnimate` as a dependency for your app:
|
||||
|
||||
```javascript
|
||||
angular.module('myApp', [require('angular-animate')]);
|
||||
```
|
||||
|
||||
### bower
|
||||
|
||||
```shell
|
||||
bower install angular-animate
|
||||
```
|
||||
|
||||
Then add a `<script>` to your `index.html`:
|
||||
|
||||
```html
|
||||
<script src="/bower_components/angular-animate/angular-animate.js"></script>
|
||||
```
|
||||
|
||||
Then add `ngAnimate` as a dependency for your app:
|
||||
|
||||
```javascript
|
||||
angular.module('myApp', ['ngAnimate']);
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation is available on the
|
||||
[AngularJS docs site](http://docs.angularjs.org/api/ngAnimate).
|
||||
|
||||
## License
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1704
server/public/lib/angular-animate/angular-animate.js
vendored
@ -1,28 +0,0 @@
|
||||
/*
|
||||
AngularJS v1.2.32
|
||||
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
License: MIT
|
||||
*/
|
||||
(function(G,d,P){'use strict';d.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(H,k,e){e=e.ngAnimateChildren;d.isString(e)&&0===e.length?k.data("$$ngAnimateChildren",!0):H.$watch(e,function(d){k.data("$$ngAnimateChildren",!!d)})}}).factory("$$animateReflow",["$$rAF","$document",function(d,k){var e=k[0].body;return function(k){return d(function(){k(e.offsetWidth)})}}]).config(["$provide","$animateProvider",function(H,k){function e(d){for(var e=0;e<d.length;e++){var g=
|
||||
d[e];if(g.nodeType==aa)return g}}function D(g){return d.element(e(g))}var p=d.noop,x=d.forEach,Q=k.$$selectors,aa=1,g="$$ngAnimateState",ga="$$ngAnimateChildren",I="ng-animate",h={running:!0};H.decorator("$animate",["$delegate","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$document",function(w,G,$,J,K,l,P){function R(a){var b=a.data(g)||{};b.running=!0;a.data(g,b)}function ha(a){if(a){var b=[],c={};a=a.substr(1).split(".");($.transitions||$.animations)&&b.push(G.get(Q[""]));
|
||||
for(var f=0;f<a.length;f++){var d=a[f],e=Q[d];e&&!c[d]&&(b.push(G.get(e)),c[d]=!0)}return b}}function M(a,b,c){function f(a,b){var c=a[b],d=a["before"+b.charAt(0).toUpperCase()+b.substr(1)];if(c||d)return"leave"==b&&(d=c,c=null),l.push({event:b,fn:c}),m.push({event:b,fn:d}),!0}function e(b,d,f){var g=[];x(b,function(a){a.fn&&g.push(a)});var q=0;x(g,function(b,e){var B=function(){a:{if(d){(d[e]||p)();if(++q<g.length)break a;d=null}f()}};switch(b.event){case "setClass":d.push(b.fn(a,r,E,B));break;case "addClass":d.push(b.fn(a,
|
||||
r||c,B));break;case "removeClass":d.push(b.fn(a,E||c,B));break;default:d.push(b.fn(a,B))}});d&&0===d.length&&f()}var g=a[0];if(g){var n="setClass"==b,k=n||"addClass"==b||"removeClass"==b,r,E;d.isArray(c)&&(r=c[0],E=c[1],c=r+" "+E);var h=a.attr("class")+" "+c;if(T(h)){var u=p,y=[],m=[],z=p,v=[],l=[],h=(" "+h).replace(/\s+/g,".");x(ha(h),function(a){!f(a,b)&&n&&(f(a,"addClass"),f(a,"removeClass"))});return{node:g,event:b,className:c,isClassBased:k,isSetClassOperation:n,before:function(a){u=a;e(m,y,
|
||||
function(){u=p;a()})},after:function(a){z=a;e(l,v,function(){z=p;a()})},cancel:function(){y&&(x(y,function(a){(a||p)(!0)}),u(!0));v&&(x(v,function(a){(a||p)(!0)}),z(!0))}}}}}function F(a,b,c,f,e,s,n){function h(d){var e="$animate:"+d;z&&(z[e]&&0<z[e].length)&&K(function(){c.triggerHandler(e,{event:a,className:b})})}function r(){h("before")}function l(){h("after")}function k(){h("close");n&&K(function(){n()})}function u(){u.hasBeenRun||(u.hasBeenRun=!0,s())}function y(){if(!y.hasBeenRun){y.hasBeenRun=
|
||||
!0;var e=c.data(g);e&&(m&&m.isClassBased?A(c,b):(K(function(){var e=c.data(g)||{};t==e.index&&A(c,b,a)}),c.data(g,e)));k()}}var m=M(c,a,b);if(m){b=m.className;var z=d.element._data(m.node),z=z&&z.events;f||(f=e?e.parent():c.parent());var v=c.data(g)||{};e=v.active||{};var p=v.totalActive||0,B=v.last,C;m.isClassBased&&(C=v.running||v.disabled||B&&!B.isClassBased);if(C||N(c,f))u(),r(),l(),y();else{f=!1;if(0<p){C=[];if(m.isClassBased)"setClass"==B.event?(C.push(B),A(c,b)):e[b]&&(w=e[b],w.event==a?f=
|
||||
!0:(C.push(w),A(c,b)));else if("leave"==a&&e["ng-leave"])f=!0;else{for(var w in e)C.push(e[w]),A(c,w);e={};p=0}0<C.length&&x(C,function(a){a.cancel()})}!m.isClassBased||(m.isSetClassOperation||f)||(f="addClass"==a==c.hasClass(b));if(f)u(),r(),l(),k();else{if("leave"==a)c.one("$destroy",function(a){a=d.element(this);var b=a.data(g);b&&(b=b.active["ng-leave"])&&(b.cancel(),A(a,"ng-leave"))});c.addClass(I);var t=O++;p++;e[b]=m;c.data(g,{last:m,active:e,index:t,totalActive:p});r();m.before(function(e){var d=
|
||||
c.data(g);e=e||!d||!d.active[b]||m.isClassBased&&d.active[b].event!=a;u();!0===e?y():(l(),m.after(y))})}}}else u(),r(),l(),y()}function U(a){if(a=e(a))a=d.isFunction(a.getElementsByClassName)?a.getElementsByClassName(I):a.querySelectorAll("."+I),x(a,function(a){a=d.element(a);(a=a.data(g))&&a.active&&x(a.active,function(a){a.cancel()})})}function A(a,b){if(e(a)==e(J))h.disabled||(h.running=!1,h.structural=!1);else if(b){var c=a.data(g)||{},d=!0===b;!d&&(c.active&&c.active[b])&&(c.totalActive--,delete c.active[b]);
|
||||
if(d||!c.totalActive)a.removeClass(I),a.removeData(g)}}function N(a,b){if(h.disabled)return!0;if(e(a)==e(J))return h.running;var c,f,l;do{if(0===b.length)break;var s=e(b)==e(J),n=s?h:b.data(g)||{};if(n.disabled)return!0;s&&(l=!0);!1!==c&&(s=b.data(ga),d.isDefined(s)&&(c=s));f=f||n.running||n.last&&!n.last.isClassBased}while(b=b.parent());return!l||!c&&f}var O=0;J.data(g,h);l.$$postDigest(function(){l.$$postDigest(function(){h.running=!1})});var V=k.classNameFilter(),T=V?function(a){return V.test(a)}:
|
||||
function(){return!0};return{enter:function(a,b,c,e){a=d.element(a);b=b&&d.element(b);c=c&&d.element(c);R(a);w.enter(a,b,c);l.$$postDigest(function(){a=D(a);F("enter","ng-enter",a,b,c,p,e)})},leave:function(a,b){a=d.element(a);U(a);R(a);l.$$postDigest(function(){F("leave","ng-leave",D(a),null,null,function(){w.leave(a)},b)})},move:function(a,b,c,e){a=d.element(a);b=b&&d.element(b);c=c&&d.element(c);U(a);R(a);w.move(a,b,c);l.$$postDigest(function(){a=D(a);F("move","ng-move",a,b,c,p,e)})},addClass:function(a,
|
||||
b,c){a=d.element(a);a=D(a);F("addClass",b,a,null,null,function(){w.addClass(a,b)},c)},removeClass:function(a,b,c){a=d.element(a);a=D(a);F("removeClass",b,a,null,null,function(){w.removeClass(a,b)},c)},setClass:function(a,b,c,e){a=d.element(a);a=D(a);F("setClass",[b,c],a,null,null,function(){w.setClass(a,b,c)},e)},enabled:function(a,b){switch(arguments.length){case 2:if(a)A(b);else{var c=b.data(g)||{};c.disabled=!0;b.data(g,c)}break;case 1:h.disabled=!a;break;default:a=!h.disabled}return!!a}}}]);k.register("",
|
||||
["$window","$sniffer","$timeout","$$animateReflow",function(g,h,k,J){function K(){L||(L=J(function(){S=[];L=null;t={}}))}function l(a,W){L&&L();S.push(W);L=J(function(){x(S,function(a){a()});S=[];L=null;t={}})}function D(a,W){var b=e(a);a=d.element(b);X.push(a);b=Date.now()+W;b<=fa||(k.cancel(ea),fa=b,ea=k(function(){R(X);X=[]},W,!1))}function R(a){x(a,function(a){(a=a.data(v))&&(a.closeAnimationFn||p)()})}function I(a,b){var c=b?t[b]:null;if(!c){var e=0,d=0,f=0,l=0,h,Y,Z,k;x(a,function(a){if(a.nodeType==
|
||||
aa){a=g.getComputedStyle(a)||{};Z=a[n+Q];e=Math.max(M(Z),e);k=a[n+u];h=a[n+y];d=Math.max(M(h),d);Y=a[r+y];l=Math.max(M(Y),l);var b=M(a[r+Q]);0<b&&(b*=parseInt(a[r+m],10)||1);f=Math.max(b,f)}});c={total:0,transitionPropertyStyle:k,transitionDurationStyle:Z,transitionDelayStyle:h,transitionDelay:d,transitionDuration:e,animationDelayStyle:Y,animationDelay:l,animationDuration:f};b&&(t[b]=c)}return c}function M(a){var b=0;a=d.isString(a)?a.split(/\s*,\s*/):[];x(a,function(a){b=Math.max(parseFloat(a)||
|
||||
0,b)});return b}function F(a){var b=a.parent(),c=b.data(z);c||(b.data(z,++da),c=da);return c+"-"+e(a).getAttribute("class")}function U(a,b,c,d){var f=F(b),g=f+" "+c,l=t[g]?++t[g].total:0,h={};if(0<l){var k=c+"-stagger",h=f+" "+k;(f=!t[h])&&b.addClass(k);h=I(b,h);f&&b.removeClass(k)}d=d||function(a){return a()};b.addClass(c);var k=b.data(v)||{},m=d(function(){return I(b,g)});d=m.transitionDuration;f=m.animationDuration;if(0===d&&0===f)return b.removeClass(c),!1;b.data(v,{running:k.running||0,itemIndex:l,
|
||||
stagger:h,timings:m,closeAnimationFn:p});a=0<k.running||"setClass"==a;0<d&&A(b,c,a);0<f&&(0<h.animationDelay&&0===h.animationDuration)&&(e(b).style[r]="none 0s");return!0}function A(a,b,c){"ng-enter"!=b&&("ng-move"!=b&&"ng-leave"!=b)&&c?a.addClass(ca):e(a).style[n+u]="none"}function N(a,b){var c=n+u,d=e(a);d.style[c]&&0<d.style[c].length&&(d.style[c]="");a.removeClass(ca)}function O(a){var b=r;a=e(a);a.style[b]&&0<a.style[b].length&&(a.style[b]="")}function V(a,b,c,d){function g(a){b.off(w,h);b.removeClass(l);
|
||||
f(b,c);a=e(b);for(var d in t)a.style.removeProperty(t[d])}function h(a){a.stopPropagation();var b=a.originalEvent||a;a=b.$manualTimeStamp||Date.now();b=parseFloat(b.elapsedTime.toFixed(B));Math.max(a-z,0)>=y&&b>=r&&d()}var k=e(b);a=b.data(v);if(-1!=k.getAttribute("class").indexOf(c)&&a){var l="";x(c.split(" "),function(a,b){l+=(0<b?" ":"")+a+"-active"});var m=a.stagger,n=a.timings,p=a.itemIndex,r=Math.max(n.transitionDuration,n.animationDuration),u=Math.max(n.transitionDelay,n.animationDelay),y=u*
|
||||
ba,z=Date.now(),w=E+" "+H,q="",t=[];if(0<n.transitionDuration){var A=n.transitionPropertyStyle;-1==A.indexOf("all")&&(q+=s+"transition-property: "+A+";",q+=s+"transition-duration: "+n.transitionDurationStyle+";",t.push(s+"transition-property"),t.push(s+"transition-duration"))}0<p&&(0<m.transitionDelay&&0===m.transitionDuration&&(q+=s+"transition-delay: "+T(n.transitionDelayStyle,m.transitionDelay,p)+"; ",t.push(s+"transition-delay")),0<m.animationDelay&&0===m.animationDuration&&(q+=s+"animation-delay: "+
|
||||
T(n.animationDelayStyle,m.animationDelay,p)+"; ",t.push(s+"animation-delay")));0<t.length&&(n=k.getAttribute("style")||"",k.setAttribute("style",n+"; "+q));b.on(w,h);b.addClass(l);a.closeAnimationFn=function(){g();d()};k=(p*(Math.max(m.animationDelay,m.transitionDelay)||0)+(u+r)*C)*ba;a.running++;D(b,k);return g}d()}function T(a,b,c){var d="";x(a.split(","),function(a,e){d+=(0<e?",":"")+(c*b+parseInt(a,10))+"s"});return d}function a(a,b,c,d){if(U(a,b,c,d))return function(a){a&&f(b,c)}}function b(a,
|
||||
b,c,d){if(b.data(v))return V(a,b,c,d);f(b,c);d()}function c(c,d,e,f){var g=a(c,d,e);if(g){var h=g;l(d,function(){N(d,e);O(d);h=b(c,d,e,f)});return function(a){(h||p)(a)}}K();f()}function f(a,b){a.removeClass(b);var c=a.data(v);c&&(c.running&&c.running--,c.running&&0!==c.running||a.removeData(v))}function q(a,b){var c="";a=d.isArray(a)?a:a.split(/\s+/);x(a,function(a,d){a&&0<a.length&&(c+=(0<d?" ":"")+a+b)});return c}var s="",n,H,r,E;G.ontransitionend===P&&G.onwebkittransitionend!==P?(s="-webkit-",
|
||||
n="WebkitTransition",H="webkitTransitionEnd transitionend"):(n="transition",H="transitionend");G.onanimationend===P&&G.onwebkitanimationend!==P?(s="-webkit-",r="WebkitAnimation",E="webkitAnimationEnd animationend"):(r="animation",E="animationend");var Q="Duration",u="Property",y="Delay",m="IterationCount",z="$$ngAnimateKey",v="$$ngAnimateCSS3Data",ca="ng-animate-block-transitions",B=3,C=1.5,ba=1E3,t={},da=0,S=[],L,ea=null,fa=0,X=[];return{enter:function(a,b){return c("enter",a,"ng-enter",b)},leave:function(a,
|
||||
b){return c("leave",a,"ng-leave",b)},move:function(a,b){return c("move",a,"ng-move",b)},beforeSetClass:function(b,c,d,e){var f=q(d,"-remove")+" "+q(c,"-add"),g=a("setClass",b,f,function(a){var e=b.attr("class");b.removeClass(d);b.addClass(c);a=a();b.attr("class",e);return a});if(g)return l(b,function(){N(b,f);O(b);e()}),g;K();e()},beforeAddClass:function(b,c,d){var e=a("addClass",b,q(c,"-add"),function(a){b.addClass(c);a=a();b.removeClass(c);return a});if(e)return l(b,function(){N(b,c);O(b);d()}),
|
||||
e;K();d()},setClass:function(a,c,d,e){d=q(d,"-remove");c=q(c,"-add");return b("setClass",a,d+" "+c,e)},addClass:function(a,c,d){return b("addClass",a,q(c,"-add"),d)},beforeRemoveClass:function(b,c,d){var e=a("removeClass",b,q(c,"-remove"),function(a){var d=b.attr("class");b.removeClass(c);a=a();b.attr("class",d);return a});if(e)return l(b,function(){N(b,c);O(b);d()}),e;d()},removeClass:function(a,c,d){return b("removeClass",a,q(c,"-remove"),d)}}}])}])})(window,window.angular);
|
||||
//# sourceMappingURL=angular-animate.min.js.map
|
||||
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "angular-animate",
|
||||
"version": "1.2.32",
|
||||
"license": "MIT",
|
||||
"main": "./angular-animate.js",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"angular": "1.2.32"
|
||||
}
|
||||
}
|
||||
2
server/public/lib/angular-animate/index.js
vendored
@ -1,2 +0,0 @@
|
||||
require('./angular-animate');
|
||||
module.exports = 'ngAnimate';
|
||||
@ -1,33 +0,0 @@
|
||||
{
|
||||
"name": "angular-animate",
|
||||
"version": "1.2.32",
|
||||
"description": "AngularJS module for animations",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"angular",
|
||||
"framework",
|
||||
"browser",
|
||||
"animation",
|
||||
"client-side"
|
||||
],
|
||||
"author": "Angular Core Team <angular-core+npm@google.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/angular/angular.js/issues"
|
||||
},
|
||||
"homepage": "http://angularjs.org",
|
||||
"jspm": {
|
||||
"shim": {
|
||||
"angular-animate": {
|
||||
"deps": ["angular"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "https://github.com/angular-ui/bootstrap/graphs/contributors"
|
||||
},
|
||||
"name": "angular-bootstrap",
|
||||
"version": "0.10.0",
|
||||
"main": [
|
||||
"./ui-bootstrap-tpls.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1"
|
||||
},
|
||||
"homepage": "https://github.com/angular-ui/bootstrap-bower",
|
||||
"_release": "0.10.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.10.0",
|
||||
"commit": "f486d33d6f4c60d905ed0792eacbba2456a32b87"
|
||||
},
|
||||
"_source": "https://github.com/angular-ui/bootstrap-bower.git",
|
||||
"_target": "~0.10.0",
|
||||
"_originalSource": "angular-bootstrap"
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "https://github.com/angular-ui/bootstrap/graphs/contributors"
|
||||
},
|
||||
"name": "angular-bootstrap",
|
||||
"version": "0.10.0",
|
||||
"main": ["./ui-bootstrap-tpls.js"],
|
||||
"dependencies": {
|
||||
"angular": ">=1"
|
||||
}
|
||||
}
|
||||
3677
server/public/lib/angular-bootstrap/ui-bootstrap-tpls.js
vendored
3427
server/public/lib/angular-bootstrap/ui-bootstrap.js
vendored
@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "angular-gettext",
|
||||
"version": "1.1.4",
|
||||
"main": "dist/angular-gettext.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"src",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"genplurals.py",
|
||||
"Gruntfile.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jquery": ">=1.8.0",
|
||||
"angular-mocks": ">=1.2.0"
|
||||
},
|
||||
"homepage": "https://github.com/rubenv/angular-gettext",
|
||||
"_release": "1.1.4",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.1.4",
|
||||
"commit": "8bc3a498bc94a19b7106e6e25faab0cc9ce4cea3"
|
||||
},
|
||||
"_source": "https://github.com/rubenv/angular-gettext.git",
|
||||
"_target": "~1.1.0",
|
||||
"_originalSource": "angular-gettext"
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2013-2014 by Ruben Vermeersch <ruben@rocketeer.be>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@ -1,31 +0,0 @@
|
||||
# angular-gettext - gettext utilities for angular.js
|
||||
|
||||
> Translate your Angular.JS applications with gettext.
|
||||
|
||||
[](https://travis-ci.org/rubenv/angular-gettext)
|
||||
|
||||
Check the website for usage instructions: [http://angular-gettext.rocketeer.be/](http://angular-gettext.rocketeer.be/).
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (C) 2013-2014 by Ruben Vermeersch <ruben@rocketeer.be>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "angular-gettext",
|
||||
"version": "1.1.4",
|
||||
"main": "dist/angular-gettext.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"src",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"genplurals.py",
|
||||
"Gruntfile.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jquery": ">=1.8.0",
|
||||
"angular-mocks": ">=1.2.0"
|
||||
}
|
||||
}
|
||||
@ -1,294 +0,0 @@
|
||||
angular.module('gettext', []);
|
||||
|
||||
angular.module('gettext').constant('gettext', function (str) {
|
||||
/*
|
||||
* Does nothing, simply returns the input string.
|
||||
*
|
||||
* This function serves as a marker for `grunt-angular-gettext` to know that
|
||||
* this string should be extracted for translations.
|
||||
*/
|
||||
return str;
|
||||
});
|
||||
|
||||
angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", "$cacheFactory", "$interpolate", "$rootScope", function (gettextPlurals, $http, $cacheFactory, $interpolate, $rootScope) {
|
||||
var catalog;
|
||||
|
||||
var prefixDebug = function (string) {
|
||||
if (catalog.debug && catalog.currentLanguage !== catalog.baseLanguage) {
|
||||
return catalog.debugPrefix + string;
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
var addTranslatedMarkers = function (string) {
|
||||
if (catalog.showTranslatedMarkers) {
|
||||
return catalog.translatedMarkerPrefix + string + catalog.translatedMarkerSuffix;
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
function broadcastUpdated() {
|
||||
$rootScope.$broadcast('gettextLanguageChanged');
|
||||
}
|
||||
|
||||
catalog = {
|
||||
debug: false,
|
||||
debugPrefix: '[MISSING]: ',
|
||||
showTranslatedMarkers: false,
|
||||
translatedMarkerPrefix: '[',
|
||||
translatedMarkerSuffix: ']',
|
||||
strings: {},
|
||||
baseLanguage: 'en',
|
||||
currentLanguage: 'en',
|
||||
cache: $cacheFactory('strings'),
|
||||
|
||||
setCurrentLanguage: function (lang) {
|
||||
this.currentLanguage = lang;
|
||||
broadcastUpdated();
|
||||
},
|
||||
|
||||
setStrings: function (language, strings) {
|
||||
if (!this.strings[language]) {
|
||||
this.strings[language] = {};
|
||||
}
|
||||
|
||||
for (var key in strings) {
|
||||
var val = strings[key];
|
||||
if (typeof val === 'string') {
|
||||
this.strings[language][key] = [val];
|
||||
} else {
|
||||
this.strings[language][key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
broadcastUpdated();
|
||||
},
|
||||
|
||||
getStringForm: function (string, n) {
|
||||
var stringTable = this.strings[this.currentLanguage] || {};
|
||||
var plurals = stringTable[string] || [];
|
||||
return plurals[n];
|
||||
},
|
||||
|
||||
getString: function (string, context) {
|
||||
string = this.getStringForm(string, 0) || prefixDebug(string);
|
||||
string = context ? $interpolate(string)(context) : string;
|
||||
return addTranslatedMarkers(string);
|
||||
},
|
||||
|
||||
getPlural: function (n, string, stringPlural, context) {
|
||||
var form = gettextPlurals(this.currentLanguage, n);
|
||||
string = this.getStringForm(string, form) || prefixDebug(n === 1 ? string : stringPlural);
|
||||
string = context ? $interpolate(string)(context) : string;
|
||||
return addTranslatedMarkers(string);
|
||||
},
|
||||
|
||||
loadRemote: function (url) {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: url,
|
||||
cache: catalog.cache
|
||||
}).success(function (data) {
|
||||
for (var lang in data) {
|
||||
catalog.setStrings(lang, data[lang]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return catalog;
|
||||
}]);
|
||||
|
||||
angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$animate", "$compile", function (gettextCatalog, $parse, $animate, $compile) {
|
||||
// Trim polyfill for old browsers (instead of jQuery)
|
||||
// Based on AngularJS-v1.2.2 (angular.js#620)
|
||||
var trim = (function () {
|
||||
if (!String.prototype.trim) {
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
||||
};
|
||||
}
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.trim() : value;
|
||||
};
|
||||
})();
|
||||
|
||||
function assert(condition, missing, found) {
|
||||
if (!condition) {
|
||||
throw new Error('You should add a ' + missing + ' attribute whenever you add a ' + found + ' attribute.');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
terminal: true,
|
||||
compile: function compile(element, attrs) {
|
||||
// Validate attributes
|
||||
assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
|
||||
assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
|
||||
|
||||
var msgid = trim(element.html());
|
||||
var translatePlural = attrs.translatePlural;
|
||||
|
||||
return {
|
||||
post: function (scope, element, attrs) {
|
||||
var countFn = $parse(attrs.translateN);
|
||||
var pluralScope = null;
|
||||
|
||||
function update() {
|
||||
// Fetch correct translated string.
|
||||
var translated;
|
||||
if (translatePlural) {
|
||||
scope = pluralScope || (pluralScope = scope.$new());
|
||||
scope.$count = countFn(scope);
|
||||
translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural);
|
||||
} else {
|
||||
translated = gettextCatalog.getString(msgid);
|
||||
}
|
||||
|
||||
// Swap in the translation
|
||||
var newWrapper = angular.element('<span>' + translated + '</span>');
|
||||
$compile(newWrapper.contents())(scope);
|
||||
var oldContents = element.contents();
|
||||
var newContents = newWrapper.contents();
|
||||
$animate.enter(newContents, element);
|
||||
$animate.leave(oldContents);
|
||||
}
|
||||
|
||||
if (attrs.translateN) {
|
||||
scope.$watch(attrs.translateN, update);
|
||||
}
|
||||
|
||||
scope.$on('gettextLanguageChanged', update);
|
||||
|
||||
update();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
angular.module('gettext').filter('translate', ["gettextCatalog", function (gettextCatalog) {
|
||||
function filter(input) {
|
||||
return gettextCatalog.getString(input);
|
||||
}
|
||||
filter.$stateful = true;
|
||||
return filter;
|
||||
}]);
|
||||
|
||||
// Do not edit this file, it is autogenerated using genplurals.py!
|
||||
angular.module("gettext").factory("gettextPlurals", function () {
|
||||
return function (langCode, n) {
|
||||
switch (langCode) {
|
||||
case "ay": // Aymará
|
||||
case "bo": // Tibetan
|
||||
case "cgg": // Chiga
|
||||
case "dz": // Dzongkha
|
||||
case "fa": // Persian
|
||||
case "id": // Indonesian
|
||||
case "ja": // Japanese
|
||||
case "jbo": // Lojban
|
||||
case "ka": // Georgian
|
||||
case "kk": // Kazakh
|
||||
case "km": // Khmer
|
||||
case "ko": // Korean
|
||||
case "ky": // Kyrgyz
|
||||
case "lo": // Lao
|
||||
case "ms": // Malay
|
||||
case "my": // Burmese
|
||||
case "sah": // Yakut
|
||||
case "su": // Sundanese
|
||||
case "th": // Thai
|
||||
case "tt": // Tatar
|
||||
case "ug": // Uyghur
|
||||
case "vi": // Vietnamese
|
||||
case "wo": // Wolof
|
||||
case "zh": // Chinese
|
||||
// 1 form
|
||||
return 0;
|
||||
case "is": // Icelandic
|
||||
// 2 forms
|
||||
return (n%10!=1 || n%100==11) ? 1 : 0;
|
||||
case "jv": // Javanese
|
||||
// 2 forms
|
||||
return n!=0 ? 1 : 0;
|
||||
case "mk": // Macedonian
|
||||
// 2 forms
|
||||
return n==1 || n%10==1 ? 0 : 1;
|
||||
case "ach": // Acholi
|
||||
case "ak": // Akan
|
||||
case "am": // Amharic
|
||||
case "arn": // Mapudungun
|
||||
case "br": // Breton
|
||||
case "fil": // Filipino
|
||||
case "fr": // French
|
||||
case "gun": // Gun
|
||||
case "ln": // Lingala
|
||||
case "mfe": // Mauritian Creole
|
||||
case "mg": // Malagasy
|
||||
case "mi": // Maori
|
||||
case "oc": // Occitan
|
||||
case "pt_BR": // Brazilian Portuguese
|
||||
case "tg": // Tajik
|
||||
case "ti": // Tigrinya
|
||||
case "tr": // Turkish
|
||||
case "uz": // Uzbek
|
||||
case "wa": // Walloon
|
||||
case "zh": // Chinese
|
||||
// 2 forms
|
||||
return n>1 ? 1 : 0;
|
||||
case "lv": // Latvian
|
||||
// 3 forms
|
||||
return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);
|
||||
case "lt": // Lithuanian
|
||||
// 3 forms
|
||||
return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);
|
||||
case "be": // Belarusian
|
||||
case "bs": // Bosnian
|
||||
case "hr": // Croatian
|
||||
case "ru": // Russian
|
||||
case "sr": // Serbian
|
||||
case "uk": // Ukrainian
|
||||
// 3 forms
|
||||
return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
|
||||
case "mnk": // Mandinka
|
||||
// 3 forms
|
||||
return (n==0 ? 0 : n==1 ? 1 : 2);
|
||||
case "ro": // Romanian
|
||||
// 3 forms
|
||||
return (n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);
|
||||
case "pl": // Polish
|
||||
// 3 forms
|
||||
return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
|
||||
case "cs": // Czech
|
||||
case "sk": // Slovak
|
||||
// 3 forms
|
||||
return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;
|
||||
case "sl": // Slovenian
|
||||
// 4 forms
|
||||
return (n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);
|
||||
case "mt": // Maltese
|
||||
// 4 forms
|
||||
return (n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3);
|
||||
case "gd": // Scottish Gaelic
|
||||
// 4 forms
|
||||
return (n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;
|
||||
case "cy": // Welsh
|
||||
// 4 forms
|
||||
return (n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;
|
||||
case "kw": // Cornish
|
||||
// 4 forms
|
||||
return (n==1) ? 0 : (n==2) ? 1 : (n == 3) ? 2 : 3;
|
||||
case "ga": // Irish
|
||||
// 5 forms
|
||||
return n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4;
|
||||
case "ar": // Arabic
|
||||
// 6 forms
|
||||
return (n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5);
|
||||
default: // Everything else
|
||||
return n != 1 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1 +0,0 @@
|
||||
angular.module("gettext",[]),angular.module("gettext").constant("gettext",function(a){return a}),angular.module("gettext").factory("gettextCatalog",["gettextPlurals","$http","$cacheFactory","$interpolate","$rootScope",function(a,b,c,d,e){function f(){e.$broadcast("gettextLanguageChanged")}var g,h=function(a){return g.debug&&g.currentLanguage!==g.baseLanguage?g.debugPrefix+a:a},i=function(a){return g.showTranslatedMarkers?g.translatedMarkerPrefix+a+g.translatedMarkerSuffix:a};return g={debug:!1,debugPrefix:"[MISSING]: ",showTranslatedMarkers:!1,translatedMarkerPrefix:"[",translatedMarkerSuffix:"]",strings:{},baseLanguage:"en",currentLanguage:"en",cache:c("strings"),setCurrentLanguage:function(a){this.currentLanguage=a,f()},setStrings:function(a,b){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];this.strings[a][c]="string"==typeof d?[d]:d}f()},getStringForm:function(a,b){var c=this.strings[this.currentLanguage]||{},d=c[a]||[];return d[b]},getString:function(a,b){return a=this.getStringForm(a,0)||h(a),a=b?d(a)(b):a,i(a)},getPlural:function(b,c,e,f){var g=a(this.currentLanguage,b);return c=this.getStringForm(c,g)||h(1===b?c:e),c=f?d(c)(f):c,i(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:g.cache}).success(function(a){for(var b in a)g.setStrings(b,a[b])})}}}]),angular.module("gettext").directive("translate",["gettextCatalog","$parse","$animate","$compile",function(a,b,c,d){function e(a,b,c){if(!a)throw new Error("You should add a "+b+" attribute whenever you add a "+c+" attribute.")}var f=function(){return String.prototype.trim?function(a){return"string"==typeof a?a.trim():a}:function(a){return"string"==typeof a?a.replace(/^\s*/,"").replace(/\s*$/,""):a}}();return{restrict:"A",terminal:!0,compile:function(g,h){e(!h.translatePlural||h.translateN,"translate-n","translate-plural"),e(!h.translateN||h.translatePlural,"translate-plural","translate-n");var i=f(g.html()),j=h.translatePlural;return{post:function(e,f,g){function h(){var b;j?(e=l||(l=e.$new()),e.$count=k(e),b=a.getPlural(e.$count,i,j)):b=a.getString(i);var g=angular.element("<span>"+b+"</span>");d(g.contents())(e);var h=f.contents(),m=g.contents();c.enter(m,f),c.leave(h)}var k=b(g.translateN),l=null;g.translateN&&e.$watch(g.translateN,h),e.$on("gettextLanguageChanged",h),h()}}}}}]),angular.module("gettext").filter("translate",["gettextCatalog",function(a){function b(b){return a.getString(b)}return b.$stateful=!0,b}]),angular.module("gettext").factory("gettextPlurals",function(){return function(a,b){switch(a){case"ay":case"bo":case"cgg":case"dz":case"fa":case"id":case"ja":case"jbo":case"ka":case"kk":case"km":case"ko":case"ky":case"lo":case"ms":case"my":case"sah":case"su":case"th":case"tt":case"ug":case"vi":case"wo":case"zh":return 0;case"is":return b%10!=1||b%100==11?1:0;case"jv":return 0!=b?1:0;case"mk":return 1==b||b%10==1?0:1;case"ach":case"ak":case"am":case"arn":case"br":case"fil":case"fr":case"gun":case"ln":case"mfe":case"mg":case"mi":case"oc":case"pt_BR":case"tg":case"ti":case"tr":case"uz":case"wa":case"zh":return b>1?1:0;case"lv":return b%10==1&&b%100!=11?0:0!=b?1:2;case"lt":return b%10==1&&b%100!=11?0:b%10>=2&&(10>b%100||b%100>=20)?1:2;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return b%10==1&&b%100!=11?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"mnk":return 0==b?0:1==b?1:2;case"ro":return 1==b?0:0==b||b%100>0&&20>b%100?1:2;case"pl":return 1==b?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"cs":case"sk":return 1==b?0:b>=2&&4>=b?1:2;case"sl":return b%100==1?1:b%100==2?2:b%100==3||b%100==4?3:0;case"mt":return 1==b?0:0==b||b%100>1&&11>b%100?1:b%100>10&&20>b%100?2:3;case"gd":return 1==b||11==b?0:2==b||12==b?1:b>2&&20>b?2:3;case"cy":return 1==b?0:2==b?1:8!=b&&11!=b?2:3;case"kw":return 1==b?0:2==b?1:3==b?2:3;case"ga":return 1==b?0:2==b?1:7>b?2:11>b?3:4;case"ar":return 0==b?0:1==b?1:2==b?2:b%100>=3&&10>=b%100?3:b%100>=11?4:5;default:return 1!=b?1:0}}});
|
||||
@ -1,48 +0,0 @@
|
||||
{
|
||||
"name": "angular-gettext",
|
||||
"version": "1.1.4",
|
||||
"description": "Gettext support for Angular.js",
|
||||
"main": "dist/angular-gettext.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt ci",
|
||||
"prepublish": "grunt build"
|
||||
},
|
||||
"keywords": [
|
||||
"angular",
|
||||
"gettext"
|
||||
],
|
||||
"author": {
|
||||
"name": "Ruben Vermeersch",
|
||||
"email": "ruben@rocketeer.be",
|
||||
"url": "http://rocketeer.be/"
|
||||
},
|
||||
"homepage": "http://angular-gettext.rocketeer.be/",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-bump": "0.0.13",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-connect": "~0.7.1",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-contrib-uglify": "~0.4.0",
|
||||
"grunt-contrib-watch": "~0.5.1",
|
||||
"grunt-jscs": "^0.6.2",
|
||||
"grunt-karma": "~0.8.3",
|
||||
"grunt-ng-annotate": "^0.3.2",
|
||||
"karma": "~0.12.16",
|
||||
"karma-chai": "~0.1.0",
|
||||
"karma-firefox-launcher": "~0.1.0",
|
||||
"karma-junit-reporter": "~0.2.2",
|
||||
"karma-mocha": "~0.1.0",
|
||||
"karma-ng-scenario": "~0.1.0",
|
||||
"karma-phantomjs-launcher": "^0.1.4"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/rubenv/angular-gettext.git"
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "angular-moment",
|
||||
"version": "0.8.3",
|
||||
"description": "Moment.JS directives & filters for Angular.JS (timeago alternative)",
|
||||
"author": "Uri Shaked",
|
||||
"license": "MIT",
|
||||
"homepage": "http://github.com/urish/angular-moment",
|
||||
"main": "./angular-moment.js",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"angular": ">=1.0.0 <1.4.0",
|
||||
"moment": ">=2.0.0 <2.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "1.2.x",
|
||||
"moment-timezone": "0.2.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/urish/angular-moment.git"
|
||||
},
|
||||
"_release": "0.8.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.8.3",
|
||||
"commit": "585547e63f9170a39fe631590b3ef2827666efec"
|
||||
},
|
||||
"_source": "https://github.com/urish/angular-moment.git",
|
||||
"_target": "~0.8.0",
|
||||
"_originalSource": "angular-moment"
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[{package.json,bower.json}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
4
server/public/lib/angular-moment/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
/.idea
|
||||
/bower_components
|
||||
/node_modules
|
||||
/coverage
|
||||
@ -1,26 +0,0 @@
|
||||
{
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"esnext": true,
|
||||
"bitwise": true,
|
||||
"camelcase": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"indent": 2,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"quotmark": "single",
|
||||
"regexp": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"strict": true,
|
||||
"trailing": true,
|
||||
"smarttabs": true,
|
||||
"maxdepth": 2,
|
||||
"maxcomplexity": 10,
|
||||
"globals": {
|
||||
"angular": false
|
||||
}
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
.idea
|
||||
bower_components
|
||||
node_modules
|
||||
coverage
|
||||
@ -1,8 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
before_script:
|
||||
- npm install -g bower@1.3.x grunt-cli
|
||||
- bower install
|
||||
after_success:
|
||||
- cat ./coverage/*/lcov.info | ./node_modules/coveralls/bin/coveralls.js
|
||||
@ -1,102 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## 0.8.3 - 2014-12-08
|
||||
- `amTimeAgo` filter ([#96](https://github.com/urish/angular-moment/pull/96), contributed by [maxklenk](https://github.com/maxklenk))
|
||||
- Show formatted time as element title ([#78](https://github.com/urish/angular-moment/pull/78), contributed by [ctesene](https://github.com/ctesene))
|
||||
- Support commonjs and browserify ([#95](https://github.com/urish/angular-moment/pull/95), contributed by [Pencroff](https://github.com/Pencroff))
|
||||
- SystemJS Loader support ([#85](https://github.com/urish/angular-moment/pull/85), contributed by [capaj](https://github.com/capaj))
|
||||
|
||||
## 0.8.2 - 2014-09-07
|
||||
- `amMoment.changeLanguage()` was deprecated in favor of `amMoment.changeLocale()` (following [a change](http://momentjs.com/docs/#/i18n/changing-locale/) introduced in moment v2.8.1)
|
||||
- Bugfix: changing the locale emitted a deprecation warning (see [#76](https://github.com/urish/angular-moment/issues/76) for details).
|
||||
|
||||
## 0.8.1 - 2014-09-01
|
||||
- Support moment.js v2.8.0. See [here](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4) for changelog.
|
||||
- Support moment-timezone v0.2.1. See [here](https://github.com/moment/moment-timezone/blob/develop/changelog.md#021-2014-08-02) for changelog.
|
||||
- Bugfix: `updateTime()` is called too often for future dates ([#73](https://github.com/urish/angular-moment/issues/73))
|
||||
|
||||
## 0.8.0 - 2014-07-26
|
||||
- Generate source map for the minified version ([#50](https://github.com/urish/angular-moment/issues/50))
|
||||
- Add support HTML `<time>` element - set the `datetime` attribute ([#41](https://github.com/urish/angular-moment/pull/41), contributed by [gsklee](https://github.com/gsklee))
|
||||
- Add default format (angularMomentConfig.format config property) ([#52](https://github.com/urish/angular-moment/pull/52), contributed by [otang](https://github.com/otang))
|
||||
- Add `serverTime` configuration option ([#53](https://github.com/urish/angular-moment/pull/53), contributed by [Facundo Pedrazzini](https://github.com/Facuu7))
|
||||
- Implement one-time binding for `am-time-ago` ([#54](https://github.com/urish/angular-moment/pull/54), contributed by [Ephi Gabay](https://github.com/ephigabay))
|
||||
- Support moment.js v2.7.0. See [here](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7) for changelog.
|
||||
- Support moment-timezone v0.1.0. See [here](https://github.com/moment/moment-timezone/blob/develop/changelog.md#010-2014-06-23) for changelog.
|
||||
|
||||
## 0.7.1 - 2014-05-16
|
||||
- bugfix: Preprocess set in configuration not used by filters ([#49](https://github.com/urish/angular-moment/issues/49))
|
||||
|
||||
## 0.7.0 - 2014-04-19
|
||||
- Use `moment` as an injectable constant instead of relying on `$window.moment` ([#35](https://github.com/urish/angular-moment/pull/35), contributed by [just-boris](https://github.com/just-boris))
|
||||
- Require.js support ([#36](https://github.com/urish/angular-moment/issues/36))
|
||||
- Add am-preprocess attribute to support unix and utc timestamps ([#38](https://github.com/urish/angular-moment/pull/38), contributed by [jspaper](https://github.com/jspaper))
|
||||
- NGDoc documentation ([#40](https://github.com/urish/angular-moment/issues/40))
|
||||
- Enable support for AngularJS 1.3.x in bower.json
|
||||
- Support moment.js v2.6.0. See [here](https://gist.github.com/ichernev/10544682) for changelog.
|
||||
|
||||
## 0.6.2 - 2014-02-05
|
||||
- Add `amMoment` service with a `changeLanguage()` method ([#32](https://github.com/urish/angular-moment/pull/32), contributed by [Ornthalas](https://github.com/Ornthalas))
|
||||
- bower.json: Move `moment-timezone` to devDependencies (fixes [#34](https://github.com/urish/angular-moment/issues/34))
|
||||
|
||||
## 0.6.1 - 2014-01-31
|
||||
- Add optional timezone support to `amCalendar` and `amDateFormat` filters ([#27](https://github.com/urish/angular-moment/pull/27), contributed by [kayhadrin](https://github.com/kayhadrin))
|
||||
- Happy Year of the Horse!
|
||||
|
||||
## 0.6.0 - 2013-12-24
|
||||
|
||||
- Add optional `am-without-suffix` attribute to `am-time-ago` ([#22](https://github.com/urish/angular-moment/issues/22), contributed by [hramaker](https://github.com/hramaker))
|
||||
- Support moment.js v2.5.0. See [here](https://gist.github.com/ichernev/8104451) for changelog.
|
||||
- Merry Christmas!
|
||||
|
||||
## 0.5.2 - 2013-11-17
|
||||
|
||||
- Add `amCalendar` filter ([#24](https://github.com/urish/angular-moment/issues/24), contributed by [OndraM](https://github.com/OndraM))
|
||||
|
||||
## 0.5.1 - 2013-11-09
|
||||
|
||||
- Add `amDuration` filter ([#20](https://github.com/urish/angular-moment/issues/20), contributed by [gabrielstuff](https://github.com/gabrielstuff))
|
||||
|
||||
## 0.5.0 - 2013-11-02
|
||||
|
||||
- Use $window.setTimeout instead of $timeout, fixes protractor synchronization issue ([#19](https://github.com/urish/angular-moment/issues/19))
|
||||
|
||||
## 0.4.2 - 2013-10-30
|
||||
|
||||
- Add settings constant for configuring moment.js withoutSuffix-option ([#18](https://github.com/urish/angular-moment/pull/18))
|
||||
|
||||
## 0.4.1 - 2013-10-27
|
||||
|
||||
- Support moment.js v2.4.0. See [here](https://github.com/moment/moment/#240) for changelog.
|
||||
|
||||
## 0.4.0 - 2013-10-08
|
||||
|
||||
- Support moment.js v2.3.0. See [here](https://gist.github.com/ichernev/6864354) for possibly breaking changes.
|
||||
|
||||
## 0.3.0 - 2013-10-07
|
||||
|
||||
- Bugfix: `am-time-ago` support for empty string ([#15](https://github.com/urish/angular-moment/issues/15))
|
||||
- Behavior change: `am-time-ago` will only change the text once there is date
|
||||
|
||||
## 0.2.2 - 2013-09-29
|
||||
|
||||
- Add support for passing unix timestamp as a string to `amDateFormat` filter ([#14](https://github.com/urish/angular-moment/issues/14))
|
||||
|
||||
## 0.2.1 - 2013-09-13
|
||||
|
||||
- Fix an issue with tests failing on a different timezone
|
||||
- Support moment 2.2.x, AngularJS 1.2
|
||||
|
||||
## 0.2.0 - 2013-08-22
|
||||
|
||||
- Add optional `am-format` attribute to `am-time-ago` ([#11](https://github.com/urish/angular-moment/issues/11))
|
||||
- Add new `amDateFormat` filter ([#12](https://github.com/urish/angular-moment/issues/12))
|
||||
- Add changelog file
|
||||
|
||||
## 0.1.1 - 2013-06-08
|
||||
|
||||
- Fix to support iOS ([#2](https://github.com/urish/angular-moment/pull/2), contributed by [giuseppeaiello](https://github.com/giuseppeaiello))
|
||||
|
||||
## 0.1.0 - 2013-05-27
|
||||
|
||||
- Initial release
|
||||
@ -1,72 +0,0 @@
|
||||
# Contributing Guide
|
||||
|
||||
Contributing to `angular-moment` is fairly easy. This document shows you how to
|
||||
get the project, run all provided tests and generate a production ready build.
|
||||
|
||||
It also covers provided grunt tasks, that help you developing on `angular-moment`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
To make sure, that the following instructions work, please install the following dependencies
|
||||
on you machine:
|
||||
|
||||
- Node.js
|
||||
- npm
|
||||
- Git
|
||||
|
||||
If you install node through the binary installation file, **npm** will be already there.
|
||||
When **npm** is installed, use it to install the needed npm packages:
|
||||
|
||||
`npm install -g grunt-cli bower`
|
||||
|
||||
## Installation
|
||||
|
||||
To get the source of `angular-moment` clone the git repository via:
|
||||
|
||||
`git clone https://github.com/urish/angular-moment`
|
||||
|
||||
This will clone the complete source to your local machine. Navigate to the project folder
|
||||
and install all needed dependencies via **npm**:
|
||||
|
||||
`npm install`
|
||||
|
||||
Then install all the needed client-side dependencies via **bower**:
|
||||
|
||||
`bower install`
|
||||
|
||||
`angular-moment` is now installed and ready to be built.
|
||||
|
||||
## Building
|
||||
|
||||
`angular-moment` comes with a few **grunt tasks** which help you to automate
|
||||
the development process. The following grunt tasks are provided:
|
||||
|
||||
#### grunt test
|
||||
|
||||
`grunt test` executes (as you might thought) the unit tests, which are located
|
||||
in `tests.js`. The task uses the **karma** test runner to executes the tests with
|
||||
the **jasmine testing framework**. This task also checks the coding using **jshint**.
|
||||
|
||||
#### grunt build
|
||||
|
||||
`grunt build` updates the minified version of the code (angular-moment.min.js). It also
|
||||
checks the code using **jshint**.
|
||||
|
||||
## Contributing/Submitting changes
|
||||
|
||||
- Checkout a new branch based on `master` and name it to what you intend to do:
|
||||
- Example:
|
||||
````
|
||||
$ git checkout -b BRANCH_NAME
|
||||
````
|
||||
- Use one branch per fix/feature
|
||||
- Make your changes
|
||||
- Make sure to provide a spec for unit tests (in `tests.js`)
|
||||
- Run your tests with `grunt test`
|
||||
- When all tests pass, everything's fine
|
||||
- Commit your changes
|
||||
- Please provide a git message which explains what you've done
|
||||
- Commit to the forked repository
|
||||
- Make a pull request
|
||||
|
||||
If you follow these instructions, your PR will land pretty safety in the main repo!
|
||||
62
server/public/lib/angular-moment/Gruntfile.js
vendored
@ -1,62 +0,0 @@
|
||||
/* License: MIT.
|
||||
* Copyright (C) 2013, 2014, Uri Shaked.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function (grunt) {
|
||||
// Load grunt tasks automatically
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.initConfig({
|
||||
karma: {
|
||||
unit: {
|
||||
configFile: 'karma.conf.js',
|
||||
singleRun: true
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
all: [
|
||||
'Gruntfile.js',
|
||||
'angular-moment.js',
|
||||
'tests.js'
|
||||
]
|
||||
},
|
||||
uglify: {
|
||||
dist: {
|
||||
options: {
|
||||
sourceMap: true
|
||||
},
|
||||
files: {
|
||||
'angular-moment.min.js': 'angular-moment.js'
|
||||
}
|
||||
}
|
||||
},
|
||||
ngdocs: {
|
||||
options: {
|
||||
startPage: '/',
|
||||
title: false,
|
||||
html5Mode: false
|
||||
},
|
||||
api: {
|
||||
src: 'angular-moment.js',
|
||||
title: 'angular-moment API Documentation'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('test', [
|
||||
'jshint',
|
||||
'karma'
|
||||
]);
|
||||
|
||||
grunt.registerTask('build', [
|
||||
'jshint',
|
||||
'uglify'
|
||||
]);
|
||||
|
||||
grunt.registerTask('default', ['build']);
|
||||
};
|
||||
@ -1,147 +0,0 @@
|
||||
angular-moment
|
||||
==============
|
||||
|
||||
Angular.JS directive and filters for [Moment.JS](http://www.momentjs.com).
|
||||
|
||||
Copyright (C) 2013, 2014, Uri Shaked <uri@urish.org>
|
||||
|
||||
[](https://travis-ci.org/urish/angular-moment)
|
||||
[](https://coveralls.io/r/urish/angular-moment)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
You can choose your preferred method of installation:
|
||||
* Through bower: `bower install angular-moment --save`
|
||||
* Through npm: `npm install angular-moment --save`
|
||||
* From a CDN: [jsDelivr](https://cdn.jsdelivr.net/angular.moment/0.8.0/angular-moment.min.js) or [CDNJS](https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.8.0/angular-moment.min.js)
|
||||
* Download from github: [angular-moment.min.js](https://raw.github.com/urish/angular-moment/master/angular-moment.min.js)
|
||||
|
||||
Usage
|
||||
-----
|
||||
Include both moment.js and angular-moment.js in your application.
|
||||
|
||||
```html
|
||||
<script src="components/moment/moment.js"></script>
|
||||
<script src="components/angular-moment/angular-moment.js"></script>
|
||||
```
|
||||
|
||||
Add the module `angularMoment` as a dependency to your app module:
|
||||
|
||||
```js
|
||||
var myapp = angular.module('myapp', ['angularMoment']);
|
||||
```
|
||||
|
||||
If you need internationalization support, load specified moment.js locale file first:
|
||||
|
||||
```html
|
||||
<script src="components/moment/locale/de.js"></script>
|
||||
```
|
||||
|
||||
Then call the `amMoment.changeLocale()` method (e.g. inside your app's run() callback):
|
||||
|
||||
```js
|
||||
myapp.run(function(amMoment) {
|
||||
amMoment.changeLocale('de');
|
||||
});
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Parameter `preprocess`(e.g: `unix`, `utc`) would pre-execute before.
|
||||
|
||||
```js
|
||||
angular.module('myapp').constant('angularMomentConfig', {
|
||||
preprocess: 'unix', // optional
|
||||
timezone: 'Europe/London' // optional
|
||||
});
|
||||
```
|
||||
|
||||
### Timeago directive
|
||||
Use am-time-ago directive to format your relative timestamps. For example:
|
||||
|
||||
```html
|
||||
<span am-time-ago="message.time"></span>
|
||||
<span am-time-ago="message.time" am-preprocess="unix"></span>
|
||||
```
|
||||
|
||||
angular-moment will dynamically update the span to indicate how much time
|
||||
passed since the message was created. So, if you controller contains the following
|
||||
code:
|
||||
```js
|
||||
$scope.message = {
|
||||
text: 'hello world!',
|
||||
time: new Date()
|
||||
};
|
||||
```
|
||||
|
||||
The user will initially see "a few seconds ago", and about a minute
|
||||
after the span will automatically update with the text "a minute ago",
|
||||
etc.
|
||||
|
||||
### amDateFormat filter
|
||||
Format dates using moment.js format() method. Example:
|
||||
|
||||
```html
|
||||
<span>{{message.time | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a'}}</span>
|
||||
```
|
||||
|
||||
This snippet will format the given time as "Monday, October 7th 2013, 12:36:29 am".
|
||||
|
||||
For more information about Moment.JS formatting options, see the
|
||||
[docs for the format() function](http://momentjs.com/docs/#/displaying/format/).
|
||||
|
||||
### amCalendar filter
|
||||
|
||||
Format dates using moment.js calendar() method. Example:
|
||||
|
||||
```html
|
||||
<span>{{message.time | amCalendar}}</span>
|
||||
```
|
||||
|
||||
This snippet will format the given time as e.g. "Today 2:30 AM" or "Last Monday 2:30 AM" etc..
|
||||
|
||||
For more information about Moment.JS calendar time format, see the
|
||||
[docs for the calendar() function](http://momentjs.com/docs/#/displaying/calendar-time/).
|
||||
|
||||
### Time zone support
|
||||
|
||||
The `amDateFormat` and `amCalendar` filters can be configured to display dates aligned
|
||||
to a specific timezone. You can configure the timezone using the following syntax:
|
||||
|
||||
```js
|
||||
angular.module('myapp').constant('angularMomentConfig', {
|
||||
timezone: 'Name of Timezone' // e.g. 'Europe/London'
|
||||
});
|
||||
```
|
||||
|
||||
Remember to include `moment-timezone.js` in your project, otherwise the custom timezone
|
||||
functionality will not be available. You will also need to include a timezone data file that
|
||||
you can create using the [Timezone Data Builder](http://momentjs.com/timezone/data/)
|
||||
or simply download from [here](https://rawgithub.com/qw4n7y/7282780/raw/6ae3b334b295f93047e8f3ad300db6bc4387e235/moment-timezone-data.js).
|
||||
|
||||
License
|
||||
----
|
||||
|
||||
Released under the terms of MIT License:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
460
server/public/lib/angular-moment/angular-moment.js
vendored
@ -1,460 +0,0 @@
|
||||
/* angular-moment.js / v0.8.3 / (c) 2013, 2014 Uri Shaked / MIT Licence */
|
||||
|
||||
'format global'; /* global define */
|
||||
'deps angular';
|
||||
'deps moment';
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function angularMoment(angular, moment) {
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name angularMoment
|
||||
*
|
||||
* @description
|
||||
* angularMoment module provides moment.js functionality for angular.js apps.
|
||||
*/
|
||||
return angular.module('angularMoment', [])
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name angularMoment.config:angularMomentConfig
|
||||
*
|
||||
* @description
|
||||
* Common configuration of the angularMoment module
|
||||
*/
|
||||
.constant('angularMomentConfig', {
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.angularMomentConfig#preprocess
|
||||
* @propertyOf angularMoment.config:angularMomentConfig
|
||||
* @returns {string} The default preprocessor to apply
|
||||
*
|
||||
* @description
|
||||
* Defines a default preprocessor to apply (e.g. 'unix', 'etc', ...). The default value is null,
|
||||
* i.e. no preprocessor will be applied.
|
||||
*/
|
||||
preprocess: null, // e.g. 'unix', 'utc', ...
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.angularMomentConfig#timezone
|
||||
* @propertyOf angularMoment.config:angularMomentConfig
|
||||
* @returns {string} The default timezone
|
||||
*
|
||||
* @description
|
||||
* The default timezone (e.g. 'Europe/London'). Empty string by default (does not apply
|
||||
* any timezone shift).
|
||||
*/
|
||||
timezone: '',
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.angularMomentConfig#format
|
||||
* @propertyOf angularMoment.config:angularMomentConfig
|
||||
* @returns {string} The pre-conversion format of the date
|
||||
*
|
||||
* @description
|
||||
* Specify the format of the input date. Essentially it's a
|
||||
* default and saves you from specifying a format in every
|
||||
* element. Overridden by element attr. Null by default.
|
||||
*/
|
||||
format: null
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name angularMoment.object:moment
|
||||
*
|
||||
* @description
|
||||
* moment global (as provided by the moment.js library)
|
||||
*/
|
||||
.constant('moment', moment)
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name angularMoment.config:amTimeAgoConfig
|
||||
* @module angularMoment
|
||||
*
|
||||
* @description
|
||||
* configuration specific to the amTimeAgo directive
|
||||
*/
|
||||
.constant('amTimeAgoConfig', {
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.amTimeAgoConfig#withoutSuffix
|
||||
* @propertyOf angularMoment.config:amTimeAgoConfig
|
||||
* @returns {boolean} Whether to include a suffix in am-time-ago directive
|
||||
*
|
||||
* @description
|
||||
* Defaults to false.
|
||||
*/
|
||||
withoutSuffix: false,
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.amTimeAgoConfig#serverTime
|
||||
* @propertyOf angularMoment.config:amTimeAgoConfig
|
||||
* @returns {number} Server time in milliseconds since the epoch
|
||||
*
|
||||
* @description
|
||||
* If set, time ago will be calculated relative to the given value.
|
||||
* If null, local time will be used. Defaults to null.
|
||||
*/
|
||||
serverTime: null,
|
||||
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment.config.amTimeAgoConfig#format
|
||||
* @propertyOf angularMoment.config:amTimeAgoConfig
|
||||
* @returns {string} The format of the date to be displayed in the title of the element. If null,
|
||||
* the directive set the title of the element.
|
||||
*
|
||||
* @description
|
||||
* Specify the format of the date when displayed. null by default.
|
||||
*/
|
||||
titleFormat: null
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name angularMoment.directive:amTimeAgo
|
||||
* @module angularMoment
|
||||
*
|
||||
* @restrict A
|
||||
*/
|
||||
.directive('amTimeAgo', ['$window', 'moment', 'amMoment', 'amTimeAgoConfig', 'angularMomentConfig', function ($window, moment, amMoment, amTimeAgoConfig, angularMomentConfig) {
|
||||
|
||||
return function (scope, element, attr) {
|
||||
var activeTimeout = null;
|
||||
var currentValue;
|
||||
var currentFormat = angularMomentConfig.format;
|
||||
var withoutSuffix = amTimeAgoConfig.withoutSuffix;
|
||||
var titleFormat = amTimeAgoConfig.titleFormat;
|
||||
var localDate = new Date().getTime();
|
||||
var preprocess = angularMomentConfig.preprocess;
|
||||
var modelName = attr.amTimeAgo.replace(/^::/, '');
|
||||
var isBindOnce = (attr.amTimeAgo.indexOf('::') === 0);
|
||||
var isTimeElement = ('TIME' === element[0].nodeName.toUpperCase());
|
||||
var unwatchChanges;
|
||||
|
||||
function getNow() {
|
||||
var now;
|
||||
if (amTimeAgoConfig.serverTime) {
|
||||
var localNow = new Date().getTime();
|
||||
var nowMillis = localNow - localDate + amTimeAgoConfig.serverTime;
|
||||
now = moment(nowMillis);
|
||||
}
|
||||
else {
|
||||
now = moment();
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
function cancelTimer() {
|
||||
if (activeTimeout) {
|
||||
$window.clearTimeout(activeTimeout);
|
||||
activeTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTime(momentInstance) {
|
||||
element.text(momentInstance.from(getNow(), withoutSuffix));
|
||||
|
||||
if (titleFormat && !element.attr('title')) {
|
||||
element.attr('title', momentInstance.local().format(titleFormat));
|
||||
}
|
||||
|
||||
if (!isBindOnce) {
|
||||
|
||||
var howOld = Math.abs(getNow().diff(momentInstance, 'minute'));
|
||||
var secondsUntilUpdate = 3600;
|
||||
if (howOld < 1) {
|
||||
secondsUntilUpdate = 1;
|
||||
} else if (howOld < 60) {
|
||||
secondsUntilUpdate = 30;
|
||||
} else if (howOld < 180) {
|
||||
secondsUntilUpdate = 300;
|
||||
}
|
||||
|
||||
activeTimeout = $window.setTimeout(function () {
|
||||
updateTime(momentInstance);
|
||||
}, secondsUntilUpdate * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function updateDateTimeAttr(value) {
|
||||
if (isTimeElement) {
|
||||
element.attr('datetime', value);
|
||||
}
|
||||
}
|
||||
|
||||
function updateMoment() {
|
||||
cancelTimer();
|
||||
if (currentValue) {
|
||||
var momentValue = amMoment.preprocessDate(currentValue, preprocess, currentFormat);
|
||||
updateTime(momentValue);
|
||||
updateDateTimeAttr(momentValue.toISOString());
|
||||
}
|
||||
}
|
||||
|
||||
unwatchChanges = scope.$watch(modelName, function (value) {
|
||||
if ((typeof value === 'undefined') || (value === null) || (value === '')) {
|
||||
cancelTimer();
|
||||
if (currentValue) {
|
||||
element.text('');
|
||||
updateDateTimeAttr('');
|
||||
currentValue = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
currentValue = value;
|
||||
updateMoment();
|
||||
|
||||
if (value !== undefined && isBindOnce) {
|
||||
unwatchChanges();
|
||||
}
|
||||
});
|
||||
|
||||
if (angular.isDefined(attr.amWithoutSuffix)) {
|
||||
scope.$watch(attr.amWithoutSuffix, function (value) {
|
||||
if (typeof value === 'boolean') {
|
||||
withoutSuffix = value;
|
||||
updateMoment();
|
||||
} else {
|
||||
withoutSuffix = amTimeAgoConfig.withoutSuffix;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
attr.$observe('amFormat', function (format) {
|
||||
if (typeof format !== 'undefined') {
|
||||
currentFormat = format;
|
||||
updateMoment();
|
||||
}
|
||||
});
|
||||
|
||||
attr.$observe('amPreprocess', function (newValue) {
|
||||
preprocess = newValue;
|
||||
updateMoment();
|
||||
});
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
cancelTimer();
|
||||
});
|
||||
|
||||
scope.$on('amMoment:localeChanged', function () {
|
||||
updateMoment();
|
||||
});
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name angularMoment.service.amMoment
|
||||
* @module angularMoment
|
||||
*/
|
||||
.service('amMoment', ['moment', '$rootScope', '$log', 'angularMomentConfig', function (moment, $rootScope, $log, angularMomentConfig) {
|
||||
var that = this;
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name angularMoment:amMoment#preprocessors
|
||||
* @module angularMoment
|
||||
*
|
||||
* @description
|
||||
* Defines the preprocessors for the preprocessDate method. By default, the following preprocessors
|
||||
* are defined: utc, unix.
|
||||
*/
|
||||
this.preprocessors = {
|
||||
utc: moment.utc,
|
||||
unix: moment.unix
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angularMoment.service.amMoment#changeLocale
|
||||
* @methodOf angularMoment.service.amMoment
|
||||
*
|
||||
* @description
|
||||
* Changes the locale for moment.js and updates all the am-time-ago directive instances
|
||||
* with the new locale. Also broadcasts a `amMoment:localeChanged` event on $rootScope.
|
||||
*
|
||||
* @param {string} locale 2-letter language code (e.g. en, es, ru, etc.)
|
||||
*/
|
||||
this.changeLocale = function (locale) {
|
||||
var result = (moment.locale||moment.lang)(locale);
|
||||
if (angular.isDefined(locale)) {
|
||||
$rootScope.$broadcast('amMoment:localeChanged');
|
||||
|
||||
// The following event is deprecated and will be removed in an upcoming
|
||||
// major release.
|
||||
$rootScope.$broadcast('amMoment:languageChange');
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angularMoment.service.amMoment#changeLanguage
|
||||
* @methodOf angularMoment.service.amMoment
|
||||
* @deprecated Please use changeLocale() instead.
|
||||
*
|
||||
* @description
|
||||
* Deprecated. Please use changeLocale() instead.
|
||||
*/
|
||||
this.changeLanguage = function (lang) {
|
||||
$log.warn('angular-moment: Usage of amMoment.changeLanguage() is deprecated. Please use changeLocale()');
|
||||
return that.changeLocale(lang);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angularMoment.service.amMoment#preprocessDate
|
||||
* @methodOf angularMoment.service.amMoment
|
||||
*
|
||||
* @description
|
||||
* Preprocess a given value and convert it into a Moment instance appropriate for use in the
|
||||
* am-time-ago directive and the filters.
|
||||
*
|
||||
* @param {*} value The value to be preprocessed
|
||||
* @param {string} preprocess The name of the preprocessor the apply (e.g. utc, unix)
|
||||
* @param {string=} format Specifies how to parse the value (see {@link http://momentjs.com/docs/#/parsing/string-format/})
|
||||
* @return {Moment} A value that can be parsed by the moment library
|
||||
*/
|
||||
this.preprocessDate = function (value, preprocess, format) {
|
||||
if (angular.isUndefined(preprocess)) {
|
||||
preprocess = angularMomentConfig.preprocess;
|
||||
}
|
||||
if (this.preprocessors[preprocess]) {
|
||||
return this.preprocessors[preprocess](value, format);
|
||||
}
|
||||
if (preprocess) {
|
||||
$log.warn('angular-moment: Ignoring unsupported value for preprocess: ' + preprocess);
|
||||
}
|
||||
if (!isNaN(parseFloat(value)) && isFinite(value)) {
|
||||
// Milliseconds since the epoch
|
||||
return moment(parseInt(value, 10));
|
||||
}
|
||||
// else just returns the value as-is.
|
||||
return moment(value, format);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angularMoment.service.amMoment#applyTimezone
|
||||
* @methodOf angularMoment.service.amMoment
|
||||
*
|
||||
* @description
|
||||
* Apply a timezone onto a given moment object - if moment-timezone.js is included
|
||||
* Otherwise, it'll not apply any timezone shift.
|
||||
*
|
||||
* @param {Moment} aMoment a moment() instance to apply the timezone shift to
|
||||
* @returns {Moment} The given moment with the timezone shift applied
|
||||
*/
|
||||
this.applyTimezone = function (aMoment) {
|
||||
var timezone = angularMomentConfig.timezone;
|
||||
if (aMoment && timezone) {
|
||||
if (aMoment.tz) {
|
||||
aMoment = aMoment.tz(timezone);
|
||||
} else {
|
||||
$log.warn('angular-moment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?');
|
||||
}
|
||||
}
|
||||
return aMoment;
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name angularMoment.filter:amCalendar
|
||||
* @module angularMoment
|
||||
*/
|
||||
.filter('amCalendar', ['moment', 'amMoment', function (moment, amMoment) {
|
||||
return function (value, preprocess) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
value = amMoment.preprocessDate(value, preprocess);
|
||||
var date = moment(value);
|
||||
if (!date.isValid()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return amMoment.applyTimezone(date).calendar();
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name angularMoment.filter:amDateFormat
|
||||
* @module angularMoment
|
||||
* @function
|
||||
*/
|
||||
.filter('amDateFormat', ['moment', 'amMoment', function (moment, amMoment) {
|
||||
return function (value, format, preprocess) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
value = amMoment.preprocessDate(value, preprocess);
|
||||
var date = moment(value);
|
||||
if (!date.isValid()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return amMoment.applyTimezone(date).format(format);
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name angularMoment.filter:amDurationFormat
|
||||
* @module angularMoment
|
||||
* @function
|
||||
*/
|
||||
.filter('amDurationFormat', ['moment', function (moment) {
|
||||
return function (value, format, suffix) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return moment.duration(value, format).humanize(suffix);
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name angularMoment.filter:amTimeAgo
|
||||
* @module angularMoment
|
||||
* @function
|
||||
*/
|
||||
.filter('amTimeAgo', ['moment', 'amMoment', function (moment, amMoment) {
|
||||
return function (value, preprocess, suffix) {
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
value = amMoment.preprocessDate(value, preprocess);
|
||||
var date = moment(value);
|
||||
if (!date.isValid()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return amMoment.applyTimezone(date).fromNow(suffix);
|
||||
};
|
||||
}]);
|
||||
}
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('angular-moment', ['angular', 'moment'], angularMoment);
|
||||
} else if (typeof module !== 'undefined' && module && module.exports) {
|
||||
angularMoment(angular, require('moment'));
|
||||
} else {
|
||||
angularMoment(angular, window.moment);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
"format global";"deps angular";"deps moment";!function(){"use strict";function a(a,b){return a.module("angularMoment",[]).constant("angularMomentConfig",{preprocess:null,timezone:"",format:null}).constant("moment",b).constant("amTimeAgoConfig",{withoutSuffix:!1,serverTime:null,titleFormat:null}).directive("amTimeAgo",["$window","moment","amMoment","amTimeAgoConfig","angularMomentConfig",function(b,c,d,e,f){return function(g,h,i){function j(){var a;if(e.serverTime){var b=(new Date).getTime(),d=b-u+e.serverTime;a=c(d)}else a=c();return a}function k(){q&&(b.clearTimeout(q),q=null)}function l(a){if(h.text(a.from(j(),s)),t&&!h.attr("title")&&h.attr("title",a.local().format(t)),!x){var c=Math.abs(j().diff(a,"minute")),d=3600;1>c?d=1:60>c?d=30:180>c&&(d=300),q=b.setTimeout(function(){l(a)},1e3*d)}}function m(a){y&&h.attr("datetime",a)}function n(){if(k(),o){var a=d.preprocessDate(o,v,r);l(a),m(a.toISOString())}}var o,p,q=null,r=f.format,s=e.withoutSuffix,t=e.titleFormat,u=(new Date).getTime(),v=f.preprocess,w=i.amTimeAgo.replace(/^::/,""),x=0===i.amTimeAgo.indexOf("::"),y="TIME"===h[0].nodeName.toUpperCase();p=g.$watch(w,function(a){return"undefined"==typeof a||null===a||""===a?(k(),void(o&&(h.text(""),m(""),o=null))):(o=a,n(),void(void 0!==a&&x&&p()))}),a.isDefined(i.amWithoutSuffix)&&g.$watch(i.amWithoutSuffix,function(a){"boolean"==typeof a?(s=a,n()):s=e.withoutSuffix}),i.$observe("amFormat",function(a){"undefined"!=typeof a&&(r=a,n())}),i.$observe("amPreprocess",function(a){v=a,n()}),g.$on("$destroy",function(){k()}),g.$on("amMoment:localeChanged",function(){n()})}}]).service("amMoment",["moment","$rootScope","$log","angularMomentConfig",function(b,c,d,e){var f=this;this.preprocessors={utc:b.utc,unix:b.unix},this.changeLocale=function(d){var e=(b.locale||b.lang)(d);return a.isDefined(d)&&(c.$broadcast("amMoment:localeChanged"),c.$broadcast("amMoment:languageChange")),e},this.changeLanguage=function(a){return d.warn("angular-moment: Usage of amMoment.changeLanguage() is deprecated. Please use changeLocale()"),f.changeLocale(a)},this.preprocessDate=function(c,f,g){return a.isUndefined(f)&&(f=e.preprocess),this.preprocessors[f]?this.preprocessors[f](c,g):(f&&d.warn("angular-moment: Ignoring unsupported value for preprocess: "+f),!isNaN(parseFloat(c))&&isFinite(c)?b(parseInt(c,10)):b(c,g))},this.applyTimezone=function(a){var b=e.timezone;return a&&b&&(a.tz?a=a.tz(b):d.warn("angular-moment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?")),a}}]).filter("amCalendar",["moment","amMoment",function(a,b){return function(c,d){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var e=a(c);return e.isValid()?b.applyTimezone(e).calendar():""}}]).filter("amDateFormat",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,e);var f=a(c);return f.isValid()?b.applyTimezone(f).format(d):""}}]).filter("amDurationFormat",["moment",function(a){return function(b,c,d){return"undefined"==typeof b||null===b?"":a.duration(b,c).humanize(d)}}]).filter("amTimeAgo",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var f=a(c);return f.isValid()?b.applyTimezone(f).fromNow(e):""}}])}"function"==typeof define&&define.amd?define("angular-moment",["angular","moment"],a):"undefined"!=typeof module&&module&&module.exports?a(angular,require("moment")):a(angular,window.moment)}();
|
||||
//# sourceMappingURL=angular-moment.min.js.map
|
||||
@ -1 +0,0 @@
|
||||
{"version":3,"file":"angular-moment.min.js","sources":["angular-moment.js"],"names":["angularMoment","angular","moment","module","constant","preprocess","timezone","format","withoutSuffix","serverTime","titleFormat","directive","$window","amMoment","amTimeAgoConfig","angularMomentConfig","scope","element","attr","getNow","now","localNow","Date","getTime","nowMillis","localDate","cancelTimer","activeTimeout","clearTimeout","updateTime","momentInstance","text","from","local","isBindOnce","howOld","Math","abs","diff","secondsUntilUpdate","setTimeout","updateDateTimeAttr","value","isTimeElement","updateMoment","currentValue","momentValue","preprocessDate","currentFormat","toISOString","unwatchChanges","modelName","amTimeAgo","replace","indexOf","nodeName","toUpperCase","$watch","undefined","isDefined","amWithoutSuffix","$observe","newValue","$on","service","$rootScope","$log","that","this","preprocessors","utc","unix","changeLocale","locale","result","lang","$broadcast","changeLanguage","warn","isUndefined","isNaN","parseFloat","isFinite","parseInt","applyTimezone","aMoment","tz","filter","date","isValid","calendar","suffix","duration","humanize","fromNow","define","amd","exports","require","window"],"mappings":"AAEA,eACA,eACA,gBAEA,WACC,YAEA,SAASA,GAAcC,EAASC,GAS/B,MAAOD,GAAQE,OAAO,oBASpBC,SAAS,uBAWTC,WAAY,KAYZC,SAAU,GAaVC,OAAQ,OAURH,SAAS,SAAUF,GAUnBE,SAAS,mBAUTI,eAAe,EAYfC,WAAY,KAYZC,YAAa,OAUbC,UAAU,aAAc,UAAW,SAAU,WAAY,kBAAmB,sBAAuB,SAAUC,EAASV,EAAQW,EAAUC,EAAiBC,GAEzJ,MAAO,UAAUC,EAAOC,EAASC,GAahC,QAASC,KACR,GAAIC,EACJ,IAAIN,EAAgBL,WAAY,CAC/B,GAAIY,IAAW,GAAIC,OAAOC,UACtBC,EAAYH,EAAWI,EAAYX,EAAgBL,UACvDW,GAAMlB,EAAOsB,OAGbJ,GAAMlB,GAEP,OAAOkB,GAGR,QAASM,KACJC,IACHf,EAAQgB,aAAaD,GACrBA,EAAgB,MAIlB,QAASE,GAAWC,GAOnB,GANAb,EAAQc,KAAKD,EAAeE,KAAKb,IAAUX,IAEvCE,IAAgBO,EAAQC,KAAK,UAChCD,EAAQC,KAAK,QAASY,EAAeG,QAAQ1B,OAAOG,KAGhDwB,EAAY,CAEhB,GAAIC,GAASC,KAAKC,IAAIlB,IAASmB,KAAKR,EAAgB,WAChDS,EAAqB,IACZ,GAATJ,EACHI,EAAqB,EACF,GAATJ,EACVI,EAAqB,GACF,IAATJ,IACVI,EAAqB,KAGtBZ,EAAgBf,EAAQ4B,WAAW,WAClCX,EAAWC,IACY,IAArBS,IAIL,QAASE,GAAmBC,GACvBC,GACH1B,EAAQC,KAAK,WAAYwB,GAI3B,QAASE,KAER,GADAlB,IACImB,EAAc,CACjB,GAAIC,GAAcjC,EAASkC,eAAeF,EAAcxC,EAAY2C,EACpEnB,GAAWiB,GACXL,EAAmBK,EAAYG,gBApEjC,GACIJ,GASAK,EAVAvB,EAAgB,KAEhBqB,EAAgBjC,EAAoBR,OACpCC,EAAgBM,EAAgBN,cAChCE,EAAcI,EAAgBJ,YAC9Be,GAAY,GAAIH,OAAOC,UACvBlB,EAAaU,EAAoBV,WACjC8C,EAAYjC,EAAKkC,UAAUC,QAAQ,MAAO,IAC1CnB,EAA+C,IAAjChB,EAAKkC,UAAUE,QAAQ,MACrCX,EAAiB,SAAW1B,EAAQ,GAAGsC,SAASC,aA+DpDN,GAAiBlC,EAAMyC,OAAON,EAAW,SAAUT,GAClD,MAAsB,mBAAVA,IAAqC,OAAVA,GAA8B,KAAVA,GAC1DhB,SACImB,IACH5B,EAAQc,KAAK,IACbU,EAAmB,IACnBI,EAAe,SAKjBA,EAAeH,EACfE,SAEcc,SAAVhB,GAAuBR,GAC1BgB,QAIEjD,EAAQ0D,UAAUzC,EAAK0C,kBAC1B5C,EAAMyC,OAAOvC,EAAK0C,gBAAiB,SAAUlB,GACvB,iBAAVA,IACVlC,EAAgBkC,EAChBE,KAEApC,EAAgBM,EAAgBN,gBAKnCU,EAAK2C,SAAS,WAAY,SAAUtD,GACb,mBAAXA,KACVyC,EAAgBzC,EAChBqC,OAIF1B,EAAK2C,SAAS,eAAgB,SAAUC,GACvCzD,EAAayD,EACblB,MAGD5B,EAAM+C,IAAI,WAAY,WACrBrC,MAGDV,EAAM+C,IAAI,yBAA0B,WACnCnB,UAUFoB,QAAQ,YAAa,SAAU,aAAc,OAAQ,sBAAuB,SAAU9D,EAAQ+D,EAAYC,EAAMnD,GAChH,GAAIoD,GAAOC,IAUXA,MAAKC,eACJC,IAAKpE,EAAOoE,IACZC,KAAMrE,EAAOqE,MAcdH,KAAKI,aAAe,SAAUC,GAC7B,GAAIC,IAAUxE,EAAOuE,QAAQvE,EAAOyE,MAAMF,EAQ1C,OAPIxE,GAAQ0D,UAAUc,KACrBR,EAAWW,WAAW,0BAItBX,EAAWW,WAAW,4BAEhBF,GAYRN,KAAKS,eAAiB,SAAUF,GAE/B,MADAT,GAAKY,KAAK,+FACHX,EAAKK,aAAaG,IAiB1BP,KAAKrB,eAAiB,SAAUL,EAAOrC,EAAYE,GAIlD,MAHIN,GAAQ8E,YAAY1E,KACvBA,EAAaU,EAAoBV,YAE9B+D,KAAKC,cAAchE,GACf+D,KAAKC,cAAchE,GAAYqC,EAAOnC,IAE1CF,GACH6D,EAAKY,KAAK,8DAAgEzE,IAEtE2E,MAAMC,WAAWvC,KAAWwC,SAASxC,GAElCxC,EAAOiF,SAASzC,EAAO,KAGxBxC,EAAOwC,EAAOnC,KAetB6D,KAAKgB,cAAgB,SAAUC,GAC9B,GAAI/E,GAAWS,EAAoBT,QAQnC,OAPI+E,IAAW/E,IACV+E,EAAQC,GACXD,EAAUA,EAAQC,GAAGhF,GAErB4D,EAAKY,KAAK,mHAGLO,MASRE,OAAO,cAAe,SAAU,WAAY,SAAUrF,EAAQW,GAC9D,MAAO,UAAU6B,EAAOrC,GACvB,GAAqB,mBAAVqC,IAAmC,OAAVA,EACnC,MAAO,EAGRA,GAAQ7B,EAASkC,eAAeL,EAAOrC,EACvC,IAAImF,GAAOtF,EAAOwC,EAClB,OAAK8C,GAAKC,UAIH5E,EAASuE,cAAcI,GAAME,WAH5B,OAaTH,OAAO,gBAAiB,SAAU,WAAY,SAAUrF,EAAQW,GAChE,MAAO,UAAU6B,EAAOnC,EAAQF,GAC/B,GAAqB,mBAAVqC,IAAmC,OAAVA,EACnC,MAAO,EAGRA,GAAQ7B,EAASkC,eAAeL,EAAOrC,EACvC,IAAImF,GAAOtF,EAAOwC,EAClB,OAAK8C,GAAKC,UAIH5E,EAASuE,cAAcI,GAAMjF,OAAOA,GAHnC,OAaTgF,OAAO,oBAAqB,SAAU,SAAUrF,GAChD,MAAO,UAAUwC,EAAOnC,EAAQoF,GAC/B,MAAqB,mBAAVjD,IAAmC,OAAVA,EAC5B,GAGDxC,EAAO0F,SAASlD,EAAOnC,GAAQsF,SAASF,OAUhDJ,OAAO,aAAc,SAAU,WAAY,SAAUrF,EAAQW,GAC5D,MAAO,UAAU6B,EAAOrC,EAAYsF,GACnC,GAAqB,mBAAVjD,IAAmC,OAAVA,EACnC,MAAO,EAGRA,GAAQ7B,EAASkC,eAAeL,EAAOrC,EACvC,IAAImF,GAAOtF,EAAOwC,EAClB,OAAK8C,GAAKC,UAIH5E,EAASuE,cAAcI,GAAMM,QAAQH,GAHpC,OAQS,kBAAXI,SAAyBA,OAAOC,IAC1CD,OAAO,kBAAmB,UAAW,UAAW/F,GACpB,mBAAXG,SAA0BA,QAAUA,OAAO8F,QAC5DjG,EAAcC,QAASiG,QAAQ,WAE/BlG,EAAcC,QAASkG,OAAOjG"}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "angular-moment",
|
||||
"version": "0.8.3",
|
||||
"description": "Moment.JS directives & filters for Angular.JS (timeago alternative)",
|
||||
"author": "Uri Shaked",
|
||||
"license": "MIT",
|
||||
"homepage": "http://github.com/urish/angular-moment",
|
||||
"main": "./angular-moment.js",
|
||||
"ignore": [
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1.0.0 <1.4.0",
|
||||
"moment": ">=2.0.0 <2.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "1.2.x",
|
||||
"moment-timezone": "0.2.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/urish/angular-moment.git"
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
/* License: MIT.
|
||||
* Copyright (C) 2013, 2014, Uri Shaked.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine'],
|
||||
logLevel: config.LOG_INFO,
|
||||
browsers: ['PhantomJS'],
|
||||
autoWatch: true,
|
||||
reporters: ['dots', 'coverage'],
|
||||
files: [
|
||||
'bower_components/angular/angular.js',
|
||||
'bower_components/moment/moment.js',
|
||||
'bower_components/moment/{locale,lang}/fr.js',
|
||||
'bower_components/moment-timezone/moment-timezone.js',
|
||||
'angular-moment.js',
|
||||
|
||||
// angular-mocks defines a global variable named 'module' which confuses moment-timezone.js.
|
||||
// Therefore, it must be included after moment-timezone.js.
|
||||
'bower_components/angular-mocks/angular-mocks.js',
|
||||
|
||||
'tests.js'
|
||||
],
|
||||
preprocessors: {
|
||||
'angular-moment.js': 'coverage'
|
||||
},
|
||||
coverageReporter: {
|
||||
type: 'lcov',
|
||||
dir: 'coverage/'
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "angular-moment",
|
||||
"version": "0.8.3",
|
||||
"main": "angular-moment.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/urish/angular-moment.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"moment": ">=2.0.0 <2.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.1",
|
||||
"load-grunt-tasks": "0.6.0",
|
||||
"grunt-contrib-uglify": "0.5.1",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-karma": "~0.8.2",
|
||||
"karma": "~0.12.0",
|
||||
"karma-coverage": "~0.2.0",
|
||||
"karma-jasmine": "~0.2.1",
|
||||
"karma-phantomjs-launcher": "~0.1.1",
|
||||
"coveralls": "~2.11.0",
|
||||
"grunt-ngdocs": "^0.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt test"
|
||||
}
|
||||
}
|
||||
606
server/public/lib/angular-moment/tests.js
vendored
@ -1,606 +0,0 @@
|
||||
/* License: MIT.
|
||||
* Copyright (C) 2013, 2014, Uri Shaked.
|
||||
*/
|
||||
|
||||
/* global describe, inject, module, beforeEach, afterEach, it, expect, spyOn, jasmine */
|
||||
|
||||
'use strict';
|
||||
|
||||
describe('module angularMoment', function () {
|
||||
var $rootScope, $compile, $window, $filter, moment, amTimeAgoConfig, originalTimeAgoConfig, angularMomentConfig,
|
||||
originalAngularMomentConfig, amMoment;
|
||||
|
||||
beforeEach(module('angularMoment'));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
$compile = $injector.get('$compile');
|
||||
$window = $injector.get('$window');
|
||||
$filter = $injector.get('$filter');
|
||||
moment = $injector.get('moment');
|
||||
amMoment = $injector.get('amMoment');
|
||||
amTimeAgoConfig = $injector.get('amTimeAgoConfig');
|
||||
angularMomentConfig = $injector.get('angularMomentConfig');
|
||||
originalTimeAgoConfig = angular.copy(amTimeAgoConfig);
|
||||
originalAngularMomentConfig = angular.copy(angularMomentConfig);
|
||||
|
||||
// Ensure the locale of moment.js is set to en by default
|
||||
(moment.locale || moment.lang)('en');
|
||||
// Add a sample timezone for tests
|
||||
moment.tz.add('Pacific/Tahiti|LMT TAHT|9W.g a0|01|-2joe1.I');
|
||||
}));
|
||||
|
||||
afterEach(function () {
|
||||
// Restore original configuration after each test
|
||||
angular.copy(originalTimeAgoConfig, amTimeAgoConfig);
|
||||
angular.copy(originalAngularMomentConfig, angularMomentConfig);
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
|
||||
describe('am-time-ago directive', function () {
|
||||
it('should change the text of the element to "a few seconds ago" when given unix timestamp', function () {
|
||||
$rootScope.testDate = new Date().getTime() / 1000;
|
||||
var element = angular.element('<span am-time-ago="testDate" am-preprocess="unix"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should change the text of the element to "a few seconds ago" when given current time', function () {
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should change the text of the div to "3 minutes ago" when given a date 3 minutes ago', function () {
|
||||
$rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000);
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('3 minutes ago');
|
||||
});
|
||||
|
||||
it('should change the text of the div to "2 hours ago" when given a date 2 hours ago', function () {
|
||||
$rootScope.testDate = new Date(new Date().getTime() - 2 * 60 * 60 * 1000);
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('2 hours ago');
|
||||
});
|
||||
|
||||
it('should change the text of the div to "one year ago" when given a date one year ago', function () {
|
||||
var today = new Date();
|
||||
$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a year ago');
|
||||
});
|
||||
|
||||
it('should parse correctly numeric dates as milliseconds since the epoch', function () {
|
||||
$rootScope.testDate = new Date().getTime();
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should update the value if date changes on scope', function () {
|
||||
var today = new Date();
|
||||
$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime();
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a year ago');
|
||||
$rootScope.testDate = new Date();
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should update the span text as time passes', function (done) {
|
||||
$rootScope.testDate = new Date(new Date().getTime() - 44000);
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
|
||||
var waitsInterval = setInterval(function () {
|
||||
// Wait until $rootScope.date is more than 45 seconds old
|
||||
if (new Date().getTime() - $rootScope.testDate.getTime() < 45000) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(waitsInterval);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a minute ago');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
it('should schedule the update timer to one hour ahead for date in the far future (#73)', function () {
|
||||
$rootScope.testDate = new Date(new Date().getTime() + 86400000);
|
||||
jasmine.clock().install();
|
||||
spyOn($window, 'setTimeout');
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect($window.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 3600000);
|
||||
});
|
||||
|
||||
describe('bindonce', function () {
|
||||
it('should change the text of the div to "3 minutes ago" when given a date 3 minutes ago with one time binding', function () {
|
||||
$rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000);
|
||||
var element = angular.element('<div am-time-ago="::testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('3 minutes ago');
|
||||
});
|
||||
|
||||
it('should parse correctly numeric dates as milliseconds since the epoch with one time binding', function () {
|
||||
$rootScope.testDate = new Date().getTime();
|
||||
var element = angular.element('<div am-time-ago="::testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should not update the value if date changes on scope when using one time binding', function () {
|
||||
var today = new Date();
|
||||
$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime();
|
||||
var element = angular.element('<div am-time-ago="::testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a year ago');
|
||||
$rootScope.testDate = new Date();
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a year ago');
|
||||
});
|
||||
|
||||
it('should not update the span text as time passes when using one time binding', function (done) {
|
||||
$rootScope.testDate = new Date(new Date().getTime() - 44000);
|
||||
var element = angular.element('<div am-time-ago="::testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
|
||||
var waitsInterval = setInterval(function () {
|
||||
// Wait until $rootScope.date is more than 45 seconds old
|
||||
if (new Date().getTime() - $rootScope.testDate.getTime() < 45000) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(waitsInterval);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle undefined data', function () {
|
||||
$rootScope.testDate = null;
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
var digest = function () {
|
||||
$rootScope.$digest();
|
||||
};
|
||||
expect(digest).not.toThrow();
|
||||
});
|
||||
|
||||
it('should remove the element text and cancel the timer when an empty string is given (#15)', function () {
|
||||
$rootScope.testDate = new Date().getTime();
|
||||
var element = angular.element('<div am-time-ago="testDate"></div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
$rootScope.testDate = '';
|
||||
spyOn($window, 'clearTimeout').and.callThrough();
|
||||
$rootScope.$digest();
|
||||
expect($window.clearTimeout).toHaveBeenCalled();
|
||||
expect(element.text()).toBe('');
|
||||
});
|
||||
|
||||
it('should not change the contents of the element until a date is given', function () {
|
||||
$rootScope.testDate = null;
|
||||
var element = angular.element('<div am-time-ago="testDate">Initial text</div>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('Initial text');
|
||||
$rootScope.testDate = new Date().getTime();
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should cancel the timer when the scope is destroyed', function () {
|
||||
var scope = $rootScope.$new();
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)(scope);
|
||||
$rootScope.$digest();
|
||||
spyOn($window, 'clearTimeout').and.callThrough();
|
||||
scope.$destroy();
|
||||
expect($window.clearTimeout).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should generate a time string without suffix when configured to do so', function () {
|
||||
amTimeAgoConfig.withoutSuffix = true;
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds');
|
||||
});
|
||||
|
||||
it('should generate update the text following a locale change via amMoment.changeLocale() method', function () {
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
amMoment.changeLocale('fr');
|
||||
expect(element.text()).toBe('il y a quelques secondes');
|
||||
});
|
||||
|
||||
it('should update the `datetime` attr if applied to a TIME element', function () {
|
||||
$rootScope.testDate = Date.UTC(2012, 8, 20, 15, 20, 12);
|
||||
var element = angular.element('<time am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('datetime')).toBe('2012-09-20T15:20:12.000Z');
|
||||
});
|
||||
|
||||
describe('setting the element title', function() {
|
||||
it('should not set the title attribute of the element to the date by default', function () {
|
||||
$rootScope.testDate = new Date().getTime() / 1000;
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('title')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not change the title attribute of the element if the element already has a title', function () {
|
||||
amTimeAgoConfig.titleFormat = 'MMMM Do YYYY, h:mm:ss a';
|
||||
$rootScope.testDate = new Date().getTime() / 1000;
|
||||
var element = angular.element('<span am-time-ago="testDate" title="test"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.attr('title')).toBe('test');
|
||||
});
|
||||
|
||||
it('should set the title attribute of the element to the formatted date as per the config', function () {
|
||||
amTimeAgoConfig.titleFormat = 'MMMM Do YYYY, h:mm:ss a';
|
||||
$rootScope.testDate = new Date().getTime() / 1000;
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
var testDateWithCustomFormatting = moment($rootScope.testDate).format(amTimeAgoConfig.titleFormat);
|
||||
expect(element.attr('title')).toBe(testDateWithCustomFormatting);
|
||||
});
|
||||
});
|
||||
|
||||
describe('am-without-suffix attribute', function () {
|
||||
it('should generate a time string without suffix when true', function () {
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate" am-without-suffix="true"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds');
|
||||
});
|
||||
|
||||
it('should generate a time string with suffix when false', function () {
|
||||
amTimeAgoConfig.withoutSuffix = true;
|
||||
$rootScope.testDate = new Date();
|
||||
var element = angular.element('<span am-time-ago="testDate" am-without-suffix="false"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should support expressions', function () {
|
||||
$rootScope.testDate = new Date();
|
||||
$rootScope.withSuffix = false;
|
||||
var element = angular.element('<span am-time-ago="testDate" am-without-suffix="!withSuffix"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds');
|
||||
$rootScope.withSuffix = true;
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should ignore non-boolean values', function () {
|
||||
$rootScope.testDate = new Date();
|
||||
$rootScope.withoutSuffix = 'string';
|
||||
var element = angular.element('<span am-time-ago="testDate" am-without-suffix="withoutSuffix"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a few seconds ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('am-format attribute', function () {
|
||||
it('should support custom date format', function () {
|
||||
var today = new Date();
|
||||
$rootScope.testDate = today.getFullYear() + '#' + today.getDate() + '#' + today.getMonth();
|
||||
var element = angular.element('<span am-time-ago="testDate" am-format="YYYY#DD#MM"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a month ago');
|
||||
});
|
||||
|
||||
it('should support angular expressions in date format', function () {
|
||||
var today = new Date();
|
||||
$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();
|
||||
var element = angular.element('<span am-time-ago="testDate" am-format="{{dateFormat}}"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
$rootScope.dateFormat = 'MM@YYYY@DD';
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a month ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('format config property', function () {
|
||||
it('should be used when no `am-format` attribute is found', function () {
|
||||
angularMomentConfig.format = 'MM@YYYY@DD';
|
||||
var today = new Date();
|
||||
$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a month ago');
|
||||
});
|
||||
|
||||
it('should be overridable by `am-format` attribute', function () {
|
||||
angularMomentConfig.format = 'YYYY@MM@@DD';
|
||||
var today = new Date();
|
||||
$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();
|
||||
var element = angular.element('<span am-format="MM@YYYY@DD" am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('a month ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('serverTime configuration', function () {
|
||||
it('should calculate time ago in respect to the configured server time', function () {
|
||||
amTimeAgoConfig.serverTime = Date.UTC(2014, 5, 12, 5, 22, 11);
|
||||
$rootScope.testDate = Date.UTC(2014, 5, 12, 9, 22, 11);
|
||||
var element = angular.element('<span am-time-ago="testDate"></span>');
|
||||
element = $compile(element)($rootScope);
|
||||
$rootScope.$digest();
|
||||
expect(element.text()).toBe('in 4 hours');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('amCalendar filter', function () {
|
||||
var amCalendar;
|
||||
|
||||
beforeEach(function () {
|
||||
amCalendar = $filter('amCalendar');
|
||||
});
|
||||
|
||||
it('should convert today date to calendar form', function () {
|
||||
var today = new Date();
|
||||
var testDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 13, 33, 33);
|
||||
expect(amCalendar(testDate)).toBe('Today at 1:33 PM');
|
||||
});
|
||||
|
||||
it('should convert date in long past to calendar form', function () {
|
||||
expect(amCalendar(new Date(2012, 2, 25, 13, 14, 15))).toBe('03/25/2012');
|
||||
});
|
||||
|
||||
it('should gracefully handle undefined values', function () {
|
||||
expect(amCalendar()).toBe('');
|
||||
});
|
||||
|
||||
it('should accept a numeric unix timestamp (milliseconds since the epoch) as input', function () {
|
||||
expect(amCalendar(new Date(2012, 0, 22, 4, 46, 54).getTime())).toBe('01/22/2012');
|
||||
});
|
||||
|
||||
it('should respect the configured timezone', function () {
|
||||
angularMomentConfig.timezone = 'Pacific/Tahiti';
|
||||
expect(amCalendar(Date.UTC(2012, 0, 22, 4, 46, 54))).toBe('01/21/2012');
|
||||
});
|
||||
|
||||
it('should apply the "utc" preprocessor when the string "utc" is given in the second argument', function () {
|
||||
expect(amCalendar(Date.UTC(2012, 0, 22, 0, 0, 0), 'utc')).toBe('01/22/2012');
|
||||
expect(amCalendar(Date.UTC(2012, 0, 22, 23, 59, 59), 'utc')).toBe('01/22/2012');
|
||||
});
|
||||
|
||||
it('should apply the "unix" preprocessor if angularMomentConfig.preprocess is set to "unix" and no preprocessor is given', function () {
|
||||
angularMomentConfig.preprocess = 'unix';
|
||||
expect(amCalendar(100000)).toBe('01/02/1970');
|
||||
});
|
||||
|
||||
it('should ignore the default preprocessor if we explicity give it null in the second argument', function () {
|
||||
angularMomentConfig.preprocess = 'unix';
|
||||
expect(amCalendar(100000, null)).toBe('01/01/1970');
|
||||
});
|
||||
|
||||
it('should gracefully handle the case where timezone is given but moment-timezone is not loaded', function () {
|
||||
angularMomentConfig.timezone = 'Pacific/Tahiti';
|
||||
var originalMomentTz = moment.fn.tz;
|
||||
try {
|
||||
delete moment.fn.tz;
|
||||
expect(amCalendar(Date.UTC(2012, 0, 22, 4, 46, 54))).toBe('01/22/2012');
|
||||
} finally {
|
||||
moment.fn.tz = originalMomentTz;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return an empty string for invalid input', function () {
|
||||
expect(amCalendar('blah blah')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('amDateFormat filter', function () {
|
||||
var amDateFormat;
|
||||
|
||||
beforeEach(function () {
|
||||
amDateFormat = $filter('amDateFormat');
|
||||
});
|
||||
|
||||
it('should support displaying format', function () {
|
||||
var today = new Date();
|
||||
var expectedResult = today.getDate() + '.' + (today.getMonth() + 1) + '.' + today.getFullYear();
|
||||
expect(amDateFormat(today, 'D.M.YYYY')).toBe(expectedResult);
|
||||
});
|
||||
|
||||
it('should gracefully handle undefined values', function () {
|
||||
expect(amDateFormat(undefined, 'D.M.YYYY')).toBe('');
|
||||
});
|
||||
|
||||
it('should accept a numeric unix timestamp (milliseconds since the epoch) as input', function () {
|
||||
var timestamp = new Date(2012, 0, 22, 12, 46, 54).getTime();
|
||||
expect(amDateFormat(timestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(12,46,54);01.22.2012');
|
||||
});
|
||||
|
||||
it('should gracefully handle string unix timestamp as input', function () {
|
||||
var strTimestamp = String(new Date(2012, 0, 22, 12, 46, 54).getTime());
|
||||
expect(amDateFormat(strTimestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(12,46,54);01.22.2012');
|
||||
});
|
||||
|
||||
it('should respect the configured timezone', function () {
|
||||
angularMomentConfig.timezone = 'Pacific/Tahiti';
|
||||
var timestamp = Date.UTC(2012, 0, 22, 12, 46, 54);
|
||||
expect(amDateFormat(timestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(02,46,54);01.22.2012');
|
||||
});
|
||||
|
||||
it('should return an empty string for invalid input', function () {
|
||||
expect(amDateFormat('blah blah', '(HH,mm,ss);MM.DD.YYYY')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('amDurationFormat filter', function () {
|
||||
var amDurationFormat;
|
||||
|
||||
beforeEach(function () {
|
||||
amDurationFormat = $filter('amDurationFormat');
|
||||
});
|
||||
|
||||
it('should support return the given duration as text', function () {
|
||||
expect(amDurationFormat(1000, 'milliseconds')).toBe('a few seconds');
|
||||
});
|
||||
|
||||
it('should support return a day given 24 hours', function () {
|
||||
expect(amDurationFormat(24, 'hours')).toBe('a day');
|
||||
});
|
||||
|
||||
it('should add prefix the result with the word "in" if the third parameter (suffix) is true', function () {
|
||||
expect(amDurationFormat(1, 'minutes', true)).toBe('in a minute');
|
||||
});
|
||||
|
||||
it('should add suffix the result with the word "ago" if the duration is negative and the third parameter is true', function () {
|
||||
expect(amDurationFormat(-1, 'minutes', true)).toBe('a minute ago');
|
||||
});
|
||||
|
||||
it('should gracefully handle undefined values for duration', function () {
|
||||
expect(amDurationFormat(undefined, 'minutes')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('amTimeAgo filter', function () {
|
||||
var amTimeAgo;
|
||||
|
||||
beforeEach(function () {
|
||||
amTimeAgo = $filter('amTimeAgo');
|
||||
});
|
||||
|
||||
it('should support return the time ago as text', function () {
|
||||
var date = new Date();
|
||||
expect(amTimeAgo(date)).toBe('a few seconds ago');
|
||||
});
|
||||
|
||||
it('should remove suffix from the result if the third parameter (suffix) is true', function () {
|
||||
var date = new Date();
|
||||
expect(amTimeAgo(date, null, true)).toBe('a few seconds');
|
||||
});
|
||||
|
||||
it('should gracefully handle undefined values', function () {
|
||||
expect(amTimeAgo()).toBe('');
|
||||
});
|
||||
|
||||
it('should gracefully handle invalid input', function () {
|
||||
expect(amTimeAgo('noDate')).toBe('');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('amMoment service', function () {
|
||||
describe('#changeLocale', function () {
|
||||
it('should return the current locale', function () {
|
||||
expect(amMoment.changeLocale()).toBe('en');
|
||||
});
|
||||
|
||||
it('should broadcast an angularMoment:localeChanged event on the root scope if a locale is specified', function () {
|
||||
var eventBroadcasted = false;
|
||||
$rootScope.$on('amMoment:localeChanged', function () {
|
||||
eventBroadcasted = true;
|
||||
});
|
||||
amMoment.changeLocale('fr');
|
||||
expect(eventBroadcasted).toBe(true);
|
||||
});
|
||||
|
||||
it('should not broadcast an angularMoment:localeChanged event on the root scope if no locale is specified', function () {
|
||||
var eventBroadcasted = false;
|
||||
$rootScope.$on('amMoment:localeChanged', function () {
|
||||
eventBroadcasted = true;
|
||||
});
|
||||
amMoment.changeLocale();
|
||||
expect(eventBroadcasted).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#changeLanguage', function () {
|
||||
it('should issue a warning about changeLanguage() deprecation', inject(function ($log) {
|
||||
spyOn($log, 'warn');
|
||||
amMoment.changeLanguage('fr');
|
||||
expect($log.warn).toHaveBeenCalledWith('angular-moment: Usage of amMoment.changeLanguage() is deprecated. Please use changeLocale()');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('#preprocessDate', function () {
|
||||
it('should call a custom preprocessor that was registered on amMoment.preprocessors', function () {
|
||||
var testDate = new Date(2013, 0, 22, 12, 46, 54);
|
||||
var meeting = {
|
||||
name: 'Budget plan',
|
||||
date: testDate
|
||||
};
|
||||
|
||||
amMoment.preprocessors.foobar = function (value) {
|
||||
return moment(value.date);
|
||||
};
|
||||
|
||||
expect(amMoment.preprocessDate(meeting, 'foobar').valueOf()).toEqual(testDate.getTime());
|
||||
});
|
||||
|
||||
it('should issue a warning if an unsupported preprocessor is used and fall-back to default processing', inject(function ($log) {
|
||||
var testDate = new Date(2014, 0, 22, 12, 46, 54);
|
||||
spyOn($log, 'warn');
|
||||
expect(amMoment.preprocessDate(testDate.getTime(), 'blabla').valueOf()).toEqual(testDate.getTime());
|
||||
expect($log.warn).toHaveBeenCalledWith('angular-moment: Ignoring unsupported value for preprocess: blabla');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('amTimeAgoConfig constant', function () {
|
||||
it('should generate time with suffix by default', function () {
|
||||
expect(amTimeAgoConfig.withoutSuffix).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('angularMomentConfig constant', function () {
|
||||
it('should have an empty timezone value by default', function () {
|
||||
expect(angularMomentConfig.timezone).toBe('');
|
||||
});
|
||||
it('should have an empty preprocess value by default', function () {
|
||||
expect(angularMomentConfig.preprocess).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "angular-qrcode",
|
||||
"version": "3.1.0",
|
||||
"main": "qrcode.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1.0.6",
|
||||
"qrcode-generator": "git://github.com/monospaced/bower-qrcode-generator.git#0.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/monospaced/angular-qrcode",
|
||||
"_release": "3.1.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v3.1.0",
|
||||
"commit": "29d8c3729aa554b4f73cc146b92aff3a83c97c99"
|
||||
},
|
||||
"_source": "https://github.com/monospaced/angular-qrcode.git",
|
||||
"_target": "~3.1.0",
|
||||
"_originalSource": "angular-qrcode"
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
Angular QR Code
|
||||
===============
|
||||
|
||||
<qrcode></qrcode>
|
||||
|
||||
An AngularJS directive to creates QR Codes using Kazuhiko Arase’s [qrcode-generator](https://github.com/kazuhikoarase/qrcode-generator) library.
|
||||
|
||||
[See it in action](http://monospaced.github.io/angular-qrcode).
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
as element
|
||||
|
||||
<qrcode data="string"></qrcode>
|
||||
|
||||
with options
|
||||
|
||||
<qrcode version="2" error-correction-level="M" size="200" data="string"></qrcode>
|
||||
|
||||
with expressions, observe changes
|
||||
|
||||
<qrcode version="{{version}}" error-correction-level="{{level}}" size="{{size}}" data="{{var}}"></qrcode>
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
Permitted values
|
||||
|
||||
* version: 1-10
|
||||
|
||||
* error-correction-level: 'L', 'M', 'Q', 'H'
|
||||
|
||||
* size: integer
|
||||
|
||||
The amount of data (measured in bits) must be within capacity according to the selected version and error correction level, see http://www.qrcode.com/en/about/version.html.
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
bower install monospaced/angular-qrcode
|
||||
|
||||
Include the [qrcode generator library](https://raw.github.com/monospaced/bower-qrcode-generator/master/js/qrcode.js) and the `qrcode.js` script provided by this component in your app, and add `monospaced.qrcode` to your app’s dependencies.
|
||||
|
||||
Demo
|
||||
----------------
|
||||
|
||||
[monospaced.github.io/angular-qrcode](http://monospaced.github.io/angular-qrcode)
|
||||
|
||||
Reference
|
||||
----------------
|
||||
|
||||
[QR Code versions](http://www.qrcode.com/en/about/version.html)
|
||||
|
||||
[QR Code error correction](http://www.qrcode.com/en/about/error_correction.html)
|
||||
@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "angular-qrcode",
|
||||
"version": "3.1.0",
|
||||
"main": "qrcode.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": ">=1.0.6",
|
||||
"qrcode-generator": "git://github.com/monospaced/bower-qrcode-generator.git#0.0.0"
|
||||
}
|
||||
}
|
||||
@ -1,161 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-gb" data-ng-app="monospaced.qrcode" id="ng-app">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Angular QR Code</title>
|
||||
<!--[if lte IE 8]>
|
||||
<script>document.createElement('qrcode');</script>
|
||||
<![endif]-->
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" href="//necolas.github.io/normalize.css/2.1.1/normalize.css">
|
||||
<style>
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
background: #fff;
|
||||
color: #1c000e;
|
||||
}
|
||||
body {
|
||||
margin: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
margin: 0 8px 8px;
|
||||
font-weight: normal;
|
||||
font-size: 30px;
|
||||
}
|
||||
small {
|
||||
display: block;
|
||||
clear: both;
|
||||
margin: 0 8px;
|
||||
}
|
||||
p,
|
||||
pre {
|
||||
margin: 16px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
form {
|
||||
margin: 0 auto 8px;
|
||||
width: 274px;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
label {
|
||||
float: left;
|
||||
width: 60px;
|
||||
color: #888;
|
||||
text-align: left;
|
||||
line-height: 2.125;
|
||||
cursor: pointer;
|
||||
}
|
||||
input,
|
||||
textarea {
|
||||
float: right;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 7px 3px 7px 7px;
|
||||
width: 204px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
select {
|
||||
float: right;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 204px;
|
||||
height: 34px;
|
||||
padding: 7px 3px 7px 7px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
-webkit-transition: all 250ms ease-in-out;
|
||||
-moz-transition: all 250ms ease-in-out;
|
||||
-o-transition: all 250ms ease-in-out;
|
||||
transition: all 250ms ease-in-out;
|
||||
}
|
||||
a:hover,
|
||||
a:focus,
|
||||
a:active {
|
||||
color: #0067ce;
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
img,
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 0 auto 8px;
|
||||
padding: 8px 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
.footer {
|
||||
margin: 0 auto;
|
||||
width: 290px;
|
||||
}
|
||||
.footer img,
|
||||
.footer canvas {
|
||||
display: block;
|
||||
margin: 0 0 8px;
|
||||
padding: 8px;
|
||||
}
|
||||
.pull-left {
|
||||
float: left;
|
||||
}
|
||||
.pull-right {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-ng-init="foo='here comes qr!';v=3;e='M';s=274;">
|
||||
|
||||
<h1>Angular QR Code</h1>
|
||||
|
||||
<pre><qrcode></qrcode></pre>
|
||||
|
||||
<qrcode version="{{v}}" error-correction-level="{{e}}" size="{{s}}" data="{{foo}}"></qrcode>
|
||||
|
||||
<form>
|
||||
<p>
|
||||
<label for="data">Data</label>
|
||||
<textarea id="data" data-ng-model="foo" maxlength="2953"></textarea>
|
||||
</p>
|
||||
<p>
|
||||
<label for="size">Size</label>
|
||||
<input id="size" type="number" data-ng-model="s">
|
||||
</p>
|
||||
<p>
|
||||
<label for="version">Version</label>
|
||||
<input id="version" type="number" data-ng-model="v" min="1" max="40">
|
||||
</p>
|
||||
<p>
|
||||
<label for="level" title="Error Correction Level">Level</label>
|
||||
<select id="level" data-ng-model="e" data-ng-options="option.version as option.name for option in [{name:'Low', version:'L'},{name:'Medium', version:'M'},{name:'Quartile', version:'Q'},{name:'High', version:'H'}]"></select>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<div class="footer">
|
||||
|
||||
<qrcode version="2" error-correction-level="M" size="129" class="pull-left" data="here comes qr!"></qrcode>
|
||||
|
||||
<qrcode version="2" error-correction-level="M" size="129" data="here comes qr!"></qrcode>
|
||||
|
||||
<qrcode class="pull-left" data="https://github.com/monospaced/angular-qrcode"></qrcode>
|
||||
|
||||
<qrcode class="pull-right" data="http://monospaced.github.io/"></qrcode>
|
||||
|
||||
<small>
|
||||
<a href="https://github.com/monospaced/angular-qrcode">https://github.com/monospaced/angular-qrcode</a> <br>
|
||||
<a href="http://monospaced.github.io/">Monospaced Labs</a>
|
||||
</small>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
|
||||
<script src="//monospaced.github.io/bower-qrcode-generator/js/qrcode.js"></script>
|
||||
<script src="qrcode.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
143
server/public/lib/angular-qrcode/qrcode.js
vendored
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* angular-qrcode v3.1.0
|
||||
* (c) 2013 Monospaced http://monospaced.com
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
angular.module('monospaced.qrcode', [])
|
||||
.directive('qrcode', ['$window', function($window) {
|
||||
|
||||
var canvas2D = !!$window.CanvasRenderingContext2D,
|
||||
levels = {
|
||||
'L': 'Low',
|
||||
'M': 'Medium',
|
||||
'Q': 'Quartile',
|
||||
'H': 'High'
|
||||
},
|
||||
draw = function(context, qr, modules, tile) {
|
||||
for (var row = 0; row < modules; row++) {
|
||||
for (var col = 0; col < modules; col++) {
|
||||
var w = (Math.ceil((col + 1) * tile) - Math.floor(col * tile)),
|
||||
h = (Math.ceil((row + 1) * tile) - Math.floor(row * tile));
|
||||
|
||||
context.fillStyle = qr.isDark(row, col) ? '#000' : '#fff';
|
||||
context.fillRect(Math.round(col * tile),
|
||||
Math.round(row * tile), w, h);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<canvas></canvas>',
|
||||
link: function(scope, element, attrs) {
|
||||
var domElement = element[0],
|
||||
canvas = element.find('canvas')[0],
|
||||
context = canvas2D ? canvas.getContext('2d') : null,
|
||||
trim = /^\s+|\s+$/g,
|
||||
error,
|
||||
version,
|
||||
errorCorrectionLevel,
|
||||
data,
|
||||
size,
|
||||
modules,
|
||||
tile,
|
||||
qr,
|
||||
setVersion = function(value) {
|
||||
version = Math.max(1, Math.min(parseInt(value, 10), 10)) || 4;
|
||||
},
|
||||
setErrorCorrectionLevel = function(value) {
|
||||
errorCorrectionLevel = value in levels ? value : 'M';
|
||||
},
|
||||
setData = function(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = value.replace(trim, '');
|
||||
qr = qrcode(version, errorCorrectionLevel);
|
||||
qr.addData(data);
|
||||
|
||||
try {
|
||||
qr.make();
|
||||
} catch(e) {
|
||||
error = e.message;
|
||||
return;
|
||||
}
|
||||
|
||||
error = false;
|
||||
modules = qr.getModuleCount();
|
||||
},
|
||||
setSize = function(value) {
|
||||
size = parseInt(value, 10) || modules * 2;
|
||||
tile = size / modules;
|
||||
canvas.width = canvas.height = size;
|
||||
},
|
||||
render = function() {
|
||||
if (!qr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (!canvas2D) {
|
||||
domElement.innerHTML = '<img src width="' + size + '"' +
|
||||
'height="' + size + '">';
|
||||
}
|
||||
scope.$emit('qrcode:error', error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvas2D) {
|
||||
draw(context, qr, modules, tile);
|
||||
} else {
|
||||
domElement.innerHTML = qr.createImgTag(tile, 0);
|
||||
}
|
||||
};
|
||||
|
||||
setVersion(attrs.version);
|
||||
setErrorCorrectionLevel(attrs.errorCorrectionLevel);
|
||||
setSize(attrs.size);
|
||||
|
||||
attrs.$observe('version', function(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
setVersion(value);
|
||||
setData(data);
|
||||
setSize(size);
|
||||
render();
|
||||
});
|
||||
|
||||
attrs.$observe('errorCorrectionLevel', function(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
setErrorCorrectionLevel(value);
|
||||
setData(data);
|
||||
setSize(size);
|
||||
render();
|
||||
});
|
||||
|
||||
attrs.$observe('data', function(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
setData(value);
|
||||
setSize(size);
|
||||
render();
|
||||
});
|
||||
|
||||
attrs.$observe('size', function(value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSize(value);
|
||||
render();
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "angular-resource",
|
||||
"version": "1.2.32",
|
||||
"license": "MIT",
|
||||
"main": "./angular-resource.js",
|
||||
"ignore": [],
|
||||
"dependencies": {
|
||||
"angular": "1.2.32"
|
||||
},
|
||||
"homepage": "https://github.com/angular/bower-angular-resource",
|
||||
"_release": "1.2.32",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.2.32",
|
||||
"commit": "7dfe1d4272d09554bf4fc1f1b783b04281735a35"
|
||||
},
|
||||
"_source": "https://github.com/angular/bower-angular-resource.git",
|
||||
"_target": "~1.2.13",
|
||||
"_originalSource": "angular-resource"
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Angular
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@ -1,68 +0,0 @@
|
||||
# packaged angular-resource
|
||||
|
||||
This repo is for distribution on `npm` and `bower`. The source for this module is in the
|
||||
[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngResource).
|
||||
Please file issues and pull requests against that repo.
|
||||
|
||||
## Install
|
||||
|
||||
You can install this package either with `npm` or with `bower`.
|
||||
|
||||
### npm
|
||||
|
||||
```shell
|
||||
npm install angular-resource
|
||||
```
|
||||
|
||||
Then add `ngResource` as a dependency for your app:
|
||||
|
||||
```javascript
|
||||
angular.module('myApp', [require('angular-resource')]);
|
||||
```
|
||||
|
||||
### bower
|
||||
|
||||
```shell
|
||||
bower install angular-resource
|
||||
```
|
||||
|
||||
Add a `<script>` to your `index.html`:
|
||||
|
||||
```html
|
||||
<script src="/bower_components/angular-resource/angular-resource.js"></script>
|
||||
```
|
||||
|
||||
Then add `ngResource` as a dependency for your app:
|
||||
|
||||
```javascript
|
||||
angular.module('myApp', ['ngResource']);
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation is available on the
|
||||
[AngularJS docs site](http://docs.angularjs.org/api/ngResource).
|
||||
|
||||
## License
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@ -1,627 +0,0 @@
|
||||
/**
|
||||
* @license AngularJS v1.2.32
|
||||
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window, angular, undefined) {'use strict';
|
||||
|
||||
var $resourceMinErr = angular.$$minErr('$resource');
|
||||
|
||||
// Helper functions and regex to lookup a dotted path on an object
|
||||
// stopping at undefined/null. The path must be composed of ASCII
|
||||
// identifiers (just like $parse)
|
||||
var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
|
||||
|
||||
function isValidDottedPath(path) {
|
||||
return (path != null && path !== '' && path !== 'hasOwnProperty' &&
|
||||
MEMBER_NAME_REGEX.test('.' + path));
|
||||
}
|
||||
|
||||
function lookupDottedPath(obj, path) {
|
||||
if (!isValidDottedPath(path)) {
|
||||
throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
|
||||
}
|
||||
var keys = path.split('.');
|
||||
for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) {
|
||||
var key = keys[i];
|
||||
obj = (obj !== null) ? obj[key] : undefined;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow copy of an object and clear other fields from the destination
|
||||
*/
|
||||
function shallowClearAndCopy(src, dst) {
|
||||
dst = dst || {};
|
||||
|
||||
angular.forEach(dst, function(value, key){
|
||||
delete dst[key];
|
||||
});
|
||||
|
||||
for (var key in src) {
|
||||
if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
|
||||
dst[key] = src[key];
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name ngResource
|
||||
* @description
|
||||
*
|
||||
* # ngResource
|
||||
*
|
||||
* The `ngResource` module provides interaction support with RESTful services
|
||||
* via the $resource service.
|
||||
*
|
||||
*
|
||||
* <div doc-module-components="ngResource"></div>
|
||||
*
|
||||
* See {@link ngResource.$resource `$resource`} for usage.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $resource
|
||||
* @requires $http
|
||||
*
|
||||
* @description
|
||||
* A factory which creates a resource object that lets you interact with
|
||||
* [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
|
||||
*
|
||||
* The returned resource object has action methods which provide high-level behaviors without
|
||||
* the need to interact with the low level {@link ng.$http $http} service.
|
||||
*
|
||||
* Requires the {@link ngResource `ngResource`} module to be installed.
|
||||
*
|
||||
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
|
||||
* `/user/:username`. If you are using a URL with a port number (e.g.
|
||||
* `http://example.com:8080/api`), it will be respected.
|
||||
*
|
||||
* If you are using a url with a suffix, just add the suffix, like this:
|
||||
* `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
|
||||
* or even `$resource('http://example.com/resource/:resource_id.:format')`
|
||||
* If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
|
||||
* collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
|
||||
* can escape it with `/\.`.
|
||||
*
|
||||
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
||||
* `actions` methods. If any of the parameter value is a function, it will be executed every time
|
||||
* when a param value needs to be obtained for a request (unless the param was overridden).
|
||||
*
|
||||
* Each key value in the parameter object is first bound to url template if present and then any
|
||||
* excess keys are appended to the url search query after the `?`.
|
||||
*
|
||||
* Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
|
||||
* URL `/path/greet?salutation=Hello`.
|
||||
*
|
||||
* If the parameter value is prefixed with `@` then the value for that parameter will be extracted
|
||||
* from the corresponding property on the `data` object (provided when calling an action method). For
|
||||
* example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam`
|
||||
* will be `data.someProp`.
|
||||
*
|
||||
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend
|
||||
* the default set of resource actions. The declaration should be created in the format of {@link
|
||||
* ng.$http#usage_parameters $http.config}:
|
||||
*
|
||||
* {action1: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
||||
* ...}
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* - **`action`** – {string} – The name of action. This name becomes the name of the method on
|
||||
* your resource object.
|
||||
* - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
|
||||
* `DELETE`, `JSONP`, etc).
|
||||
* - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
|
||||
* the parameter value is a function, it will be executed every time when a param value needs to
|
||||
* be obtained for a request (unless the param was overridden).
|
||||
* - **`url`** – {string} – action specific `url` override. The url templating is supported just
|
||||
* like for the resource-level urls.
|
||||
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
|
||||
* see `returns` section.
|
||||
* - **`transformRequest`** –
|
||||
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* request body and headers and returns its transformed (typically serialized) version.
|
||||
* By default, transformRequest will contain one function that checks if the request data is
|
||||
* an object and serializes to using `angular.toJson`. To prevent this behavior, set
|
||||
* `transformRequest` to an empty array: `transformRequest: []`
|
||||
* - **`transformResponse`** –
|
||||
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
||||
* transform function or an array of such functions. The transform function takes the http
|
||||
* response body and headers and returns its transformed (typically deserialized) version.
|
||||
* By default, transformResponse will contain one function that checks if the response looks like
|
||||
* a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, set
|
||||
* `transformResponse` to an empty array: `transformResponse: []`
|
||||
* - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
|
||||
* GET request, otherwise if a cache instance built with
|
||||
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
|
||||
* caching.
|
||||
* - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
|
||||
* should abort the request when resolved.
|
||||
* - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
|
||||
* XHR object. See
|
||||
* [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
|
||||
* for more information.
|
||||
* - **`responseType`** - `{string}` - see
|
||||
* [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
|
||||
* - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
|
||||
* `response` and `responseError`. Both `response` and `responseError` interceptors get called
|
||||
* with `http response` object. See {@link ng.$http $http interceptors}.
|
||||
*
|
||||
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
||||
* optionally extended with custom `actions`. The default set contains these actions:
|
||||
* ```js
|
||||
* { 'get': {method:'GET'},
|
||||
* 'save': {method:'POST'},
|
||||
* 'query': {method:'GET', isArray:true},
|
||||
* 'remove': {method:'DELETE'},
|
||||
* 'delete': {method:'DELETE'} };
|
||||
* ```
|
||||
*
|
||||
* Calling these methods invoke an {@link ng.$http} with the specified http method,
|
||||
* destination and parameters. When the data is returned from the server then the object is an
|
||||
* instance of the resource class. The actions `save`, `remove` and `delete` are available on it
|
||||
* as methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
|
||||
* read, update, delete) on server-side data like this:
|
||||
* ```js
|
||||
* var User = $resource('/user/:userId', {userId:'@id'});
|
||||
* var user = User.get({userId:123}, function() {
|
||||
* user.abc = true;
|
||||
* user.$save();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* It is important to realize that invoking a $resource object method immediately returns an
|
||||
* empty reference (object or array depending on `isArray`). Once the data is returned from the
|
||||
* server the existing reference is populated with the actual data. This is a useful trick since
|
||||
* usually the resource is assigned to a model which is then rendered by the view. Having an empty
|
||||
* object results in no rendering, once the data arrives from the server then the object is
|
||||
* populated with the data and the view automatically re-renders itself showing the new data. This
|
||||
* means that in most cases one never has to write a callback function for the action methods.
|
||||
*
|
||||
* The action methods on the class object or instance object can be invoked with the following
|
||||
* parameters:
|
||||
*
|
||||
* - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
|
||||
* - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
|
||||
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
|
||||
*
|
||||
* Success callback is called with (value, responseHeaders) arguments. Error callback is called
|
||||
* with (httpResponse) argument.
|
||||
*
|
||||
* Class actions return empty instance (with additional properties below).
|
||||
* Instance actions return promise of the action.
|
||||
*
|
||||
* The Resource instances and collection have these additional properties:
|
||||
*
|
||||
* - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
|
||||
* instance or collection.
|
||||
*
|
||||
* On success, the promise is resolved with the same resource instance or collection object,
|
||||
* updated with data from server. This makes it easy to use in
|
||||
* {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
|
||||
* rendering until the resource(s) are loaded.
|
||||
*
|
||||
* On failure, the promise is resolved with the {@link ng.$http http response} object, without
|
||||
* the `resource` property.
|
||||
*
|
||||
* If an interceptor object was provided, the promise will instead be resolved with the value
|
||||
* returned by the interceptor.
|
||||
*
|
||||
* - `$resolved`: `true` after first server interaction is completed (either with success or
|
||||
* rejection), `false` before that. Knowing if the Resource has been resolved is useful in
|
||||
* data-binding.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* # Credit card resource
|
||||
*
|
||||
* ```js
|
||||
// Define CreditCard class
|
||||
var CreditCard = $resource('/user/:userId/card/:cardId',
|
||||
{userId:123, cardId:'@id'}, {
|
||||
charge: {method:'POST', params:{charge:true}}
|
||||
});
|
||||
|
||||
// We can retrieve a collection from the server
|
||||
var cards = CreditCard.query(function() {
|
||||
// GET: /user/123/card
|
||||
// server returns: [ {id:456, number:'1234', name:'Smith'} ];
|
||||
|
||||
var card = cards[0];
|
||||
// each item is an instance of CreditCard
|
||||
expect(card instanceof CreditCard).toEqual(true);
|
||||
card.name = "J. Smith";
|
||||
// non GET methods are mapped onto the instances
|
||||
card.$save();
|
||||
// POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
|
||||
// server returns: {id:456, number:'1234', name: 'J. Smith'};
|
||||
|
||||
// our custom method is mapped as well.
|
||||
card.$charge({amount:9.99});
|
||||
// POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
|
||||
});
|
||||
|
||||
// we can create an instance as well
|
||||
var newCard = new CreditCard({number:'0123'});
|
||||
newCard.name = "Mike Smith";
|
||||
newCard.$save();
|
||||
// POST: /user/123/card {number:'0123', name:'Mike Smith'}
|
||||
// server returns: {id:789, number:'0123', name: 'Mike Smith'};
|
||||
expect(newCard.id).toEqual(789);
|
||||
* ```
|
||||
*
|
||||
* The object returned from this function execution is a resource "class" which has "static" method
|
||||
* for each action in the definition.
|
||||
*
|
||||
* Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
|
||||
* `headers`.
|
||||
* When the data is returned from the server then the object is an instance of the resource type and
|
||||
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
||||
* operations (create, read, update, delete) on server-side data.
|
||||
|
||||
```js
|
||||
var User = $resource('/user/:userId', {userId:'@id'});
|
||||
User.get({userId:123}, function(user) {
|
||||
user.abc = true;
|
||||
user.$save();
|
||||
});
|
||||
```
|
||||
*
|
||||
* It's worth noting that the success callback for `get`, `query` and other methods gets passed
|
||||
* in the response that came from the server as well as $http header getter function, so one
|
||||
* could rewrite the above example and get access to http headers as:
|
||||
*
|
||||
```js
|
||||
var User = $resource('/user/:userId', {userId:'@id'});
|
||||
User.get({userId:123}, function(u, getResponseHeaders){
|
||||
u.abc = true;
|
||||
u.$save(function(u, putResponseHeaders) {
|
||||
//u => saved user object
|
||||
//putResponseHeaders => $http header getter
|
||||
});
|
||||
});
|
||||
```
|
||||
*
|
||||
* You can also access the raw `$http` promise via the `$promise` property on the object returned
|
||||
*
|
||||
```
|
||||
var User = $resource('/user/:userId', {userId:'@id'});
|
||||
User.get({userId:123})
|
||||
.$promise.then(function(user) {
|
||||
$scope.user = user;
|
||||
});
|
||||
```
|
||||
|
||||
* # Creating a custom 'PUT' request
|
||||
* In this example we create a custom method on our resource to make a PUT request
|
||||
* ```js
|
||||
* var app = angular.module('app', ['ngResource', 'ngRoute']);
|
||||
*
|
||||
* // Some APIs expect a PUT request in the format URL/object/ID
|
||||
* // Here we are creating an 'update' method
|
||||
* app.factory('Notes', ['$resource', function($resource) {
|
||||
* return $resource('/notes/:id', null,
|
||||
* {
|
||||
* 'update': { method:'PUT' }
|
||||
* });
|
||||
* }]);
|
||||
*
|
||||
* // In our controller we get the ID from the URL using ngRoute and $routeParams
|
||||
* // We pass in $routeParams and our Notes factory along with $scope
|
||||
* app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
|
||||
function($scope, $routeParams, Notes) {
|
||||
* // First get a note object from the factory
|
||||
* var note = Notes.get({ id:$routeParams.id });
|
||||
* $id = note.id;
|
||||
*
|
||||
* // Now call update passing in the ID first then the object you are updating
|
||||
* Notes.update({ id:$id }, note);
|
||||
*
|
||||
* // This will PUT /notes/ID with the note object in the request payload
|
||||
* }]);
|
||||
* ```
|
||||
*/
|
||||
angular.module('ngResource', ['ng']).
|
||||
factory('$resource', ['$http', '$q', function($http, $q) {
|
||||
|
||||
var DEFAULT_ACTIONS = {
|
||||
'get': {method:'GET'},
|
||||
'save': {method:'POST'},
|
||||
'query': {method:'GET', isArray:true},
|
||||
'remove': {method:'DELETE'},
|
||||
'delete': {method:'DELETE'}
|
||||
};
|
||||
var noop = angular.noop,
|
||||
forEach = angular.forEach,
|
||||
extend = angular.extend,
|
||||
copy = angular.copy,
|
||||
isFunction = angular.isFunction;
|
||||
|
||||
/**
|
||||
* We need our custom method because encodeURIComponent is too aggressive and doesn't follow
|
||||
* http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
|
||||
* segments:
|
||||
* segment = *pchar
|
||||
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
* pct-encoded = "%" HEXDIG HEXDIG
|
||||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
* / "*" / "+" / "," / ";" / "="
|
||||
*/
|
||||
function encodeUriSegment(val) {
|
||||
return encodeUriQuery(val, true).
|
||||
replace(/%26/gi, '&').
|
||||
replace(/%3D/gi, '=').
|
||||
replace(/%2B/gi, '+');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is intended for encoding *key* or *value* parts of query component. We need a
|
||||
* custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
|
||||
* have to be encoded per http://tools.ietf.org/html/rfc3986:
|
||||
* query = *( pchar / "/" / "?" )
|
||||
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
* pct-encoded = "%" HEXDIG HEXDIG
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
* / "*" / "+" / "," / ";" / "="
|
||||
*/
|
||||
function encodeUriQuery(val, pctEncodeSpaces) {
|
||||
return encodeURIComponent(val).
|
||||
replace(/%40/gi, '@').
|
||||
replace(/%3A/gi, ':').
|
||||
replace(/%24/g, '$').
|
||||
replace(/%2C/gi, ',').
|
||||
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
||||
}
|
||||
|
||||
function Route(template, defaults) {
|
||||
this.template = template;
|
||||
this.defaults = defaults || {};
|
||||
this.urlParams = {};
|
||||
}
|
||||
|
||||
Route.prototype = {
|
||||
setUrlParams: function(config, params, actionUrl) {
|
||||
var self = this,
|
||||
url = actionUrl || self.template,
|
||||
val,
|
||||
encodedVal;
|
||||
|
||||
var urlParams = self.urlParams = {};
|
||||
forEach(url.split(/\W/), function(param){
|
||||
if (param === 'hasOwnProperty') {
|
||||
throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
|
||||
}
|
||||
if (!(new RegExp("^\\d+$").test(param)) && param &&
|
||||
(new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
|
||||
urlParams[param] = true;
|
||||
}
|
||||
});
|
||||
url = url.replace(/\\:/g, ':');
|
||||
|
||||
params = params || {};
|
||||
forEach(self.urlParams, function(_, urlParam){
|
||||
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
||||
if (angular.isDefined(val) && val !== null) {
|
||||
encodedVal = encodeUriSegment(val);
|
||||
url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
|
||||
return encodedVal + p1;
|
||||
});
|
||||
} else {
|
||||
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
|
||||
leadingSlashes, tail) {
|
||||
if (tail.charAt(0) == '/') {
|
||||
return tail;
|
||||
} else {
|
||||
return leadingSlashes + tail;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// strip trailing slashes and set the url
|
||||
url = url.replace(/\/+$/, '') || '/';
|
||||
// then replace collapse `/.` if found in the last URL path segment before the query
|
||||
// E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
|
||||
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
||||
// replace escaped `/\.` with `/.`
|
||||
config.url = url.replace(/\/\\\./, '/.');
|
||||
|
||||
|
||||
// set params - delegate param encoding to $http
|
||||
forEach(params, function(value, key){
|
||||
if (!self.urlParams[key]) {
|
||||
config.params = config.params || {};
|
||||
config.params[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function resourceFactory(url, paramDefaults, actions) {
|
||||
var route = new Route(url);
|
||||
|
||||
actions = extend({}, DEFAULT_ACTIONS, actions);
|
||||
|
||||
function extractParams(data, actionParams){
|
||||
var ids = {};
|
||||
actionParams = extend({}, paramDefaults, actionParams);
|
||||
forEach(actionParams, function(value, key){
|
||||
if (isFunction(value)) { value = value(); }
|
||||
ids[key] = value && value.charAt && value.charAt(0) == '@' ?
|
||||
lookupDottedPath(data, value.substr(1)) : value;
|
||||
});
|
||||
return ids;
|
||||
}
|
||||
|
||||
function defaultResponseInterceptor(response) {
|
||||
return response.resource;
|
||||
}
|
||||
|
||||
function Resource(value){
|
||||
shallowClearAndCopy(value || {}, this);
|
||||
}
|
||||
|
||||
forEach(actions, function(action, name) {
|
||||
var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
|
||||
|
||||
Resource[name] = function(a1, a2, a3, a4) {
|
||||
var params = {}, data, success, error;
|
||||
|
||||
/* jshint -W086 */ /* (purposefully fall through case statements) */
|
||||
switch(arguments.length) {
|
||||
case 4:
|
||||
error = a4;
|
||||
success = a3;
|
||||
//fallthrough
|
||||
case 3:
|
||||
case 2:
|
||||
if (isFunction(a2)) {
|
||||
if (isFunction(a1)) {
|
||||
success = a1;
|
||||
error = a2;
|
||||
break;
|
||||
}
|
||||
|
||||
success = a2;
|
||||
error = a3;
|
||||
//fallthrough
|
||||
} else {
|
||||
params = a1;
|
||||
data = a2;
|
||||
success = a3;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
if (isFunction(a1)) success = a1;
|
||||
else if (hasBody) data = a1;
|
||||
else params = a1;
|
||||
break;
|
||||
case 0: break;
|
||||
default:
|
||||
throw $resourceMinErr('badargs',
|
||||
"Expected up to 4 arguments [params, data, success, error], got {0} arguments",
|
||||
arguments.length);
|
||||
}
|
||||
/* jshint +W086 */ /* (purposefully fall through case statements) */
|
||||
|
||||
var isInstanceCall = this instanceof Resource;
|
||||
var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
|
||||
var httpConfig = {};
|
||||
var responseInterceptor = action.interceptor && action.interceptor.response ||
|
||||
defaultResponseInterceptor;
|
||||
var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
|
||||
undefined;
|
||||
|
||||
forEach(action, function(value, key) {
|
||||
if (key != 'params' && key != 'isArray' && key != 'interceptor') {
|
||||
httpConfig[key] = copy(value);
|
||||
}
|
||||
});
|
||||
|
||||
if (hasBody) httpConfig.data = data;
|
||||
route.setUrlParams(httpConfig,
|
||||
extend({}, extractParams(data, action.params || {}), params),
|
||||
action.url);
|
||||
|
||||
var promise = $http(httpConfig).then(function (response) {
|
||||
var data = response.data,
|
||||
promise = value.$promise;
|
||||
|
||||
if (data) {
|
||||
// Need to convert action.isArray to boolean in case it is undefined
|
||||
// jshint -W018
|
||||
if (angular.isArray(data) !== (!!action.isArray)) {
|
||||
throw $resourceMinErr('badcfg',
|
||||
'Error in resource configuration. Expected ' +
|
||||
'response to contain an {0} but got an {1}',
|
||||
action.isArray ? 'array' : 'object',
|
||||
angular.isArray(data) ? 'array' : 'object');
|
||||
}
|
||||
// jshint +W018
|
||||
if (action.isArray) {
|
||||
value.length = 0;
|
||||
forEach(data, function (item) {
|
||||
if (typeof item === "object") {
|
||||
value.push(new Resource(item));
|
||||
} else {
|
||||
// Valid JSON values may be string literals, and these should not be converted
|
||||
// into objects. These items will not have access to the Resource prototype
|
||||
// methods, but unfortunately there
|
||||
value.push(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
shallowClearAndCopy(data, value);
|
||||
value.$promise = promise;
|
||||
}
|
||||
}
|
||||
|
||||
value.$resolved = true;
|
||||
|
||||
response.resource = value;
|
||||
|
||||
return response;
|
||||
}, function(response) {
|
||||
value.$resolved = true;
|
||||
|
||||
(error||noop)(response);
|
||||
|
||||
return $q.reject(response);
|
||||
});
|
||||
|
||||
promise = promise.then(
|
||||
function(response) {
|
||||
var value = responseInterceptor(response);
|
||||
(success||noop)(value, response.headers);
|
||||
return value;
|
||||
},
|
||||
responseErrorInterceptor);
|
||||
|
||||
if (!isInstanceCall) {
|
||||
// we are creating instance / collection
|
||||
// - set the initial promise
|
||||
// - return the instance / collection
|
||||
value.$promise = promise;
|
||||
value.$resolved = false;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// instance call
|
||||
return promise;
|
||||
};
|
||||
|
||||
|
||||
Resource.prototype['$' + name] = function(params, success, error) {
|
||||
if (isFunction(params)) {
|
||||
error = success; success = params; params = {};
|
||||
}
|
||||
var result = Resource[name].call(this, params, this, success, error);
|
||||
return result.$promise || result;
|
||||
};
|
||||
});
|
||||
|
||||
Resource.bind = function(additionalParamDefaults){
|
||||
return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
|
||||
};
|
||||
|
||||
return Resource;
|
||||
}
|
||||
|
||||
return resourceFactory;
|
||||
}]);
|
||||
|
||||
|
||||
})(window, window.angular);
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
AngularJS v1.2.32
|
||||
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
License: MIT
|
||||
*/
|
||||
(function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
|
||||
b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f<c&&k!==A;f++){var g=a[f];k=null!==k?k[g]:A}}else k=b;e[d]=k});return e}function e(a){return a.resource}function f(a){D(a||{},this)}var F=new c(n);l=x({},B,l);s(l,function(h,d){var c=/^(POST|PUT|PATCH)$/i.test(h.method);f[d]=function(b,d,k,w){var q={},n,l,y;switch(arguments.length){case 4:y=w,l=k;case 3:case 2:if(u(d)){if(u(b)){l=
|
||||
b;y=d;break}l=d;y=k}else{q=b;n=d;l=k;break}case 1:u(b)?l=b:c?n=b:q=b;break;case 0:break;default:throw v("badargs",arguments.length);}var t=this instanceof f,m=t?n:h.isArray?[]:new f(n),z={},B=h.interceptor&&h.interceptor.response||e,C=h.interceptor&&h.interceptor.responseError||A;s(h,function(a,b){"params"!=b&&("isArray"!=b&&"interceptor"!=b)&&(z[b]=G(a))});c&&(z.data=n);F.setUrlParams(z,x({},r(n,h.params||{}),q),h.url);q=p(z).then(function(b){var d=b.data,k=m.$promise;if(d){if(a.isArray(d)!==!!h.isArray)throw v("badcfg",
|
||||
h.isArray?"array":"object",a.isArray(d)?"array":"object");h.isArray?(m.length=0,s(d,function(b){"object"===typeof b?m.push(new f(b)):m.push(b)})):(D(d,m),m.$promise=k)}m.$resolved=!0;b.resource=m;return b},function(b){m.$resolved=!0;(y||E)(b);return g.reject(b)});q=q.then(function(b){var a=B(b);(l||E)(a,b.headers);return a},C);return t?q:(m.$promise=q,m.$resolved=!1,m)};f.prototype["$"+d]=function(b,a,k){u(b)&&(k=a,a=b,b={});b=f[d].call(this,b,this,a,k);return b.$promise||b}});f.bind=function(a){return t(n,
|
||||
x({},w,a),l)};return f}var B={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},E=a.noop,s=a.forEach,x=a.extend,G=a.copy,u=a.isFunction;c.prototype={setUrlParams:function(c,g,l){var r=this,e=l||r.template,f,p,h=r.urlParams={};s(e.split(/\W/),function(a){if("hasOwnProperty"===a)throw v("badname");!/^\d+$/.test(a)&&(a&&RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(e))&&(h[a]=!0)});e=e.replace(/\\:/g,":");g=g||{};s(r.urlParams,function(d,
|
||||
c){f=g.hasOwnProperty(c)?g[c]:r.defaults[c];a.isDefined(f)&&null!==f?(p=encodeURIComponent(f).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),e=e.replace(RegExp(":"+c+"(\\W|$)","g"),function(a,c){return p+c})):e=e.replace(RegExp("(/?):"+c+"(\\W|$)","g"),function(a,c,d){return"/"==d.charAt(0)?d:c+d})});e=e.replace(/\/+$/,"")||"/";e=e.replace(/\/\.(?=\w+($|\?))/,".");c.url=e.replace(/\/\\\./,
|
||||
"/.");s(g,function(a,e){r.urlParams[e]||(c.params=c.params||{},c.params[e]=a)})}};return t}])})(window,window.angular);
|
||||
//# sourceMappingURL=angular-resource.min.js.map
|
||||