<commit_before>const BaseHistogram = require('./base-histogram');
const debug = require('debug')('windshaft:dataview:numeric-histogram');

const columnCastTpl = ctx => `date_part('epoch', ${ctx.column})`;

const filterOutSpecialNumericValues = ctx => `
        ${ctx.column} != 'infinity'::float
    AND
        ${ctx.column} != '-infinity'::float
    AND
        ${ctx.column} != 'NaN'::float
`;

const filteredQueryTpl = ctx => `
    __cdb_filtered_source AS (
        SELECT *
        FROM (${ctx.query}) __cdb_filtered_source_query
        WHERE ${ctx.column} IS NOT NULL
        ${ctx.isFloatColumn ? `AND ${filterOutSpecialNumericValues(ctx)}` : ''}
    )
`;

const basicsQueryTpl = ctx => `
    __cdb_basics AS (
        SELECT
            max(${ctx.column}) AS __cdb_max_val, min(${ctx.column}) AS __cdb_min_val,
            avg(${ctx.column}) AS __cdb_avg_val, count(1) AS __cdb_total_rows
        FROM __cdb_filtered_source
    )
`;

const overrideBasicsQueryTpl = ctx => `
    __cdb_basics AS (
        SELECT
            max(${ctx.end}) AS __cdb_max_val, min(${ctx.start}) AS __cdb_min_val,
            avg(${ctx.column}) AS __cdb_avg_val, count(1) AS __cdb_total_rows
        FROM __cdb_filtered_source
    )
`;

const iqrQueryTpl = ctx => `
    __cdb_iqrange AS (
        SELECT max(quartile_max) - min(quartile_max) AS __cdb_iqr
        FROM (
            SELECT quartile, max(_cdb_iqr_column) AS quartile_max from (
                SELECT ${ctx.column} AS _cdb_iqr_column, ntile(4) over (order by ${ctx.column}
            ) AS quartile
            FROM __cdb_filtered_source) _cdb_quartiles
            WHERE quartile = 1 or quartile = 3
            GROUP BY quartile
        ) __cdb_iqr
    )
`;

const binsQueryTpl = ctx => `
    __cdb_bins AS (
        SELECT
            CASE WHEN __cdb_total_rows = 0 OR __cdb_iqr = 0
            THEN 1
            ELSE GREATEST(
                LEAST(${ctx.minBins}, CAST(__cdb_total_rows AS INT)),
                LEAST(
                    CAST(((__cdb_max_val - __cdb_min_val) / (2 * __cdb_iqr * power(__cdb_total_rows, 1/3))) AS INT),
                    ${ctx.maxBins}
                )
            )
            END AS __cdb_bins_number
        FROM __cdb_basics, __cdb_iqrange, __cdb_filtered_source
        LIMIT 1
    )
`;

const overrideBinsQueryTpl = ctx => `
    __cdb_bins AS (
        SELECT ${ctx.override.bins} AS __cdb_bins_number
    )
`;

const nullsQueryTpl = ctx => `
    __cdb_nulls AS (
        SELECT
            count(*) AS __cdb_nulls_count
        FROM (${ctx.query}) __cdb_histogram_nulls
        WHERE ${ctx.column} IS NULL
    )
`;

const infinitiesQueryTpl = ctx => `
    __cdb_infinities AS (
        SELECT
            count(*) AS __cdb_infinities_count
        FROM (${ctx.query}) __cdb_infinities_query
        WHERE
            ${ctx.column} = 'infinity'::float
        OR
            ${ctx.column} = '-infinity'::float
    )
`;

const nansQueryTpl = ctx => `
    __cdb_nans AS (
        SELECT
            count(*) AS __cdb_nans_count
        FROM (${ctx.query}) __cdb_nans_query
        WHERE ${ctx.column} = 'NaN'::float
    )
`;

const specialNumericValuesColumnDefinitionTpl = () => `
    __cdb_infinities_count AS infinities_count,
    __cdb_nans_count AS nans_count
`;

const specialNumericValuesCTETpl = () => `
    __cdb_infinities, __cdb_nans
`;

const specialNumericValuesColumnTpl = () => `
    infinities_count, nans_count
`;

const histogramQueryTpl = ctx => `
    SELECT
        (__cdb_max_val - __cdb_min_val) / cast(__cdb_bins_number as float) AS bin_width,
        __cdb_bins_number AS bins_number,
        __cdb_nulls_count AS nulls_count,
        ${ctx.isFloatColumn ? `${specialNumericValuesColumnDefinitionTpl()},` : ''}
        __cdb_avg_val AS avg_val,
        CASE WHEN __cdb_min_val = __cdb_max_val
            THEN 0
            ELSE GREATEST(
                1,
                LEAST(
                    WIDTH_BUCKET(${ctx.column}, __cdb_min_val, __cdb_max_val, __cdb_bins_number),
                    __cdb_bins_number
                )
            ) - 1
        END AS bin,
        min(${ctx.column})::numeric AS min,
        max(${ctx.column})::numeric AS max,
        avg(${ctx.column})::numeric AS avg,
        count(*) AS freq
    FROM __cdb_filtered_source, __cdb_basics, __cdb_nulls, __cdb_bins
        ${ctx.isFloatColumn ? `, ${specialNumericValuesCTETpl()}` : ''}
    GROUP BY bin, bins_number, bin_width, nulls_count, avg_val
        ${ctx.isFloatColumn ? `, ${specialNumericValuesColumnTpl()}` : ''}
    ORDER BY bin
`;

const BIN_MIN_NUMBER = 6;
const BIN_MAX_NUMBER = 48;

/**
Numeric histogram:
{
    type: 'histogram',
    options: {
        column: 'name', // column data type: numeric
        bins: 10 // OPTIONAL
    }
}
*/
module.exports = class NumericHistogram extends BaseHistogram {
    constructor (query, options, queries) {
        super(query, options, queries);
    }

    _buildQuery (psql, override, callback) {
        const histogramSql = this._buildQueryTpl({
            override: override,
            column: this._columnType === 'date' ? columnCastTpl({ column: this.column }) : this.column,
            isFloatColumn: this._columnType === 'float',
            query: this.query,
            start: this._getBinStart(override),
            end: this._getBinEnd(override),
            minBins: BIN_MIN_NUMBER,
            maxBins: BIN_MAX_NUMBER,
        });

        debug(histogramSql);

        return callback(null, histogramSql);
    }

    _buildQueryTpl (ctx) {
        return `
            WITH
            ${filteredQueryTpl(ctx)},
            ${this._hasOverridenRange(ctx.override) ? overrideBasicsQueryTpl(ctx) : basicsQueryTpl(ctx)},
            ${this._hasOverridenBins(ctx.override) ?
                overrideBinsQueryTpl(ctx) :
                `${iqrQueryTpl(ctx)}, ${binsQueryTpl(ctx)}`
            },
            ${nullsQueryTpl(ctx)}
            ${ctx.isFloatColumn ? `,${infinitiesQueryTpl(ctx)}, ${nansQueryTpl(ctx)}` : ''}
            ${histogramQueryTpl(ctx)}
        `;
    }

    _hasOverridenBins (override) {
        return override && override.hasOwnProperty('bins');
    }

    _getSummary (result, override) {
        const firstRow = result.rows[0] || {};

        return {
            bin_width: firstRow.bin_width,
            bins_count: firstRow.bins_number,
            bins_start: this._populateBinStart(firstRow, override),
            nulls: firstRow.nulls_count,
            infinities: firstRow.infinities_count,
            nans: firstRow.nans_count,
            avg: firstRow.avg_val,
        };
    }

    _getBuckets (result) {
        return result.rows.map(({ bin, min, max, avg, freq }) => ({ bin, min, max, avg, freq }));
    }

    _populateBinStart (firstRow, override = {}) {
        let binStart;

        if (override.hasOwnProperty('start')) {
            binStart = this._getBinStart(override);
        } else {
            binStart = firstRow.min;
        }

        return binStart;
    }

};
<commit_msg>Optimize histogram queries<commit_after>const BaseHistogram = require('./base-histogram');
const debug = require('debug')('windshaft:dataview:numeric-histogram');

/** Cast the column column to epoch */
const columnCastTpl = ctx => `date_part('epoch', ${ctx.column})`;

/** If the column type is float, ignore any non numeric result (infinity / NaN) */
const handleFloatColum = ctx => `${!ctx.isFloatColumn ? `${ctx.column}` :
    `nullif(nullif(nullif(${ctx.column}, 'infinity'::float), '-infinity'::float), 'NaN'::float)`
}`;

/** Count only infinity (positive and negative) appearances */
const countInfinites = ctx => `${!ctx.isFloatColumn ? `0` :
    `sum(CASE WHEN (${ctx.column} = 'infinity'::float OR ${ctx.column} = '-infinity'::float) THEN 1 ELSE 0 END)`
}`;

/** Count only NaNs appearances*/
const countNaNs = ctx => `${!ctx.isFloatColumn ? `0` :
    `sum(CASE WHEN (${ctx.column} = 'NaN'::float) THEN 1 ELSE 0 END)`
}`;

/** Query to get min and max values from the query */
const irqQueryTpl = ctx => `
    __cdb_filtered_source AS (
        SELECT *
        FROM (${ctx.query}) __cdb_filtered_source_query
        WHERE ${handleFloatColum(ctx)} IS NOT NULL
    ),
    __cdb_basics AS (
        SELECT
            max(${ctx.column}) AS __cdb_max_val,
            min(${ctx.column}) AS __cdb_min_val,
            count(1) AS __cdb_total_rows
        FROM __cdb_filtered_source
    )
`;

/* Query to calculate the number of bins (needs irqQueryTpl before it*/
const binsQueryTpl = ctx => `
    __cdb_iqrange AS (
        SELECT max(quartile_max) - min(quartile_max) AS __cdb_iqr
        FROM (
            SELECT quartile, max(_cdb_iqr_column) AS quartile_max from (
                SELECT ${ctx.column} AS _cdb_iqr_column, ntile(4) over (order by ${ctx.column}
            ) AS quartile
            FROM __cdb_filtered_source) _cdb_quartiles
            WHERE quartile = 1 or quartile = 3
            GROUP BY quartile
        ) __cdb_iqr
    ),
    __cdb_bins AS (
        SELECT
            CASE WHEN __cdb_total_rows = 0 OR __cdb_iqr = 0
            THEN 1
            ELSE GREATEST(
                LEAST(${ctx.minBins}, CAST(__cdb_total_rows AS INT)),
                LEAST(
                    CAST(((__cdb_max_val - __cdb_min_val) / (2 * __cdb_iqr * power(__cdb_total_rows, 1/3))) AS INT),
                    ${ctx.maxBins}
                )
            )
            END AS __cdb_bins_number
        FROM __cdb_basics, __cdb_iqrange, __cdb_filtered_source
        LIMIT 1
    )
`;

const BIN_MIN_NUMBER = 6;
const BIN_MAX_NUMBER = 48;

/**
Numeric histogram:
{
    type: 'histogram',
    options: {
        column: 'name', // column data type: numeric
        bins: 10 // OPTIONAL
    }
}
*/
module.exports = class NumericHistogram extends BaseHistogram {
    constructor (query, options, queries) {
        super(query, options, queries);
    }

    _buildQuery (psql, override, callback) {
        const histogramSql = this._buildQueryTpl({
            column: this._columnType === 'date' ? columnCastTpl({ column: this.column }) : this.column,
            isFloatColumn: this._columnType === 'float',
            query: this.query,
            start: this._getBinStart(override),
            end: this._getBinEnd(override),
            bins: this._getBinsCount(override),
            minBins: BIN_MIN_NUMBER,
            maxBins: BIN_MAX_NUMBER
        });

        debug(histogramSql);

        return callback(null, histogramSql);
    }

/**
 * ctx: Object with the following values
 * ctx.column -- Column for the histogram
 * ctx.isFloatColumn - Whether the column is float or not
 * ctx.query -- Subquery to extract data
 * ctx.start -- Start value for the bins. [>= end to force calculation]
 * ctx.end -- End value for the bins.
 * ctx.bins -- Numbers of bins to generate [<0 to force calculation]
 * ctx.minBins - If !full min bins to calculate [Optional]
 * ctx.maxBins - If !full max bins to calculate [Optional]
 */
    _buildQueryTpl (ctx) {
        var extra_tables = ``;
        var extra_queries = ``;
        var extra_groupby = ``;

        if (ctx.start >= ctx.end) {
            ctx.end = `__cdb_basics.__cdb_max_val`;
            ctx.start = `__cdb_basics.__cdb_min_val`;
            extra_groupby = `, __cdb_basics.__cdb_max_val, __cdb_basics.__cdb_min_val`;
            extra_tables = `, __cdb_basics`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}`;
        }

        if (ctx.bins <= 0) {
            ctx.bins = `__cdb_bins.__cdb_bins_number`;
            extra_groupby += `, __cdb_bins.__cdb_bins_number`;
            extra_tables += `, __cdb_bins`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}, ${binsQueryTpl(ctx)}`;
        }

        return `
${extra_queries}
SELECT
    (${ctx.end} - ${ctx.start}) / ${ctx.bins}::float AS bin_width,
    ${ctx.bins} as bins_number,
    sum(CASE WHEN (${ctx.column} IS NULL) THEN 1 ELSE 0 END) AS nulls_count,
    ${countInfinites(ctx)} AS infinities_count,
    ${countNaNs(ctx)} AS nans_count,
    min(${handleFloatColum(ctx)}) AS min,
    max(${handleFloatColum(ctx)}) AS max,
    avg(${handleFloatColum(ctx)}) AS avg,
    sum(CASE WHEN (${handleFloatColum(ctx)} is not NULL) THEN 1 ELSE 0 END) as freq,
    CASE WHEN ${ctx.start} = ${ctx.end}
        THEN 0
        ELSE GREATEST(1, LEAST(${ctx.bins},
                               WIDTH_BUCKET(${handleFloatColum(ctx)}, ${ctx.start}, ${ctx.end}, ${ctx.bins}))) - 1
    END AS bin
FROM
(
    ${ctx.query}
) __cdb_filtered_source_query${extra_tables}
GROUP BY bin${extra_groupby}
ORDER BY bin;`;
    }

    _hasOverridenBins (override) {
        return override && override.hasOwnProperty('bins');
    }

    _getSummary (result, override) {
        const firstRow = result.rows[0] || {};

        var total_nulls = 0;
        var total_infinities = 0;
        var total_nans = 0;
        var total_avg = 0;
        var total_count = 0;

        result.rows.forEach(function(row) {
            total_nulls += row.nulls_count;
            total_infinities += row.infinities_count;
            total_nans += row.nans_count;
            total_avg += row.avg * row.freq;
            total_count += row.freq;
        });
        if (total_count !== 0) {
            total_avg /= total_count;
        }

        return {
            bin_width: firstRow.bin_width,
            bins_count: firstRow.bins_number,
            bins_start: this._populateBinStart(firstRow, override),
            nulls: total_nulls,
            infinities: total_infinities,
            nans: total_nans,
            avg: total_avg
        };
    }

    _getBuckets (result) {
        return result.rows.map(({ bin, min, max, avg, freq }) => ({ bin, min, max, avg, freq }));
    }

    _populateBinStart (firstRow, override = {}) {
        let binStart;

        if (override.hasOwnProperty('start')) {
            binStart = this._getBinStart(override);
        } else {
            binStart = firstRow.min;
        }

        return binStart;
    }

};
<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2020 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var EXEC_PATH = require( 'process' ).execPath;
var resolve = require( 'path' ).resolve;
var exec = require( 'child_process' ).exec;
var tape = require( 'tape' );
var IS_BROWSER = require( '@stdlib/assert/is-browser' );
var IS_WINDOWS = require( '@stdlib/assert/is-windows' );
var readFileSync = require( '@stdlib/fs/read-file' ).sync;

// VARIABLES //

var fpath = resolve( __dirname, '..', 'bin', 'cli' );
var opts = {
	'skip': IS_BROWSER || IS_WINDOWS
};

// FIXTURES //

var PKG_VERSION = require( './../package.json' ).version;

// TESTS //

tape( 'command-line interface', function test( t ) {
	t.ok( true, __filename );
	t.end();
});

tape( 'when invoked with a `--help` flag, the command-line interface prints the help text to `stderr`', opts, function test( t ) {
	var expected;
	var cmd;

	expected = readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), {
		'encoding': 'utf8'
	});
	cmd = [
		EXEC_PATH,
		fpath,
		'--help'
	];

	exec( cmd.join( ' ' ), done );

	function done( error, stdout, stderr ) {
		if ( error ) {
			t.fail( error.message );
		} else {
			t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' );
			t.strictEqual( stderr.toString(), expected+'\n', 'expected value' );
		}
		t.end();
	}
});

tape( 'when invoked with a `-h` flag, the command-line interface prints the help text to `stderr`', opts, function test( t ) {
	var expected;
	var cmd;

	expected = readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), {
		'encoding': 'utf8'
	});
	cmd = [
		EXEC_PATH,
		fpath,
		'-h'
	];

	exec( cmd.join( ' ' ), done );

	function done( error, stdout, stderr ) {
		if ( error ) {
			t.fail( error.message );
		} else {
			t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' );
			t.strictEqual( stderr.toString(), expected+'\n', 'expected value' );
		}
		t.end();
	}
});

tape( 'when invoked with a `--version` flag, the command-line interface prints the version to `stderr`', opts, function test( t ) {
	var cmd = [
		EXEC_PATH,
		fpath,
		'--version'
	];

	exec( cmd.join( ' ' ), done );

	function done( error, stdout, stderr ) {
		if ( error ) {
			t.fail( error.message );
		} else {
			t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' );
			t.strictEqual( stderr.toString(), PKG_VERSION+'\n', 'expected value' );
		}
		t.end();
	}
});

tape( 'when invoked with a `-V` flag, the command-line interface prints the version to `stderr`', opts, function test( t ) {
	var cmd = [
		EXEC_PATH,
		fpath,
		'-V'
	];

	exec( cmd.join( ' ' ), done );

	function done( error, stdout, stderr ) {
		if ( error ) {
			t.fail( error.message );
		} else {
			t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' );
			t.strictEqual( stderr.toString(), PKG_VERSION+'\n', 'expected value' );
		}
		t.end();
	}
});

tape( 'the command-line interface prints the absolute pathname of the executable', opts, function test( t ) {
	var cmd = [
		EXEC_PATH,
		fpath
	];

	exec( cmd.join( ' ' ), done );

	function done( error, stdout, stderr ) {
		var str;
		if ( error ) {
			t.fail( error.message );
		} else {
			str = stdout.toString();
			t.strictEqual( str, EXEC_PATH+'\n', 'prints pathname to `stdout`' );
			t.strictEqual( stderr.toString(), '', 'does not print to `stderr`' );
		}
		t.end();
	}
});
<commit_msg>Remove stray test file<commit_after><|endoftext|>


<commit_before>import {join} from 'path';
import pascalCase from 'pascal-case';
import merge from 'lodash.merge';
import {transform, buildExternalHelpers} from 'babel-core';
import template from './react-class.tmpl';
import dependencyTemplate from './require.tmpl';

export default function createReactCodeFactory(application) {
	const config = application.configuration.transforms['react'] || {};

	return async function createReactCode(file, demo) {
		let helpers = buildExternalHelpers(['interop-require-wildcard', 'interop-require-default'], 'var');
		let result = convertCode(file);
		let requireBlock = createRequireBlock(getDependencies(file));
		result = helpers + requireBlock + result;
		if (demo) {
			demo.dependencies = {
				pattern: file
			};
			merge(demo.dependencies, file.dependencies);
			let demoResult = convertCode(demo);
			let requireBlock = createRequireBlock(getDependencies(demo));
			demoResult = helpers + requireBlock + demoResult;
			file.demoSource = demo.source;
			file.demoBuffer = new Buffer(demoResult, 'utf-8');
		}

		file.buffer = result;
		file.in = config.inFormat;
		file.out = config.outFormat;
		return file;
	}
}

function convertCode(file) {
	let source = file.buffer.toString('utf-8');
	// TODO: This is a weak criteria to check if we have to create a wrapper
	if (source.indexOf('extends React.Component') === -1 || source.indexOf('React.createClass') !== -1)	 {
		source = createWrappedRenderFunction(file, source);
	}
	let opts = {
		whitelist: ['es6.modules'],
		externalHelpers: true
	};
	return transform(source, opts).code;
}

function createWrappedRenderFunction(file, source) {
	let patternJson = loadPatternJson(file.path);
	let dependencies = writeDependencyImports(file).join('\n');
	return renderCodeTemplate(source, dependencies, template, pascalCase(patternJson.name));
}

function writeDependencyImports(file) {
	let patterns = loadPatternJson(file.path).patterns || {};
	let dependencies = [];
	for (let name of Object.keys(file.dependencies)) {
		dependencies.push(`import ${pascalCase(name)} from '${patterns[name] || name}';`);
	}
	return dependencies;
}

function renderCodeTemplate(source, dependencies, template, className) {
	return template
		.replace('$$dependencies$$', dependencies)
		.replace('$$class-name$$', className)
		.replace('$$render-code$$', matchFirstJsxExpressionAndWrapWithReturn(source));
}

const TAG_START = '<[a-z0-9]+';
const HTML_ATTRIBUTE = '\\s+[a-z0-9]+="[^"]*?"';
const REACT_ATTRIBUTE = '\\s+[a-z0-9]+={[^}]*?}';
const SPREAD_ATTRIBUTE = '\\s+\\{\\.\\.\\.[^}]+\\}';
const ATTRIBUTES = `(?:${HTML_ATTRIBUTE}|${REACT_ATTRIBUTE}|${SPREAD_ATTRIBUTE})*`;
const TAG_END = '\\s*\\/?>';
const EXPR = new RegExp(`(${TAG_START}${ATTRIBUTES}${TAG_END}[^]*)`, 'gi');

function matchFirstJsxExpressionAndWrapWithReturn(source) {
	return source.replace(EXPR, (match, jsxExpr) => {
		return 'return (\n' + jsxExpr/*.split('\n').map(line => indent + line).join('\n')*/ + '\n);\n'
	});
}

function loadPatternJson(path) {
	return require(
		join(
			path.substring(0,
				path.lastIndexOf('/')), 'pattern.json'));
}

function rewriteImportsToGlobalNames(file, source) {
	let patterns = loadPatternJson(file.path).patterns || {};
	return source.replace(/(import\s+(?:\* as\s)?[^\s]+\s+from\s+["'])([^"']+)(["'];)/g, (match, before, name, after) => {
		return `${before}${patterns[name] || name}${after}`;
	});
}

function getDependencies(file) {
	let patterns = loadPatternJson(file.path).patterns || {};
	let dependencies = {};
	for (let name of Object.keys(file.dependencies)) {
		let globalName = patterns[name] || name;
		let dependencyFile = file.dependencies[name];
		dependencies[globalName] = dependencyFile;
		merge(dependencies, getDependencies(dependencyFile));
	}
	return dependencies;
}

function createRequireBlock(dependencies) {
	let source = [];
	for (let name of Object.keys(dependencies)) {
		source.push(`
			'${name}': function(module, exports, require) {
				${convertCode(dependencies[name]).split('\n').map(line => '\t\t\t' + line).join('\n')}
			}
		`);
	}
	return dependencyTemplate.replace('$$localDependencies$$', source.join('\n,'));
}

<commit_msg>Enabled opts to react transformer<commit_after>import {join} from 'path';
import pascalCase from 'pascal-case';
import merge from 'lodash.merge';
import {transform, buildExternalHelpers} from 'babel-core';
import template from './react-class.tmpl';
import dependencyTemplate from './require.tmpl';

export default function createReactCodeFactory(application) {
	const config = application.configuration.transforms['react'] || {};

	return async function createReactCode(file, demo) {
		let helpers = buildExternalHelpers(undefined, 'var');
		let result = convertCode(file, config.opts);
		let requireBlock = createRequireBlock(getDependencies(file));
		result = helpers + requireBlock + result;
		if (demo) {
			demo.dependencies = {
				pattern: file
			};
			merge(demo.dependencies, file.dependencies);
			let demoResult = convertCode(demo, config.opts);
			let requireBlock = createRequireBlock(getDependencies(demo));
			demoResult = helpers + requireBlock + demoResult;
			file.demoSource = demo.source;
			file.demoBuffer = new Buffer(demoResult, 'utf-8');
		}

		file.buffer = result;
		file.in = config.inFormat;
		file.out = config.outFormat;
		return file;
	}
}

function convertCode(file, opts) {
	let source = file.buffer.toString('utf-8');
	// TODO: This is a weak criteria to check if we have to create a wrapper
	if (source.indexOf('extends React.Component') === -1 || source.indexOf('React.createClass') !== -1)	 {
		source = createWrappedRenderFunction(file, source);
	} else {
		source = rewriteImportsToGlobalNames(file, source);
	}
	return transform(source, merge({externalHelpers: true}, opts)).code;
}

function createWrappedRenderFunction(file, source) {
	let patternJson = loadPatternJson(file.path);
	let dependencies = writeDependencyImports(file).join('\n');
	return renderCodeTemplate(source, dependencies, template, pascalCase(patternJson.name));
}

function writeDependencyImports(file) {
	let patterns = loadPatternJson(file.path).patterns || {};
	let dependencies = [];
	for (let name of Object.keys(file.dependencies)) {
		dependencies.push(`import ${pascalCase(name)} from '${patterns[name] || name}';`);
	}
	return dependencies;
}

function renderCodeTemplate(source, dependencies, template, className) {
	return template
		.replace('$$dependencies$$', dependencies)
		.replace('$$class-name$$', className)
		.replace('$$render-code$$', matchFirstJsxExpressionAndWrapWithReturn(source));
}

const TAG_START = '<[a-z0-9]+';
const HTML_ATTRIBUTE = '\\s+[a-z0-9]+="[^"]*?"';
const REACT_ATTRIBUTE = '\\s+[a-z0-9]+={[^}]*?}';
const SPREAD_ATTRIBUTE = '\\s+\\{\\.\\.\\.[^}]+\\}';
const ATTRIBUTES = `(?:${HTML_ATTRIBUTE}|${REACT_ATTRIBUTE}|${SPREAD_ATTRIBUTE})*`;
const TAG_END = '\\s*\\/?>';
const EXPR = new RegExp(`(${TAG_START}${ATTRIBUTES}${TAG_END}[^]*)`, 'gi');

function matchFirstJsxExpressionAndWrapWithReturn(source) {
	return source.replace(EXPR, (match, jsxExpr) => {
		return 'return (\n' + jsxExpr/*.split('\n').map(line => indent + line).join('\n')*/ + '\n);\n'
	});
}

function loadPatternJson(path) {
	return require(
		join(
			path.substring(0,
				path.lastIndexOf('/')), 'pattern.json'));
}

function rewriteImportsToGlobalNames(file, source) {
	let patterns = loadPatternJson(file.path).patterns || {};
	return source.replace(/(import\s+(?:\* as\s)?[^\s]+\s+from\s+["'])([^"']+)(["'];)/g, (match, before, name, after) => {
		return `${before}${patterns[name] || name}${after}`;
	});
}

function rewriteImportsToGlobalNames(file, source) {
	let patterns = loadPatternJson(file.path).patterns || {};
	return source.replace(/(import\s+(?:\* as\s)?[^\s]+\s+from\s+["'])([^"']+)(["'];)/g, (match, before, name, after) => {
		return `${before}${patterns[name] || name}${after}`;
	});
}

function getDependencies(file) {
	let patterns = loadPatternJson(file.path).patterns || {};
	let dependencies = {};
	for (let name of Object.keys(file.dependencies)) {
		let globalName = patterns[name] || name;
		let dependencyFile = file.dependencies[name];
		dependencies[globalName] = dependencyFile;
		merge(dependencies, getDependencies(dependencyFile));
	}
	return dependencies;
}

function createRequireBlock(dependencies) {
	let source = [];
	for (let name of Object.keys(dependencies)) {
		source.push(`
			'${name}': function(module, exports, require) {
				${convertCode(dependencies[name]).split('\n').map(line => '\t\t\t' + line).join('\n')}
			}
		`);
	}
	return dependencyTemplate.replace('$$localDependencies$$', source.join('\n,'));
}

<|endoftext|>


<commit_before>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @namespace
 *
Using Camera API allows to invoke the native camera application to record video or take a picture and receive a path to the file stored.

 *
The methods are static and don't required to create an instance of a camera.

 * @toc {Media} Camera
 * @featureID blackberry.media.camera
 */
blackberry.media.camera = {

    /**
     * @function
     * @description Opens the camera and return a path to the onCaptured callback when a photo is taken.
     * @callback {function} onCaptured Method will be invoked when a picture is captured.
Expected signature: function onCaptured(filePath)
     * @callback {String} [onCaptured.filePath] Path to a picture captured by the camera.
     * @callback {function} [onCameraClosed] Method will be invoked on camera closed event.
Expected signature: function onCameraClosed()
     * @callback {function} [onError] Method will be invoked when an error occurs.
Expected signature: function onError()
     * @BB50+
     * @PB10
     */
    takePicture: function(onCaptured, onCameraClosed, onError) {
    },
    /**
     * @function
     * @description Opens the camera and return a path to the onCaptured callback when a video is taken.
     * @callback {function} onCaptured Method will be invoked when a video is recorded.
Expected signature: function onCaptured(filePath)
     * @callback {String} [onCaptured.filePath] Path to a video captured by the camera.
     * @callback {function} [onCameraClosed] Method will be invoked on camera closed event.
Expected signature: function onCameraClosed()
     * @callback {function} [onError] Method will be invoked when an error occurs.
Expected signature: function onError()
     * @BB50+
     * @PB10
     * @example
     * function takeVideo() {
     *   try {
     *     blackberry.media.camera.takeVideo(successCB, closedCB, errorCB);
     *   } catch(e) {
     *     alert("Error in supported: " + e);
     *   }
     * }
     *
     * function successCB(filePath) {
     *   alert("Succeed: " + filePath);
     * }
     *
     * function closedCB() {
     *   alert("Camera closed event");
     * }
     *
     * function errorCB() {
     *   alert("Error occured");
     * }
     */
    takeVideo: function(onCaptured, onCameraClosed, onError) {
    }
}<commit_msg>Added permission tag requires use_camera permission.<commit_after>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @namespace
 *
Using Camera API allows to invoke the native camera application to record video or take a picture and receive a path to the file stored.

 *
The methods are static and don't required to create an instance of a camera.

 * @toc {Media} Camera
 * @featureID blackberry.media.camera
 * @permission use_camera This permission should be granted in order to be able to invoke native camera.
 */
blackberry.media.camera = {

    /**
     * @function
     * @description Opens the camera and return a path to the onCaptured callback when a photo is taken.
     * @callback {function} onCaptured Method will be invoked when a picture is captured.
Expected signature: function onCaptured(filePath)
     * @callback {String} [onCaptured.filePath] Path to a picture captured by the camera.
     * @callback {function} [onCameraClosed] Method will be invoked on camera closed event.
Expected signature: function onCameraClosed()
     * @callback {function} [onError] Method will be invoked when an error occurs.
Expected signature: function onError()
     * @BB50+
     * @PB10
     */
    takePicture: function(onCaptured, onCameraClosed, onError) {
    },
    /**
     * @function
     * @description Opens the camera and return a path to the onCaptured callback when a video is taken.
     * @callback {function} onCaptured Method will be invoked when a video is recorded.
Expected signature: function onCaptured(filePath)
     * @callback {String} [onCaptured.filePath] Path to a video captured by the camera.
     * @callback {function} [onCameraClosed] Method will be invoked on camera closed event.
Expected signature: function onCameraClosed()
     * @callback {function} [onError] Method will be invoked when an error occurs.
Expected signature: function onError()
     * @BB50+
     * @PB10
     * @example
     * function takeVideo() {
     *   try {
     *     blackberry.media.camera.takeVideo(successCB, closedCB, errorCB);
     *   } catch(e) {
     *     alert("Error in supported: " + e);
     *   }
     * }
     *
     * function successCB(filePath) {
     *   alert("Succeed: " + filePath);
     * }
     *
     * function closedCB() {
     *   alert("Camera closed event");
     * }
     *
     * function errorCB() {
     *   alert("Error occured");
     * }
     */
    takeVideo: function(onCaptured, onCameraClosed, onError) {
    }
}<|endoftext|>


<commit_before>MWF.xDesktop.requireApp("process.Xform", "$Input", null, false);
/** @class Calendar 日期组件。
 * @example
 * //可以在脚本中获取该组件
 * //方法1：
 * var field = this.form.get("fieldId"); //获取组件对象
 * //方法2
 * var field = this.target; //在组件本身的脚本中获取，比如事件脚本、默认值脚本、校验脚本等等
 * @extends MWF.xApplication.process.Xform.$Input
 * @o2category FormComponents
 * @o2range {Process|CMS|Portal}
 * @hideconstructor
 */
MWF.xApplication.process.Xform.Calendar = MWF.APPCalendar =  new Class(
    /** @lends MWF.xApplication.process.Xform.Calendar# */
{
	Implements: [Events],
	Extends: MWF.APP$Input,
	iconStyle: "calendarIcon",
    options: {
        /**
         * 日期选择完成时触发.
         * @event MWF.xApplication.process.Xform.Calendar#complete
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 日期选择器上点清空时触发.
         * @event MWF.xApplication.process.Xform.Calendar#clear
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 值改变时触发.
         * @event MWF.xApplication.process.Xform.Calendar#change
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 显示日期选择器时触发.
         * @event MWF.xApplication.process.Xform.Calendar#show
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 隐藏日期选择器时触发.
         * @event MWF.xApplication.process.Xform.Calendar#hide
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        "moduleEvents": ["queryLoad","postLoad","load","complete", "clear", "change","show","hide"]
    },
    _loadNode: function(){
        if (this.readonly || this.json.isReadonly){
            this._loadNodeRead();
        }else{
            this._loadNodeEdit();
            var input = this.node.getFirst();
            input.set("readonly", true);
        }
    },
    setDescriptionEvent: function(){
        if (this.descriptionNode){
            this.descriptionNode.addEvents({
                "mousedown": function(){
                    this.descriptionNode.setStyle("display", "none");
                    //this.clickSelect();
                }.bind(this)
            });
        }
    },
    _getValueAg: function(value,isDate){
        if (value && value.isAG){
            return value.then(function(v){
                this._getValueAg(v, isDate);
            }.bind(this), function(){});
        }else{
            var d = (!!value) ? Date.parse(value) : "";
            if (isDate){
                return d || null;
            }else{
                return (d) ? d.format(this.json.format) : "";
            }
        }
    },
    getValue: function(isDate){
        if (this.moduleValueAG) return this.moduleValueAG;
        var value = this._getBusinessData();
        if( value && !isDate)return value;
        if (!value) value = this._computeValue();
        if (value.then) return value;

        var d = (!!value) ? Date.parse(value) : "";
        if (isDate){
            return d || null;
        }else{
            //if (d) value = Date.parse(value).format(this.json.format);
            return (d) ? d.format(this.json.format) : "";
        }

        return value || "";
    },
    getValueStr : function(){
        var value = this._getBusinessData();
        if (!value) value = this._computeValue();
        return value;
    },

    __setValue: function(value){
        var v;
        if( typeOf( value ) === "date" ){
            v = (value) ? ( Date.parse(value)).format(this.json.format) : "";
        }else{
            v = value;
        }
        this._setBusinessData(value);
        if (this.node.getFirst()) this.node.getFirst().set("value", v || "");
        if (this.readonly || this.json.isReadonly) this.node.set("text", v);
        this.moduleValueAG = null;
        this.fieldModuleLoaded = true;
        return value;
    },

	clickSelect: function(){

        var _self = this;
        if (!this.calendar){
            MWF.require("MWF.widget.Calendar", function(){
                var defaultView = "day";
                if( this.json.selectType === "month" )defaultView = "month";
                if( this.json.selectType === "year" )defaultView = "year";
                var options = {
                    "style": o2.session.isMobile ? "xform_mobile" : "xform",
                    "secondEnable" : this.json.isSelectSecond,
                    "timeSelectType" : this.json.timeSelectType,
                    "isTime": (this.json.selectType==="datetime" || this.json.selectType==="time"),
                    "timeOnly": (this.json.selectType === "time"),
                    "monthOnly" : (this.json.selectType === "month"),
                    "yearOnly" : (this.json.selectType === "year"),
                    "defaultView" : defaultView,
                    //"target": this.form.node,
                    "target": layout.mobile ? $(document.body) : this.form.app.content,
                    "format": this.json.format,
                    "onComplate": function(formateDate, date){
                        this.validationMode();
                        if(this.validation()){
                            var v = this.getInputData("change");
                            this._setBusinessData(v);
                            //this._setEnvironmentData(v);
                        }
                        this.fireEvent("complete");
                    }.bind(this),
                    "onChange": function(){
                        this.fireEvent("change");
                    }.bind(this),
                    "onClear": function(){
                        this.validationMode();
                        if(this.validation()){
                            var v = this.getInputData("change");
                            this._setBusinessData(v);
                            //this._setEnvironmentData(v);
                        }
                        this.fireEvent("clear");
                        if (!this.node.getFirst().get("value")) if (this.descriptionNode)  this.descriptionNode.setStyle("display", "block");
                    }.bind(this),
                    "onShow": function(){
                        if (_self.descriptionNode) _self.descriptionNode.setStyle("display", "none");

                        if( layout.mobile ){
                            this.container.position({
                                relativeTo: $(document.body),
                                position: 'leftCenter',
                                edge: 'leftCenter'
                                //offset : { y : -25 }
                            });
                        }else{
                            var parent = _self.node.getParent();
                            while( parent ){
                                var overflow = parent.getStyle("overflow");
                                var overflowY = parent.getStyle("overflow-y");
                                if(  overflow === "auto" || overflow === "scroll" || overflowY === "auto" || overflowY === "scroll" ){
                                    _self.scrollFun = function( e ){
                                        if (this.container.position ) {
                                            this.container.position({
                                                relativeTo: this.node,
                                                position: 'bottomLeft',
                                                edge: 'upperLeft',
                                                allowNegative : true
                                            });
                                        }
                                    }.bind(this);
                                    _self.scrollParentNode = parent;
                                    parent.addEvent( "scroll", _self.scrollFun );
                                    parent = null;
                                }else{
                                    parent = parent.getParent();
                                }
                            }
                        }
                        _self.fireEvent("show");
                    },
                    "onHide": function(){
                        if (!this.node.getFirst().get("value")) if (this.descriptionNode)  this.descriptionNode.setStyle("display", "block");
                        if( _self.scrollParentNode && _self.scrollFun ){
                            _self.scrollParentNode.removeEvent("scroll", _self.scrollFun);
                        }
                        _self.fireEvent("hide");
                    }.bind(this)
                };
                options.baseDate = this.getBaseDate();
                /**
                 * @summary 日期弹出选择界面，只读情况下无此成员.
                 * @member {MWF.widget.Calendar}
                 * @example
                 * var calendar = this.form.get("fieldId").calendar; //获取组件
                 * if(calendar)calendar.show(); //弹出选择组件
                 */
                this.calendar = new MWF.widget.Calendar(this.node.getFirst(), options);
                if( this.form.json && this.form.json.canlendarStyle && typeOf( this.form.json.canlendarStyle.zIndex ) !== "null" && typeOf( this.form.json.canlendarStyle.zIndex ) !== "undefined" ){
                    this.calendar.container.setStyle("z-index", this.form.json.canlendarStyle.zIndex );
                }
                this.calendar.show();
            }.bind(this));
        }else{
            var options = {};
            options.baseDate = this.getBaseDate();
            this.calendar.setOptions(options);
            //this.calendar.show();
            this.node.getFirst().focus();
        }
	},
    getBaseDate : function(){
	    debugger;
        var d;
        var value = this.getValue(true);
        if( value && value.getTime() > 10000 ){
            d = value;
        }else{
            var ud = Date.parse( this.unformatDate( this.getValueStr() ) );
            if( ud && ud.getTime() > 10000 ){
                d = ud;
            }else{
                d = new Date();
            }
        }
        return d;
    },
    unformatDate : function( dateStr ){
        var formatStr = this.json.format;
        var matchArr = [ "%Y", "%m", "%d", "%H", "%M", "%S", "%z", "%Z" ];
        var lengthArr = [ 4, 2, 2, 2, 2, 2, 5, 3];
        var indexArr = [ formatStr.indexOf("%Y"), formatStr.indexOf("%m"), formatStr.indexOf("%d"), formatStr.indexOf("%H"), formatStr.indexOf("%M"), formatStr.indexOf("%S"), formatStr.indexOf("%z"), formatStr.indexOf("%Z") ];
        var resultArr = [ null, null, null, null, null, null, null, null ];
        for( var i=0; i<matchArr.length; i++ ){
            if( indexArr[i] === -1 )continue;
            var leftLength = 0;
            var leftUnitLength = 0;
            Array.each( indexArr, function( n, k ){
                if( n === -1 )return;
                if( indexArr[i] > n ){
                    leftLength += lengthArr[k];
                    leftUnitLength += matchArr[k].length;
                }
            });
            resultArr[i] = dateStr.substr( indexArr[i] - leftUnitLength + leftLength, lengthArr[i] );
        }
        var now = new Date();
        for( var i=0; i < resultArr.length; i++ ){
            if( !resultArr[i] ){
                switch ( matchArr[i] ){
                    case "%Y":
                    case "%m":
                    case "%d":
                        resultArr[i] = now.format( matchArr[i] );
                        break;
                    case "%H":
                    case "%M":
                    case "%S":
                        resultArr[i] = "00";
                        break;
                    case "%z":
                    case "%Z":
                    default:
                        break;
                }
            }
        }
        return resultArr[0] + "-" + resultArr[1] + "-" + resultArr[2] + " " + resultArr[3]+":"+resultArr[4]+":"+resultArr[5];
    }
});
<commit_msg>mobile<commit_after>MWF.xDesktop.requireApp("process.Xform", "$Input", null, false);
/** @class Calendar 日期组件。
 * @example
 * //可以在脚本中获取该组件
 * //方法1：
 * var field = this.form.get("fieldId"); //获取组件对象
 * //方法2
 * var field = this.target; //在组件本身的脚本中获取，比如事件脚本、默认值脚本、校验脚本等等
 * @extends MWF.xApplication.process.Xform.$Input
 * @o2category FormComponents
 * @o2range {Process|CMS|Portal}
 * @hideconstructor
 */
MWF.xApplication.process.Xform.Calendar = MWF.APPCalendar =  new Class(
    /** @lends MWF.xApplication.process.Xform.Calendar# */
{
	Implements: [Events],
	Extends: MWF.APP$Input,
	iconStyle: "calendarIcon",
    options: {
        /**
         * 日期选择完成时触发.
         * @event MWF.xApplication.process.Xform.Calendar#complete
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 日期选择器上点清空时触发.
         * @event MWF.xApplication.process.Xform.Calendar#clear
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 值改变时触发.
         * @event MWF.xApplication.process.Xform.Calendar#change
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 显示日期选择器时触发.
         * @event MWF.xApplication.process.Xform.Calendar#show
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        /**
         * 隐藏日期选择器时触发.
         * @event MWF.xApplication.process.Xform.Calendar#hide
         * @see {@link https://www.yuque.com/o2oa/ixsnyt/hm5uft#i0zTS|组件事件说明}
         */
        "moduleEvents": ["queryLoad","postLoad","load","complete", "clear", "change","show","hide"]
    },
    _loadNode: function(){
        if (this.readonly || this.json.isReadonly){
            this._loadNodeRead();
        }else{
            this._loadNodeEdit();
            var input = this.node.getFirst();
            input.set("readonly", true);
        }
    },
    setDescriptionEvent: function(){
        if (this.descriptionNode){
            this.descriptionNode.addEvents({
                "mousedown": function(){
                    this.descriptionNode.setStyle("display", "none");
                    //this.clickSelect();
                }.bind(this)
            });
        }
    },
    _getValueAg: function(value,isDate){
        if (value && value.isAG){
            return value.then(function(v){
                this._getValueAg(v, isDate);
            }.bind(this), function(){});
        }else{
            var d = (!!value) ? Date.parse(value) : "";
            if (isDate){
                return d || null;
            }else{
                return (d) ? d.format(this.json.format) : "";
            }
        }
    },
    getValue: function(isDate){
        if (this.moduleValueAG) return this.moduleValueAG;
        var value = this._getBusinessData();
        if( value && !isDate)return value;
        if (!value) value = this._computeValue();
        if (value.then) return value;

        var d = (!!value) ? Date.parse(value) : "";
        if (isDate){
            return d || null;
        }else{
            //if (d) value = Date.parse(value).format(this.json.format);
            return (d) ? d.format(this.json.format) : "";
        }

        return value || "";
    },
    getValueStr : function(){
        var value = this._getBusinessData();
        if (!value) value = this._computeValue();
        return value;
    },

    __setValue: function(value){
        var v;
        if( typeOf( value ) === "date" ){
            v = (value) ? ( Date.parse(value)).format(this.json.format) : "";
        }else{
            v = value;
        }
        this._setBusinessData(value);
        if (this.node.getFirst()) this.node.getFirst().set("value", v || "");
        if (this.readonly || this.json.isReadonly) this.node.set("text", v);
        this.moduleValueAG = null;
        this.fieldModuleLoaded = true;
        return value;
    },

	clickSelect: function(){

        var _self = this;
        if (!this.calendar){
            MWF.require("MWF.widget.Calendar", function(){
                var defaultView = "day";
                if( this.json.selectType === "month" )defaultView = "month";
                if( this.json.selectType === "year" )defaultView = "year";
                var options = {
                    "style": o2.session.isMobile ? "xform_mobile" : "xform",
                    "secondEnable" : this.json.isSelectSecond,
                    "timeSelectType" : this.json.timeSelectType,
                    "isTime": (this.json.selectType==="datetime" || this.json.selectType==="time"),
                    "timeOnly": (this.json.selectType === "time"),
                    "monthOnly" : (this.json.selectType === "month"),
                    "yearOnly" : (this.json.selectType === "year"),
                    "defaultView" : defaultView,
                    //"target": this.form.node,
                    "target": o2.session.isMobile ? $(document.body) : this.form.app.content,
                    "format": this.json.format,
                    "onComplate": function(formateDate, date){
                        this.validationMode();
                        if(this.validation()){
                            var v = this.getInputData("change");
                            this._setBusinessData(v);
                            //this._setEnvironmentData(v);
                        }
                        this.fireEvent("complete");
                    }.bind(this),
                    "onChange": function(){
                        this.fireEvent("change");
                    }.bind(this),
                    "onClear": function(){
                        this.validationMode();
                        if(this.validation()){
                            var v = this.getInputData("change");
                            this._setBusinessData(v);
                            //this._setEnvironmentData(v);
                        }
                        this.fireEvent("clear");
                        if (!this.node.getFirst().get("value")) if (this.descriptionNode)  this.descriptionNode.setStyle("display", "block");
                    }.bind(this),
                    "onShow": function(){
                        if (_self.descriptionNode) _self.descriptionNode.setStyle("display", "none");

                        if( o2.session.isMobile ){
                            this.container.position({
                                relativeTo: $(document.body),
                                position: 'leftCenter',
                                edge: 'leftCenter'
                                //offset : { y : -25 }
                            });
                        }else{
                            var parent = _self.node.getParent();
                            while( parent ){
                                var overflow = parent.getStyle("overflow");
                                var overflowY = parent.getStyle("overflow-y");
                                if(  overflow === "auto" || overflow === "scroll" || overflowY === "auto" || overflowY === "scroll" ){
                                    _self.scrollFun = function( e ){
                                        if (this.container.position ) {
                                            this.container.position({
                                                relativeTo: this.node,
                                                position: 'bottomLeft',
                                                edge: 'upperLeft',
                                                allowNegative : true
                                            });
                                        }
                                    }.bind(this);
                                    _self.scrollParentNode = parent;
                                    parent.addEvent( "scroll", _self.scrollFun );
                                    parent = null;
                                }else{
                                    parent = parent.getParent();
                                }
                            }
                        }
                        _self.fireEvent("show");
                    },
                    "onHide": function(){
                        if (!this.node.getFirst().get("value")) if (this.descriptionNode)  this.descriptionNode.setStyle("display", "block");
                        if( _self.scrollParentNode && _self.scrollFun ){
                            _self.scrollParentNode.removeEvent("scroll", _self.scrollFun);
                        }
                        _self.fireEvent("hide");
                    }.bind(this)
                };
                options.baseDate = this.getBaseDate();
                /**
                 * @summary 日期弹出选择界面，只读情况下无此成员.
                 * @member {MWF.widget.Calendar}
                 * @example
                 * var calendar = this.form.get("fieldId").calendar; //获取组件
                 * if(calendar)calendar.show(); //弹出选择组件
                 */
                this.calendar = new MWF.widget.Calendar(this.node.getFirst(), options);
                if( this.form.json && this.form.json.canlendarStyle && typeOf( this.form.json.canlendarStyle.zIndex ) !== "null" && typeOf( this.form.json.canlendarStyle.zIndex ) !== "undefined" ){
                    this.calendar.container.setStyle("z-index", this.form.json.canlendarStyle.zIndex );
                }
                this.calendar.show();
            }.bind(this));
        }else{
            var options = {};
            options.baseDate = this.getBaseDate();
            this.calendar.setOptions(options);
            //this.calendar.show();
            this.node.getFirst().focus();
        }
	},
    getBaseDate : function(){
	    debugger;
        var d;
        var value = this.getValue(true);
        if( value && value.getTime() > 10000 ){
            d = value;
        }else{
            var ud = Date.parse( this.unformatDate( this.getValueStr() ) );
            if( ud && ud.getTime() > 10000 ){
                d = ud;
            }else{
                d = new Date();
            }
        }
        return d;
    },
    unformatDate : function( dateStr ){
        var formatStr = this.json.format;
        var matchArr = [ "%Y", "%m", "%d", "%H", "%M", "%S", "%z", "%Z" ];
        var lengthArr = [ 4, 2, 2, 2, 2, 2, 5, 3];
        var indexArr = [ formatStr.indexOf("%Y"), formatStr.indexOf("%m"), formatStr.indexOf("%d"), formatStr.indexOf("%H"), formatStr.indexOf("%M"), formatStr.indexOf("%S"), formatStr.indexOf("%z"), formatStr.indexOf("%Z") ];
        var resultArr = [ null, null, null, null, null, null, null, null ];
        for( var i=0; i<matchArr.length; i++ ){
            if( indexArr[i] === -1 )continue;
            var leftLength = 0;
            var leftUnitLength = 0;
            Array.each( indexArr, function( n, k ){
                if( n === -1 )return;
                if( indexArr[i] > n ){
                    leftLength += lengthArr[k];
                    leftUnitLength += matchArr[k].length;
                }
            });
            resultArr[i] = dateStr.substr( indexArr[i] - leftUnitLength + leftLength, lengthArr[i] );
        }
        var now = new Date();
        for( var i=0; i < resultArr.length; i++ ){
            if( !resultArr[i] ){
                switch ( matchArr[i] ){
                    case "%Y":
                    case "%m":
                    case "%d":
                        resultArr[i] = now.format( matchArr[i] );
                        break;
                    case "%H":
                    case "%M":
                    case "%S":
                        resultArr[i] = "00";
                        break;
                    case "%z":
                    case "%Z":
                    default:
                        break;
                }
            }
        }
        return resultArr[0] + "-" + resultArr[1] + "-" + resultArr[2] + " " + resultArr[3]+":"+resultArr[4]+":"+resultArr[5];
    }
});
<|endoftext|>


<commit_before>"use strict";

const debug = require('debug')('bus-eta-bot-sg:bot/command-handlers/help');
const telegram = require('../../telegram');

/**
 * Handler for /help command
 * @param {Bot} bot
 * @param {IncomingTextMessage} msg
 * @returns {Promise}
 */
module.exports = function (bot, msg) {
  const action_type = 'help_display';

  const chat_id = msg.chat_id;

  const text = `*Bus Eta Bot Help*
Commands:
\`/eta [bus stop code] [service numbers]\` - Get etas for a particular bus stop, optionally filtered by specific service numbers.
\`/history\` - List your most recent successful eta queries.
\`/version\` - Show the current Bus Eta Bot version.
\`/about\` - View more information about this bot.
\`/help\` - Display this message.`;

  const config = {
    parse_mode: 'Markdown'
  };

  return new telegram.OutgoingTextMessage(text, config).send(chat_id)

    // analytics
    .then(() => Promise.all([bot.analytics.logAction(action_type), bot.analytics.logUser(action_type, msg)]))

    .catch(err => {
      debug(err);
      return bot.analytics.logError(action_type, err.message);
    });
};
<commit_msg>Removed monospace formatting from commands in help text<commit_after>"use strict";

const debug = require('debug')('bus-eta-bot-sg:bot/command-handlers/help');
const telegram = require('../../telegram');

/**
 * Handler for /help command
 * @param {Bot} bot
 * @param {IncomingTextMessage} msg
 * @returns {Promise}
 */
module.exports = function (bot, msg) {
  const action_type = 'help_display';

  const chat_id = msg.chat_id;

  const text = `*Bus Eta Bot Help*
Commands:
/eta [bus stop code] [service numbers] - Get etas for a particular bus stop, optionally filtered by specific service numbers.
/history - List your most recent successful eta queries.
/version - Show the current Bus Eta Bot version.
/about - View more information about this bot.
/help - Display this message.`;

  const config = {
    parse_mode: 'Markdown'
  };

  return new telegram.OutgoingTextMessage(text, config).send(chat_id)

    // analytics
    .then(() => Promise.all([bot.analytics.logAction(action_type), bot.analytics.logUser(action_type, msg)]))

    .catch(err => {
      debug(err);
      return bot.analytics.logError(action_type, err.message);
    });
};
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2012, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

 define(function(require, exports) {
  "use strict";

  var oop = require("../lib/oop");
  var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

  var NSISHighlightRules = function() {
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
      start: [{
        token: "keyword.compiler.nsis",
        regex: /^\s*%NSIS_IMPORTANT%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.command.nsis",
        regex: /^\s*%NSIS_KEYWORDS%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.control.nsis",
        regex: /^\s*%NSIS_IMPORTANT_BLOCKS%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.plugin.nsis",
        regex: /^\s*\w+::\w+/,
        caseInsensitive: true
      }, {
        token: "keyword.operator.comparison.nsis",
        regex: /[!<>]?=|<>|<|>/
      }, {
        token: "support.function.nsis",
        regex: /(?:\b|^\s*)%NSIS_BLOCKS%\b/,
        caseInsensitive: true
      }, {
        token: "support.library.nsis",
        regex: /\${[\w.:-]+}/
      }, {
        token: "constant.nsis",
        regex: /\b%NSIS_PROPERTIES_UPPERCASE%\b/,
        caseInsensitive: true
      }, {
        token: "constant.library.nsis",
        regex: /\${(?:AtLeastServicePack|AtLeastWin7|AtLeastWin8|AtLeastWin10|AtLeastWin95|AtLeastWin98|AtLeastWin2000|AtLeastWin2003|AtLeastWin2008|AtLeastWin2008R2|AtLeastWinME|AtLeastWinNT4|AtLeastWinVista|AtLeastWinXP|AtMostServicePack|AtMostWin7|AtMostWin8|AtMostWin10|AtMostWin95|AtMostWin98|AtMostWin2000|AtMostWin2003|AtMostWin2008|AtMostWin2008R2|AtMostWinME|AtMostWinNT4|AtMostWinVista|AtMostWinXP|IsDomainController|IsNT|IsServer|IsServicePack|IsWin7|IsWin8|IsWin10|IsWin95|IsWin98|IsWin2000|IsWin2003|IsWin2008|IsWin2008R2|IsWinME|IsWinNT4|IsWinVista|IsWinXP)}/
      }, {
        token: "constant.language.boolean.true.nsis",
        regex: /\b(?:true|on)\b/
      }, {
        token: "constant.language.boolean.false.nsis",
        regex: /\b(?:false|off)\b/
      }, {
        token: "constant.language.option.nsis",
        regex: /(?:\b|^\s*)%NSIS_PROPERTIES_LOWERCASE%\b/,
        caseInsensitive: true
      }, {
        token: "constant.language.slash-option.nsis",
        regex: /\b\/(?:a|BRANDING|CENTER|COMPONENTSONLYONCUSTOM|CUSTOMSTRING=|date|e|ENABLECANCEL|FILESONLY|file|FINAL|GLOBAL|gray|ifempty|ifndef|ignorecase|IMGID=|ITALIC|LANG=|NOCUSTOM|noerrors|NONFATAL|nonfatal|oname=|o|REBOOTOK|redef|RESIZETOFIT|r|SHORT|SILENT|SOLID|STRIKE|TRIM|UNDERLINE|utcdate|windows|x)\b/,
        caseInsensitive: true
      }, {
        token: "constant.numeric.nsis",
        regex: /\b(?:0(?:x|X)[0-9a-fA-F]+|[0-9]+(?:\.[0-9]+)?)\b/
      }, {
        token: "entity.name.function.nsis",
        regex: /\$\([\w.:-]+\)/
      }, {
        token: "storage.type.function.nsis",
        regex: /\$\w+/
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /`/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /`/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.back.nsis"
        }]
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /"/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /"/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.double.nsis"
        }]
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /'/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /'/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.single.nsis"
        }]
      }, {
        token: [
        "punctuation.definition.comment.nsis",
        "comment.line.nsis"
        ],
        regex: /(;|#)(.*$)/
      }, {
        token: "punctuation.definition.comment.nsis",
        regex: /\/\*/,
        push: [{
          token: "punctuation.definition.comment.nsis",
          regex: /\*\//,
          next: "pop"
        }, {
          defaultToken: "comment.block.nsis"
        }]
      }, {
        token: "text",
        regex: /(?:!include|!insertmacro)\b/
      }]
    };

    this.normalizeRules();
  };

  NSISHighlightRules.metaData = {
    comment: "\n\ttodo: - highlight functions\n\t",
    fileTypes: ["nsi", "nsh", "bnsi", "bnsh", "nsdinc"],
    name: "NSIS",
    scopeName: "source.nsis"
  };

  oop.inherits(NSISHighlightRules, TextHighlightRules);

  exports.NSISHighlightRules = NSISHighlightRules;
});
<commit_msg>remove comment<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2012, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

 define(function(require, exports) {
  "use strict";

  var oop = require("../lib/oop");
  var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

  var NSISHighlightRules = function() {
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
      start: [{
        token: "keyword.compiler.nsis",
        regex: /^\s*%NSIS_IMPORTANT%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.command.nsis",
        regex: /^\s*%NSIS_KEYWORDS%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.control.nsis",
        regex: /^\s*%NSIS_IMPORTANT_BLOCKS%\b/,
        caseInsensitive: true
      }, {
        token: "keyword.plugin.nsis",
        regex: /^\s*\w+::\w+/,
        caseInsensitive: true
      }, {
        token: "keyword.operator.comparison.nsis",
        regex: /[!<>]?=|<>|<|>/
      }, {
        token: "support.function.nsis",
        regex: /(?:\b|^\s*)%NSIS_BLOCKS%\b/,
        caseInsensitive: true
      }, {
        token: "support.library.nsis",
        regex: /\${[\w.:-]+}/
      }, {
        token: "constant.nsis",
        regex: /\b%NSIS_PROPERTIES_UPPERCASE%\b/,
        caseInsensitive: true
      }, {
        token: "constant.library.nsis",
        regex: /\${(?:AtLeastServicePack|AtLeastWin7|AtLeastWin8|AtLeastWin10|AtLeastWin95|AtLeastWin98|AtLeastWin2000|AtLeastWin2003|AtLeastWin2008|AtLeastWin2008R2|AtLeastWinME|AtLeastWinNT4|AtLeastWinVista|AtLeastWinXP|AtMostServicePack|AtMostWin7|AtMostWin8|AtMostWin10|AtMostWin95|AtMostWin98|AtMostWin2000|AtMostWin2003|AtMostWin2008|AtMostWin2008R2|AtMostWinME|AtMostWinNT4|AtMostWinVista|AtMostWinXP|IsDomainController|IsNT|IsServer|IsServicePack|IsWin7|IsWin8|IsWin10|IsWin95|IsWin98|IsWin2000|IsWin2003|IsWin2008|IsWin2008R2|IsWinME|IsWinNT4|IsWinVista|IsWinXP)}/
      }, {
        token: "constant.language.boolean.true.nsis",
        regex: /\b(?:true|on)\b/
      }, {
        token: "constant.language.boolean.false.nsis",
        regex: /\b(?:false|off)\b/
      }, {
        token: "constant.language.option.nsis",
        regex: /(?:\b|^\s*)%NSIS_PROPERTIES_LOWERCASE%\b/,
        caseInsensitive: true
      }, {
        token: "constant.language.slash-option.nsis",
        regex: /\b\/(?:a|BRANDING|CENTER|COMPONENTSONLYONCUSTOM|CUSTOMSTRING=|date|e|ENABLECANCEL|FILESONLY|file|FINAL|GLOBAL|gray|ifempty|ifndef|ignorecase|IMGID=|ITALIC|LANG=|NOCUSTOM|noerrors|NONFATAL|nonfatal|oname=|o|REBOOTOK|redef|RESIZETOFIT|r|SHORT|SILENT|SOLID|STRIKE|TRIM|UNDERLINE|utcdate|windows|x)\b/,
        caseInsensitive: true
      }, {
        token: "constant.numeric.nsis",
        regex: /\b(?:0(?:x|X)[0-9a-fA-F]+|[0-9]+(?:\.[0-9]+)?)\b/
      }, {
        token: "entity.name.function.nsis",
        regex: /\$\([\w.:-]+\)/
      }, {
        token: "storage.type.function.nsis",
        regex: /\$\w+/
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /`/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /`/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.back.nsis"
        }]
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /"/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /"/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.double.nsis"
        }]
      }, {
        token: "punctuation.definition.string.begin.nsis",
        regex: /'/,
        push: [{
          token: "punctuation.definition.string.end.nsis",
          regex: /'/,
          next: "pop"
        }, {
          token: "constant.character.escape.nsis",
          regex: /\$\\./
        }, {
          defaultToken: "string.quoted.single.nsis"
        }]
      }, {
        token: [
        "punctuation.definition.comment.nsis",
        "comment.line.nsis"
        ],
        regex: /(;|#)(.*$)/
      }, {
        token: "punctuation.definition.comment.nsis",
        regex: /\/\*/,
        push: [{
          token: "punctuation.definition.comment.nsis",
          regex: /\*\//,
          next: "pop"
        }, {
          defaultToken: "comment.block.nsis"
        }]
      }, {
        token: "text",
        regex: /(?:!include|!insertmacro)\b/
      }]
    };

    this.normalizeRules();
  };

  NSISHighlightRules.metaData = {
    fileTypes: ["nsi", "nsh", "bnsi", "bnsh", "nsdinc"],
    name: "NSIS",
    scopeName: "source.nsis"
  };

  oop.inherits(NSISHighlightRules, TextHighlightRules);

  exports.NSISHighlightRules = NSISHighlightRules;
});
<|endoftext|>


<commit_before>'use strict';

const core = require('./core.js');
const fd = require('./field.js');
const serv = require('./../services/services.js');
const servWeather = require('./../services/weatherService.js');
const db = require('./../AslanDBConnector.js');
/*
*   Fonction qui traite les réponses de type bonjour
*/
function processingGrettings(information, response) {
	if(information != undefined && response != undefined && information.first_name != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{prenom}") != -1) {
			var answer = fd.replaceField(response.result.fulfillment.speech, "{prenom}", information.first_name);
			core.prepareMessage(answer);
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingHour(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.ville != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{heure}") != -1) {
			console.log(response.result.parameters.ville);
			serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				core.prepareMessage(answer);
			});
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingFountain(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.location != undefined) {
		serv.nearestFontaines(response.result.parameters.location, 20, function(foutains) {
			message["attachment"] = foutains;
			core.prepareMessage(message);
		});
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingCitizen(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.ville != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{heure}") != -1) {
			console.log(response.result.parameters.ville);
			serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				console.log(answer);
				core.prepareMessage(answer);
			});
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingDate(response) {

}

function processingWeather(message, location) {
	if(message != undefined && message.result != undefined && message.result.parameters != undefined) {
		var fields = fd.extractFields(message.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{meteo}") != -1) {
			var coord = "";
			if(location) {

			} else if(message.result.parameters["geo-city"] != undefined){
				coord = message.result.parameters["geo-city"];
			}
			servWeather.JSONP_LocalWeather(coord, formattedDate(), function(response) {
				console.log(response.data);
				if(response.data != null && response.data.current_condition != null) {
					var weather = "";
					if(response.data.current_condition['0'].lang_fr != null)
						weather = response.data.current_condition['0'].lang_fr['0'].value + ", ";
					weather +=  response.data.current_condition['0'].temp_C + "°";
					var answer = fd.replaceField(message.result.fulfillment.speech, "{meteo}", weather);
					core.prepareMessage(answer);
				}
			});
		} else {
			core.prepareMessage(message.result.fulfillment.speech);
		}
	} else {
		core.prepareMessage(message.result.fulfillment.speech);
	}
}

function processingRestaurant(response, location) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{\"location\":[]}") != -1) {
			response.result.fulfillment.speech = fd.removeFields(response.result.fulfillment.speech);
			db.insertData("conversation", response.result, function(err, data) {
				console.log(err);
			});
			core.askLocation();
		} else if (fields.indexOf("{restaurants}") != -1 && location != null){
			console.log("on appelle le service")
			core.prepareMessage(response);
			/*serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				console.log(answer);
				core.prepareMessage(answer);
			});*/
		} else {
			core.prepareMessage(response.result.fulfillment.speech);
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function formattedDate(d = new Date) {
  let month = String(d.getMonth() + 1);
  let day = String(d.getDate());
  const year = String(d.getFullYear());

  if (month.length < 2) month = '0' + month;
  if (day.length < 2) day = '0' + day;

  return `${year}-${month}-${day}`;
}
exports.processingGrettings = processingGrettings;
exports.processingHour = processingHour;
exports.processingFountain = processingFountain;
exports.processingCitizen = processingCitizen;
exports.processingDate = processingDate;
exports.processingWeather = processingWeather;
exports.processingRestaurant = processingRestaurant;<commit_msg>Fix bug sauvegarde<commit_after>'use strict';

const core = require('./core.js');
const fd = require('./field.js');
const serv = require('./../services/services.js');
const servWeather = require('./../services/weatherService.js');
const db = require('./../AslanDBConnector.js');
/*
*   Fonction qui traite les réponses de type bonjour
*/
function processingGrettings(information, response) {
	if(information != undefined && response != undefined && information.first_name != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{prenom}") != -1) {
			var answer = fd.replaceField(response.result.fulfillment.speech, "{prenom}", information.first_name);
			core.prepareMessage(answer);
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingHour(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.ville != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{heure}") != -1) {
			console.log(response.result.parameters.ville);
			serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				core.prepareMessage(answer);
			});
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingFountain(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.location != undefined) {
		serv.nearestFontaines(response.result.parameters.location, 20, function(foutains) {
			message["attachment"] = foutains;
			core.prepareMessage(message);
		});
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingCitizen(response) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined
		&& response.result.parameters.ville != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{heure}") != -1) {
			console.log(response.result.parameters.ville);
			serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				console.log(answer);
				core.prepareMessage(answer);
			});
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function processingDate(response) {

}

function processingWeather(message, location) {
	if(message != undefined && message.result != undefined && message.result.parameters != undefined) {
		var fields = fd.extractFields(message.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{\"location\":[]}") != -1) {
			response.result.fulfillment.speech = fd.removeFields(response.result.fulfillment.speech);
			db.insertData("conversation", response.result, function(err, data) {
				console.log(err);
			});
			core.askLocation();
		} else if(fields.indexOf("{meteo}") != -1) {
			var coord = "";
			if(location) {

			} else if(message.result.parameters["geo-city"] != undefined){
				coord = message.result.parameters["geo-city"];
			}
			servWeather.JSONP_LocalWeather(coord, formattedDate(), function(response) {
				console.log(response.data);
				if(response.data != null && response.data.current_condition != null) {
					var weather = "";
					if(response.data.current_condition['0'].lang_fr != null)
						weather = response.data.current_condition['0'].lang_fr['0'].value + ", ";
					weather +=  response.data.current_condition['0'].temp_C + "°";
					var answer = fd.replaceField(message.result.fulfillment.speech, "{meteo}", weather);
					core.prepareMessage(answer);
				}
			});
		} else {
			core.prepareMessage(message.result.fulfillment.speech);
		}
	} else {
		core.prepareMessage(message.result.fulfillment.speech);
	}
}

function processingRestaurant(response, location) {
	if(response != undefined && response.result != undefined && response.result.parameters != undefined) {
		var fields = fd.extractFields(response.result.fulfillment.speech);
		console.log(fields);
		if(fields.indexOf("{\"location\":[]}") != -1) {
			response.result.fulfillment.speech = fd.removeFields(response.result.fulfillment.speech);
			db.insertData("conversation", {metadata: response.result.metadata, fulfillment: response.result.fulfillment}, function(err, data) {
				console.log(err);
			});
			core.askLocation();
		} else if (fields.indexOf("{restaurants}") != -1 && location != null){
			console.log("on appelle le service")
			core.prepareMessage(response);
			/*serv.getTimeAt(response.result.parameters.ville, function(hour) {
				var answer = fd.replaceField(response.result.fulfillment.speech, "{heure}",hour);
				answer = fd.replaceField(answer,
					"{\"ville\":[\"" + response.result.parameters.ville + "\"]}", response.result.parameters.ville);
				console.log(answer);
				core.prepareMessage(answer);
			});*/
		} else {
			core.prepareMessage(response.result.fulfillment.speech);
		}
	} else {
		core.prepareMessage(response.result.fulfillment.speech);
	}
}

function formattedDate(d = new Date) {
  let month = String(d.getMonth() + 1);
  let day = String(d.getDate());
  const year = String(d.getFullYear());

  if (month.length < 2) month = '0' + month;
  if (day.length < 2) day = '0' + day;

  return `${year}-${month}-${day}`;
}
exports.processingGrettings = processingGrettings;
exports.processingHour = processingHour;
exports.processingFountain = processingFountain;
exports.processingCitizen = processingCitizen;
exports.processingDate = processingDate;
exports.processingWeather = processingWeather;
exports.processingRestaurant = processingRestaurant;<|endoftext|>