<commit_before>import { errors } from 'arsenal';
import { parseString } from 'xml2js';

import api from '../api/api';
import routesUtils from './routesUtils';
import utils from '../utils';
import pushMetrics from '../utilities/pushMetrics';
import statsReport500 from '../utilities/statsReport500';

const encryptionHeaders = [
    'x-amz-server-side-encryption',
    'x-amz-server-side-encryption-customer-algorithm',
    'x-amz-server-side-encryption-aws-kms-key-id',
    'x-amz-server-side-encryption-context',
    'x-amz-server-side-encryption-customer-key',
    'x-amz-server-side-encryption-customer-key-md5',
];

const validStatuses = ['Enabled', 'Suspended'];
const validMfaDeletes = [undefined, 'Enabled', 'Disabled'];

/* eslint-disable no-param-reassign */
export default function routePUT(request, response, log, utapi, statsClient) {
    log.debug('routing request', { method: 'routePUT' });

    if (request.objectKey === undefined || request.objectKey === '/') {
        request.post = '';
        request.on('data', chunk => {
            request.post += chunk.toString();
        });

        request.on('end', () => {
            // PUT bucket ACL
            if (request.query.acl !== undefined) {
                api.callApiMethod('bucketPutACL', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'bucketPutACL',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            } else if (request.query.versioning !== undefined) {
                if (request.post === '') {
                    log.debug('request xml is missing');
                    return routesUtils.responseNoBody(
                        errors.MalformedXML, null, response, null, log);
                }
                const xmlToParse = request.post;
                return parseString(xmlToParse, (err, result) => {
                    if (err) {
                        log.debug('request xml is malformed');
                        return routesUtils.responseNoBody(
                            errors.MalformedXML, null, response, null, log);
                    }
                    const status = result.VersioningConfiguration.Status ?
                        result.VersioningConfiguration.Status[0] : undefined;
                    const mfaDelete = result.VersioningConfiguration.MfaDelete ?
                        result.VersioningConfiguration.MfaDelete[0] : undefined;
                    if (validStatuses.indexOf(status) < 0 ||
                        validMfaDeletes.indexOf(mfaDelete) < 0) {
                        log.debug('illegal versioning configuration');
                        return routesUtils.responseNoBody(
                            errors.IllegalVersioningConfigurationException,
                            null, response, null, log);
                    }
                    if (mfaDelete) {
                        log.debug('mfa deletion is not implemented');
                        return routesUtils.responseNoBody(
                            errors.NotImplemented.customizedDescription(
                                'MFA Deletion is not supported yet.'), null,
                            response, null, log);
                    }
                    return api.callApiMethod('bucketPutVersioning', request,
                        log, err => {
                            // TODO push metrics for bucketPutVersioning
                            // pushMetrics(err, log, utapi,
                            //         'bucketPutVersioning',
                            //         request.bucketName);
                            statsReport500(err, statsClient);
                            routesUtils.responseNoBody(
                                err, null, response, 200, log);
                        });
                });
            } else if (request.query.acl === undefined) {
                // PUT bucket
                if (request.post) {
                    const xmlToParse = request.post;
                    return parseString(xmlToParse, (err, result) => {
                        if (err || !result.CreateBucketConfiguration
                            || !result.CreateBucketConfiguration
                                .LocationConstraint
                            || !result.CreateBucketConfiguration
                                .LocationConstraint[0]) {
                            log.debug('request xml is malformed');
                            return routesUtils.responseNoBody(errors
                                .MalformedXML,
                                null, response, null, log);
                        }
                        const locationConstraint =
                            result.CreateBucketConfiguration
                            .LocationConstraint[0];
                        log.trace('location constraint',
                            { locationConstraint });
                        return api.callApiMethod('bucketPut', request, log,
                        err => {
                            statsReport500(err, statsClient);
                            pushMetrics(err, log, utapi, 'bucketPut',
                                request.bucketName);
                            return routesUtils.responseNoBody(err, null,
                              response, 200, log);
                        }, locationConstraint);
                    });
                }
                return api.callApiMethod('bucketPut', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'bucketPut',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            }
            return undefined;
        });
    } else {
        // PUT object, PUT object ACL, PUT object multipart or
        // PUT object copy
        // if content-md5 is not present in the headers, try to
        // parse content-md5 from meta headers

        if (request.headers['content-md5'] === '') {
            log.debug('empty content-md5 header', {
                method: 'routePUT',
            });
            return routesUtils
            .responseNoBody(errors.InvalidDigest, null, response, 200, log);
        }
        if (request.headers['content-md5']) {
            request.contentMD5 = request.headers['content-md5'];
        } else {
            request.contentMD5 = utils.parseContentMD5(request.headers);
        }
        if (request.contentMD5 && request.contentMD5.length !== 32) {
            request.contentMD5 = Buffer.from(request.contentMD5, 'base64')
                .toString('hex');
            if (request.contentMD5 && request.contentMD5.length !== 32) {
                log.warn('invalid md5 digest', {
                    contentMD5: request.contentMD5,
                });
                return routesUtils
                    .responseNoBody(errors.InvalidDigest, null, response, 200,
                                    log);
            }
        }
        // object level encryption
        if (encryptionHeaders.some(i => request.headers[i] !== undefined)) {
            return routesUtils.responseXMLBody(errors.NotImplemented, null,
                response, log);
        }
        if (request.query.partNumber) {
            if (request.headers['x-amz-copy-source']) {
                api.callApiMethod('objectPutCopyPart', request, log,
                (err, xml, additionalHeaders) => {
                    statsReport500(err, statsClient);
                    return routesUtils.responseXMLBody(err, xml, response, log,
                            additionalHeaders);
                });
            } else {
                api.callApiMethod('objectPutPart', request, log,
                    (err, calculatedHash) => {
                        // ETag's hex should always be enclosed in quotes
                        const resMetaHeaders = { ETag: `"${calculatedHash}"` };
                        statsReport500(err, statsClient);
                        pushMetrics(err, log, utapi, 'objectPutPart',
                            request.bucketName, request.parsedContentLength);
                        routesUtils.responseNoBody(err, resMetaHeaders,
                            response, 200, log);
                    });
            }
        } else if (request.query.acl !== undefined) {
            request.post = '';
            request.on('data', chunk => {
                request.post += chunk.toString();
            });
            request.on('end', () => {
                api.callApiMethod('objectPutACL', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'objectPutACL',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            });
        } else if (request.headers['x-amz-copy-source']) {
            return api.callApiMethod('objectCopy', request, log, (err, xml,
                additionalHeaders, sourceObjSize, destObjPrevSize) => {
                statsReport500(err, statsClient);
                pushMetrics(err, log, utapi, 'objectCopy', request.bucketName,
                    sourceObjSize, destObjPrevSize);
                routesUtils.responseXMLBody(err, xml, response, log,
                    additionalHeaders);
            });
        } else {
            if (request.headers['content-length'] === undefined &&
            request.headers['x-amz-decoded-content-length'] === undefined) {
                return routesUtils.responseNoBody(errors.MissingContentLength,
                    null, response, 411, log);
            }
            if (Number.isNaN(request.parsedContentLength) ||
            request.parsedContentLength < 0) {
                return routesUtils.responseNoBody(errors.BadRequest,
                    null, response, 400, log);
            }
            log.end().addDefaultFields({
                contentLength: request.parsedContentLength,
            });

            api.callApiMethod('objectPut', request, log,
                (err, contentMD5, prevContentLen) => {
                    // ETag's hex should always be enclosed in quotes
                    statsReport500(err, statsClient);
                    const resMetaHeaders = {
                        ETag: `"${contentMD5}"`,
                    };
                    pushMetrics(err, log, utapi, 'objectPut',
                        request.bucketName, request.parsedContentLength,
                        prevContentLen);
                    return routesUtils.responseNoBody(err, resMetaHeaders,
                        response, 200, log);
                });
        }
    }
    return undefined;
}
/* eslint-enable no-param-reassign */
<commit_msg>COMPAT: PUT empty content-lenght header FIXES #437<commit_after>import { errors } from 'arsenal';
import { parseString } from 'xml2js';

import api from '../api/api';
import routesUtils from './routesUtils';
import utils from '../utils';
import pushMetrics from '../utilities/pushMetrics';
import statsReport500 from '../utilities/statsReport500';

const encryptionHeaders = [
    'x-amz-server-side-encryption',
    'x-amz-server-side-encryption-customer-algorithm',
    'x-amz-server-side-encryption-aws-kms-key-id',
    'x-amz-server-side-encryption-context',
    'x-amz-server-side-encryption-customer-key',
    'x-amz-server-side-encryption-customer-key-md5',
];

const validStatuses = ['Enabled', 'Suspended'];
const validMfaDeletes = [undefined, 'Enabled', 'Disabled'];

/* eslint-disable no-param-reassign */
export default function routePUT(request, response, log, utapi, statsClient) {
    log.debug('routing request', { method: 'routePUT' });

    if (request.objectKey === undefined || request.objectKey === '/') {
        // PUT bucket - PUT bucket ACL

        // content-length for object is handled separately below
        const contentLength = request.headers['content-length'];
        if (contentLength && (isNaN(contentLength) || contentLength === '' ||
        contentLength < 0)) {
            log.debug('invalid content-length header');
            return routesUtils.responseNoBody(
              errors.BadRequest, null, response, null, log);
        }
        request.post = '';
        request.on('data', chunk => {
            request.post += chunk.toString();
        });

        request.on('end', () => {
            // PUT bucket ACL
            if (request.query.acl !== undefined) {
                api.callApiMethod('bucketPutACL', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'bucketPutACL',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            } else if (request.query.versioning !== undefined) {
                if (request.post === '') {
                    log.debug('request xml is missing');
                    return routesUtils.responseNoBody(
                        errors.MalformedXML, null, response, null, log);
                }
                const xmlToParse = request.post;
                return parseString(xmlToParse, (err, result) => {
                    if (err) {
                        log.debug('request xml is malformed');
                        return routesUtils.responseNoBody(
                            errors.MalformedXML, null, response, null, log);
                    }
                    const status = result.VersioningConfiguration.Status ?
                        result.VersioningConfiguration.Status[0] : undefined;
                    const mfaDelete = result.VersioningConfiguration.MfaDelete ?
                        result.VersioningConfiguration.MfaDelete[0] : undefined;
                    if (validStatuses.indexOf(status) < 0 ||
                        validMfaDeletes.indexOf(mfaDelete) < 0) {
                        log.debug('illegal versioning configuration');
                        return routesUtils.responseNoBody(
                            errors.IllegalVersioningConfigurationException,
                            null, response, null, log);
                    }
                    if (mfaDelete) {
                        log.debug('mfa deletion is not implemented');
                        return routesUtils.responseNoBody(
                            errors.NotImplemented.customizedDescription(
                                'MFA Deletion is not supported yet.'), null,
                            response, null, log);
                    }
                    return api.callApiMethod('bucketPutVersioning', request,
                        log, err => {
                            // TODO push metrics for bucketPutVersioning
                            // pushMetrics(err, log, utapi,
                            //         'bucketPutVersioning',
                            //         request.bucketName);
                            statsReport500(err, statsClient);
                            routesUtils.responseNoBody(
                                err, null, response, 200, log);
                        });
                });
            } else if (request.query.acl === undefined) {
                // PUT bucket
                if (request.post) {
                    const xmlToParse = request.post;
                    return parseString(xmlToParse, (err, result) => {
                        if (err || !result.CreateBucketConfiguration
                            || !result.CreateBucketConfiguration
                                .LocationConstraint
                            || !result.CreateBucketConfiguration
                                .LocationConstraint[0]) {
                            log.debug('request xml is malformed');
                            return routesUtils.responseNoBody(errors
                                .MalformedXML,
                                null, response, null, log);
                        }
                        const locationConstraint =
                            result.CreateBucketConfiguration
                            .LocationConstraint[0];
                        log.trace('location constraint',
                            { locationConstraint });
                        return api.callApiMethod('bucketPut', request, log,
                        err => {
                            statsReport500(err, statsClient);
                            pushMetrics(err, log, utapi, 'bucketPut',
                                request.bucketName);
                            return routesUtils.responseNoBody(err, null,
                              response, 200, log);
                        }, locationConstraint);
                    });
                }
                return api.callApiMethod('bucketPut', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'bucketPut',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            }
            return undefined;
        });
    } else {
        // PUT object, PUT object ACL, PUT object multipart or
        // PUT object copy
        // if content-md5 is not present in the headers, try to
        // parse content-md5 from meta headers

        if (request.headers['content-md5'] === '') {
            log.debug('empty content-md5 header', {
                method: 'routePUT',
            });
            return routesUtils
            .responseNoBody(errors.InvalidDigest, null, response, 200, log);
        }
        if (request.headers['content-md5']) {
            request.contentMD5 = request.headers['content-md5'];
        } else {
            request.contentMD5 = utils.parseContentMD5(request.headers);
        }
        if (request.contentMD5 && request.contentMD5.length !== 32) {
            request.contentMD5 = Buffer.from(request.contentMD5, 'base64')
                .toString('hex');
            if (request.contentMD5 && request.contentMD5.length !== 32) {
                log.warn('invalid md5 digest', {
                    contentMD5: request.contentMD5,
                });
                return routesUtils
                    .responseNoBody(errors.InvalidDigest, null, response, 200,
                                    log);
            }
        }
        // object level encryption
        if (encryptionHeaders.some(i => request.headers[i] !== undefined)) {
            return routesUtils.responseXMLBody(errors.NotImplemented, null,
                response, log);
        }
        if (request.query.partNumber) {
            if (request.headers['x-amz-copy-source']) {
                api.callApiMethod('objectPutCopyPart', request, log,
                (err, xml, additionalHeaders) => {
                    statsReport500(err, statsClient);
                    return routesUtils.responseXMLBody(err, xml, response, log,
                            additionalHeaders);
                });
            } else {
                api.callApiMethod('objectPutPart', request, log,
                    (err, calculatedHash) => {
                        // ETag's hex should always be enclosed in quotes
                        const resMetaHeaders = { ETag: `"${calculatedHash}"` };
                        statsReport500(err, statsClient);
                        pushMetrics(err, log, utapi, 'objectPutPart',
                            request.bucketName, request.parsedContentLength);
                        routesUtils.responseNoBody(err, resMetaHeaders,
                            response, 200, log);
                    });
            }
        } else if (request.query.acl !== undefined) {
            request.post = '';
            request.on('data', chunk => {
                request.post += chunk.toString();
            });
            request.on('end', () => {
                api.callApiMethod('objectPutACL', request, log, err => {
                    statsReport500(err, statsClient);
                    pushMetrics(err, log, utapi, 'objectPutACL',
                        request.bucketName);
                    return routesUtils.responseNoBody(err, null, response, 200,
                        log);
                });
            });
        } else if (request.headers['x-amz-copy-source']) {
            return api.callApiMethod('objectCopy', request, log, (err, xml,
                additionalHeaders, sourceObjSize, destObjPrevSize) => {
                statsReport500(err, statsClient);
                pushMetrics(err, log, utapi, 'objectCopy', request.bucketName,
                    sourceObjSize, destObjPrevSize);
                routesUtils.responseXMLBody(err, xml, response, log,
                    additionalHeaders);
            });
        } else {
            if (request.headers['content-length'] === undefined &&
            request.headers['x-amz-decoded-content-length'] === undefined) {
                return routesUtils.responseNoBody(errors.MissingContentLength,
                    null, response, 411, log);
            }
            if (Number.isNaN(request.parsedContentLength) ||
            request.parsedContentLength < 0) {
                return routesUtils.responseNoBody(errors.BadRequest,
                    null, response, 400, log);
            }
            log.end().addDefaultFields({
                contentLength: request.parsedContentLength,
            });

            api.callApiMethod('objectPut', request, log,
                (err, contentMD5, prevContentLen) => {
                    // ETag's hex should always be enclosed in quotes
                    statsReport500(err, statsClient);
                    const resMetaHeaders = {
                        ETag: `"${contentMD5}"`,
                    };
                    pushMetrics(err, log, utapi, 'objectPut',
                        request.bucketName, request.parsedContentLength,
                        prevContentLen);
                    return routesUtils.responseNoBody(err, resMetaHeaders,
                        response, 200, log);
                });
        }
    }
    return undefined;
}
/* eslint-enable no-param-reassign */
<|endoftext|>


<commit_before>/** @babel */

import { Range, Point } from 'atom'

import { client } from '../connection'
import modules from './modules'
import { scopes, words } from '../misc'

const datatip = client.import('datatip')
const { getEditorModule } = modules
const { isStringOrCommentScope } = scopes
const { isValidWord } = words

// @FIXME: This does not work with non-ascii characters
const wordRegex = /[^0-9A-Za-z_!\.´@]/
const grammar = atom.grammars.grammarForScopeName('source.julia');

/**
 * Returns `true` if the scope at `bufferPosition` in `editor` is valid code scope to be inspected
 */
function isValidScope (editor, bufferPosition) {
  const scopes = editor
    .scopeDescriptorForBufferPosition(bufferPosition)
    .getScopesArray();
  return !isStringOrCommentScope(scopes)
}

class DatatipProvider {
  providerName = "Julia-Client";

  priority = 100;

  grammarScopes = atom.config.get('julia-client.juliaSyntaxScopes');

  useAtomIDEUI = false;

  async datatip(editor, bufferPosition, mouseEvent) {
    // If Julia is not running, do nothing
    if (!client.isActive()) return

    // If the scope at `bufferPosition` is not valid code scope, do nothing
    if (!isValidScope(editor, bufferPosition)) return

    // Code to be inspected
    const { row, column } = bufferPosition
    const text = editor.lineTextForBufferRow(row)
    if (!text) return null
    let start = column
    const identifierStart = text.slice(0, column).split('').reverse().join('').search(wordRegex)
    if (identifierStart === -1) {
      start = 0
    } else {
      start -= identifierStart
    }
    let end = column
    const identifierEnd = text.slice(column).search(wordRegex)
    if (identifierEnd === -1) {
      end = text.length
    } else {
      end += identifierEnd
    }
    const word = text.slice(start, end)
    if (!isValidWord(word)) return

    const { main, sub } = await getEditorModule(editor, bufferPosition)
    const module = main ? (sub ? `${main}.${sub}` : main) : 'Main'

    return new Promise((resolve, reject) => {
      datatip({ word: word, mod: module }).then((result) => {
        if (result.error) {
          reject(null)
        } else if (result.novariable) {
          reject(null)
        } else {
          resolve({
            range: new Range(
              new Point(row, start),
              new Point(row, end)
            ),
            markedStrings: result.strings.map(string => {
              return {
                // @NOTE: Currently only the datatip service provided by Atom-IDE-UI can render code snippets correctly
                type: this.useAtomIDEUI ? string.type : 'markdown',
                value: string.value,
                grammar: string.type === 'snippet' ? grammar : null
              }
            }),
          });
        }
      })
    });
  }
}

export default new DatatipProvider();
<commit_msg>Change datatip `providerName`<commit_after>/** @babel */

import { Range, Point } from 'atom'

import { client } from '../connection'
import modules from './modules'
import { scopes, words } from '../misc'

const datatip = client.import('datatip')
const { getEditorModule } = modules
const { isStringOrCommentScope } = scopes
const { isValidWord } = words

// @FIXME: This does not work with non-ascii characters
const wordRegex = /[^0-9A-Za-z_!\.´@]/
const grammar = atom.grammars.grammarForScopeName('source.julia');

/**
 * Returns `true` if the scope at `bufferPosition` in `editor` is valid code scope to be inspected
 */
function isValidScope (editor, bufferPosition) {
  const scopes = editor
    .scopeDescriptorForBufferPosition(bufferPosition)
    .getScopesArray();
  return !isStringOrCommentScope(scopes)
}

class DatatipProvider {
  providerName = 'julia-client-datatip-provider';

  priority = 100;

  grammarScopes = atom.config.get('julia-client.juliaSyntaxScopes');

  useAtomIDEUI = false;

  async datatip(editor, bufferPosition, mouseEvent) {
    // If Julia is not running, do nothing
    if (!client.isActive()) return

    // If the scope at `bufferPosition` is not valid code scope, do nothing
    if (!isValidScope(editor, bufferPosition)) return

    // Code to be inspected
    const { row, column } = bufferPosition
    const text = editor.lineTextForBufferRow(row)
    if (!text) return null
    let start = column
    const identifierStart = text.slice(0, column).split('').reverse().join('').search(wordRegex)
    if (identifierStart === -1) {
      start = 0
    } else {
      start -= identifierStart
    }
    let end = column
    const identifierEnd = text.slice(column).search(wordRegex)
    if (identifierEnd === -1) {
      end = text.length
    } else {
      end += identifierEnd
    }
    const word = text.slice(start, end)
    if (!isValidWord(word)) return

    const { main, sub } = await getEditorModule(editor, bufferPosition)
    const module = main ? (sub ? `${main}.${sub}` : main) : 'Main'

    return new Promise((resolve, reject) => {
      datatip({ word: word, mod: module }).then((result) => {
        if (result.error) {
          reject(null)
        } else if (result.novariable) {
          reject(null)
        } else {
          resolve({
            range: new Range(
              new Point(row, start),
              new Point(row, end)
            ),
            markedStrings: result.strings.map(string => {
              return {
                // @NOTE: Currently only the datatip service provided by Atom-IDE-UI can render code snippets correctly
                type: this.useAtomIDEUI ? string.type : 'markdown',
                value: string.value,
                grammar: string.type === 'snippet' ? grammar : null
              }
            }),
          });
        }
      })
    });
  }
}

export default new DatatipProvider();
<|endoftext|>


<commit_before>/** @babel */

import { Range, Point } from 'atom'

import { client } from '../connection'
import modules from './modules'
import { scopes, words } from '../misc'

const datatip = client.import('datatip')
const { isValidWord } = words

// @FIXME: This does not work with non-ascii characters
const wordRegex = /[^0-9A-Za-z_!\.´@]/
const grammar = atom.grammars.grammarForScopeName('source.julia');

/**
 * Returns `true` if the scope at `bufferPosition` in `editor` is valid code scope to be inspected
 */
function isValidScope (editor, bufferPosition) {
  const scps = editor
    .scopeDescriptorForBufferPosition(bufferPosition)
    .getScopesArray();
  return scopes.isValidInspectionScope(scps)
}

class DatatipProvider {
  providerName = 'julia-client-datatip-provider';

  priority = 100;

  grammarScopes = atom.config.get('julia-client.juliaSyntaxScopes');

  useAtomIDEUI = false;

  async datatip(editor, bufferPosition, mouseEvent) {
    // If Julia is not running, do nothing
    if (!client.isActive()) return

    // If the scope at `bufferPosition` is not valid code scope, do nothing
    if (!isValidScope(editor, bufferPosition)) return

    // Code to be inspected
    const { row, column } = bufferPosition
    const text = editor.lineTextForBufferRow(row)
    if (!text) return null
    let start = column
    const identifierStart = text.slice(0, column).split('').reverse().join('').search(wordRegex)
    if (identifierStart === -1) {
      start = 0
    } else {
      start -= identifierStart
    }
    let end = column
    const identifierEnd = text.slice(column).search(wordRegex)
    if (identifierEnd === -1) {
      end = text.length
    } else {
      end += identifierEnd
    }
    const word = text.slice(start, end)
    if (!isValidWord(word)) return

    const { main, sub } = await modules.getEditorModule(editor, bufferPosition)
    const module = main ? (sub ? `${main}.${sub}` : main) : 'Main'

    return new Promise((resolve, reject) => {
      datatip({ word: word, mod: module }).then((result) => {
        if (result.error) {
          reject(null)
        } else if (result.novariable) {
          reject(null)
        } else {
          resolve({
            range: new Range(
              new Point(row, start),
              new Point(row, end)
            ),
            markedStrings: result.strings.map(string => {
              return {
                // @NOTE: Currently only the datatip service provided by Atom-IDE-UI can render code snippets correctly
                type: this.useAtomIDEUI ? string.type : 'markdown',
                value: string.value,
                grammar: string.type === 'snippet' ? grammar : null
              }
            }),
          });
        }
      })
    });
  }
}

export default new DatatipProvider();
<commit_msg>Make datatip regex work with non-ascii characters<commit_after>/** @babel */

import { Range, Point } from 'atom'

import { client } from '../connection'
import modules from './modules'
import { scopes, words } from '../misc'

const datatip = client.import('datatip')
const { isValidWord } = words

const wordRegex = /[^.\u00A0-\uFFFF\w_!´\.@]/
const grammar = atom.grammars.grammarForScopeName('source.julia')

/**
 * Returns `true` if the scope at `bufferPosition` in `editor` is valid code scope to be inspected
 */
function isValidScope (editor, bufferPosition) {
  const scps = editor
    .scopeDescriptorForBufferPosition(bufferPosition)
    .getScopesArray();
  return scopes.isValidInspectionScope(scps)
}

class DatatipProvider {
  providerName = 'julia-client-datatip-provider';

  priority = 100;

  grammarScopes = atom.config.get('julia-client.juliaSyntaxScopes');

  useAtomIDEUI = false;

  async datatip(editor, bufferPosition, mouseEvent) {
    // If Julia is not running, do nothing
    if (!client.isActive()) return

    // If the scope at `bufferPosition` is not valid code scope, do nothing
    if (!isValidScope(editor, bufferPosition)) return

    // Code to be inspected
    const { row, column } = bufferPosition
    const text = editor.lineTextForBufferRow(row)
    if (!text) return null
    let start = column
    const identifierStart = text.slice(0, column).split('').reverse().join('').search(wordRegex)
    if (!identifierStart || identifierStart === -1) {
      start = 0
    } else {
      start -= identifierStart
    }
    let end = column
    const identifierEnd = text.slice(column).search(wordRegex)
    if (!identifierEnd || identifierEnd === -1) {
      end = text.length
    } else {
      end += identifierEnd
    }
    const word = text.slice(start, end)
    if (!isValidWord(word)) return

    const { main, sub } = await modules.getEditorModule(editor, bufferPosition)
    const module = main ? (sub ? `${main}.${sub}` : main) : 'Main'

    return new Promise((resolve, reject) => {
      datatip({ word: word, mod: module }).then((result) => {
        if (result.error) {
          reject(null)
        } else if (result.novariable) {
          reject(null)
        } else {
          resolve({
            range: new Range(
              new Point(row, start),
              new Point(row, end)
            ),
            markedStrings: result.strings.map(string => {
              return {
                // @NOTE: Currently only the datatip service provided by Atom-IDE-UI can render code snippets correctly
                type: this.useAtomIDEUI ? string.type : 'markdown',
                value: string.value,
                grammar: string.type === 'snippet' ? grammar : null
              }
            }),
          });
        }
      })
    });
  }
}

export default new DatatipProvider();
<|endoftext|>


<commit_before>function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    // Save current buffer state.
    buffer.save();

    // Setup translate/rotation for wall drawing.
    buffer.translate(
      x,
      y
    );
    buffer.rotate(rotation * pi_divide_180);

    // Draw walls.
    var loop_counter = 3;
    do{
        buffer.beginPath();
        buffer.moveTo(
          0,
          0
        );
        buffer.lineTo(
          wall_splits[[0,0,2,4,][loop_counter]],
          wall_splits[[1,1,3,5,][loop_counter]]
        );
        buffer.lineTo(
          wall_splits[[2,4,6,6,][loop_counter]],
          wall_splits[[3,5,7,7,][loop_counter]]
        );
        buffer.closePath();
        buffer.fillStyle = colors[0][loop_counter];
        buffer.fill();
    }while(loop_counter--);

    buffer.beginPath();
    buffer.moveTo(
      -x,
      -x
    );
    buffer.lineTo(
      wall_splits[0],
      wall_splits[1]
    );
    buffer.lineTo(
      wall_splits[2],
      wall_splits[3]
    );
    buffer.lineTo(
      x,
      -x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][0];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      -x,
      -x
    );
    buffer.lineTo(
      wall_splits[0],
      wall_splits[1]
    );
    buffer.lineTo(
      wall_splits[4],
      wall_splits[5]
    );
    buffer.lineTo(
      -x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][1];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      x,
      -x
    );
    buffer.lineTo(
      wall_splits[2],
      wall_splits[3]
    );
    buffer.lineTo(
      wall_splits[6],
      wall_splits[7]
    );
    buffer.lineTo(
      x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][2];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      -x,
      x
    );
    buffer.lineTo(
      wall_splits[4],
      wall_splits[5]
    );
    buffer.lineTo(
      wall_splits[6],
      wall_splits[7]
    );
    buffer.lineTo(
      x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][3];
    buffer.fill();

    // Restore buffer state.
    buffer.restore();

    // Draw current speed.
    buffer.font = '23pt sans-serif';
    buffer.textAlign = 'left';
    buffer.textBaseline = 'top';
    buffer.fillStyle = '#fff';
    buffer.fillText(
      speed + ' m/s',
      5,
      5
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(key_left){
        rotation -= speed / 10 + 1;
    }
    if(key_right){
        rotation += speed / 10 + 1;
    }

    if(key_speedminus
      && speed > 0){
        speed -= 1;
    }
    if(key_speedplus){
        speed += 1;
    }

    var do_split = 0;

    // Move wall split location.
    var loop_counter = 3;
    do{
        wall_splits[loop_counter * 2] += wall_splits[loop_counter * 2] >= 0
          ? speed
          : -speed;
        wall_splits[loop_counter * 2 + 1] += wall_splits[loop_counter * 2 + 1] >= 0
          ? speed
          : -speed;

        // Check if wall split reached edge of screen.
        if(wall_splits[loop_counter * 2] < -x
          || wall_splits[loop_counter * 2] > x){
            // Reset wall splits.
            wall_splits[loop_counter * 2] = [
              -2,
              -2,
              2,
              -2,
              -2,
              2,
              2,
              2,
            ][loop_counter * 2];
            wall_splits[loop_counter * 2 + 1] = [
              -2,
              -2,
              2,
              -2,
              -2,
              2,
              2,
              2,
            ][loop_counter * 2 + 1];

            do_split = 1;
        }
    }while(loop_counter--);

    if(do_split){
        colors[1] = colors[0];
        colors[0] = [
          random_hex(),
          random_hex(),
          random_hex(),
          random_hex(),
        ];
    }
}

function random_hex(){
    var choices = '0123456789abcdef';
    return '#'
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16));
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('audio-volume').value = 1;
    document.getElementById('key-slowdown').value = 'S';
    document.getElementById('key-speedup').value = 'W';
    document.getElementById('movement-keys').value = 'AD';
    document.getElementById('ms-per-frame').value = 30;

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    if(document.getElementById('audio-volume').value == 1){
        window.localStorage.removeItem('Tubes-2D3D.htm-audio-volume');
        settings['audio-volume'] = 1;

    }else{
        settings['audio-volume'] = parseFloat(document.getElementById('audio-volume').value);
        window.localStorage.setItem(
          'Tubes-2D3D.htm-audio-volume',
          settings['audio-volume']
        );
    }

    if(document.getElementById('key-slowdown').value == 'S'){
        window.localStorage.removeItem('Tubes-2D3D.htm-key-slowdown');
        settings['key-slowdown'] = 'S';

    }else{
        settings['key-slowdown'] = document.getElementById('key-slowdown').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-key-slowdown',
          settings['key-slowdown']
        );
    }

    if(document.getElementById('key-speedup').value == 'W'){
        window.localStorage.removeItem('Tubes-2D3D.htm-key-speedup');
        settings['key-speedup'] = 'W';

    }else{
        settings['key-speedup'] = document.getElementById('key-speedup').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-key-speedup',
          settings['key-speedup']
        );
    }

    if(document.getElementById('movement-keys').value == 'AD'){
        window.localStorage.removeItem('Tubes-2D3D.htm-movement-keys');
        settings['movement-keys'] = 'AD';

    }else{
        settings['movement-keys'] = document.getElementById('movement-keys').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-movement-keys',
          settings['movement-keys']
        );
    }

    if(document.getElementById('ms-per-frame').value == 30
      || isNaN(document.getElementById('ms-per-frame').value)
      || document.getElementById('ms-per-frame').value < 1){
        window.localStorage.removeItem('Tubes-2D3D.htm-ms-per-frame');
        settings['ms-per-frame'] = 30;

    }else{
        settings['ms-per-frame'] = parseInt(document.getElementById('ms-per-frame').value);
        window.localStorage.setItem(
          'Tubes-2D3D.htm-ms-per-frame',
          settings['ms-per-frame']
        );
    }
}

function setmode(newmode){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    mode = newmode;

    // New game mode.
    if(mode > 0){
        save();

        key_left = false;
        key_right = false;
        key_speedminus = false;
        key_speedplus = false;
        speed = 10;
        rotation = 0;

        document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer style=display:none></canvas>';

        buffer = document.getElementById('buffer').getContext('2d');
        canvas = document.getElementById('canvas').getContext('2d');

        resize();

        wall_splits = [
          -2,
          -2,
          2,
          -2,
          -2,
          2,
          2,
          2,
        ];

        // Set initial tube colors.
        colors = [
          ['#f0f', '#06f', '#ff0', '#f60'],// Initial
          ['#0f0', '#f00', '#00f', '#0ff'],// First swap
        ];

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          'logic()',
          settings['ms-per-frame']
        );

    // Main menu mode.
    }else{
        buffer = 0;
        canvas = 0;

        document.getElementById('page').innerHTML = '

Enter the Tubes

<input disabled style=border:0 value=ESC>Main Menu
<input id=movement-keys maxlength=2 value='
          + settings['movement-keys'] + '>Move ←→
<input id=key-slowdown maxlength=1 value='
          + settings['key-slowdown'] + '>Speed--
<input id=key-speedup maxlength=1 value='
          + settings['key-speedup'] + '>Speed++

<input id=audio-volume max=1 min=0 step=.01 type=range value='
          + settings['audio-volume'] + '>Audio
<input id=ms-per-frame value='
          + settings['ms-per-frame'] + '>ms/Frame
Reset Settings

';
    }
}

var animationFrame = 0;
var buffer = 0;
var canvas = 0;
var colors = [];
var height = 0;
var interval = 0;
var key_left = false;
var key_right = false;
var key_speedminus = false;
var key_speedplus = false;
var mode = 0;
var mx = 0;
var my = 0;
var pi_divide_180 = Math.PI / 180;
var px = 0;
var py = 0;
var rotation = 0;
var settings = {
  'audio-volume': parseFloat(window.localStorage.getItem('Tubes-2D3D.htm-audio-volume')) || 1,
  'key-slowdown': window.localStorage.getItem('Tubes-2D3D.htm-key-slowdown') || 'S',
  'key-speedup': window.localStorage.getItem('Tubes-2D3D.htm-key-speedup') || 'W',
  'movement-keys': window.localStorage.getItem('Tubes-2D3D.htm-movement-keys') || 'AD',
  'ms-per-frame': parseInt(window.localStorage.getItem('Tubes-2D3D.htm-ms-per-frame')) || 30,
};
var speed = 0;
var wall_splits = [];
var width = 0;
var x = 0;
var y = 0;

setmode(0);

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        setmode(0);
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_left = true;

    }else if(key === settings['movement-keys'][1]){
        key_right = true;

    }else if(key === settings['key-slowdown']){
        key_speedminus = true;

    }else if(key === settings['key-speedup']){
        key_speedplus = true;
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_left = false;

    }else if(key === settings['movement-keys'][1]){
        key_right = false;

    }else if(key === settings['key-slowdown']){
        key_speedminus = false;

    }else if(key === settings['key-speedup']){
        key_speedplus = false;
    }
};

window.onresize = resize;
<commit_msg>moved initial setup to window.onload<commit_after>function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    // Save current buffer state.
    buffer.save();

    // Setup translate/rotation for wall drawing.
    buffer.translate(
      x,
      y
    );
    buffer.rotate(rotation * pi_divide_180);

    // Draw walls.
    var loop_counter = 3;
    do{
        buffer.beginPath();
        buffer.moveTo(
          0,
          0
        );
        buffer.lineTo(
          wall_splits[[0,0,2,4,][loop_counter]],
          wall_splits[[1,1,3,5,][loop_counter]]
        );
        buffer.lineTo(
          wall_splits[[2,4,6,6,][loop_counter]],
          wall_splits[[3,5,7,7,][loop_counter]]
        );
        buffer.closePath();
        buffer.fillStyle = colors[0][loop_counter];
        buffer.fill();
    }while(loop_counter--);

    buffer.beginPath();
    buffer.moveTo(
      -x,
      -x
    );
    buffer.lineTo(
      wall_splits[0],
      wall_splits[1]
    );
    buffer.lineTo(
      wall_splits[2],
      wall_splits[3]
    );
    buffer.lineTo(
      x,
      -x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][0];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      -x,
      -x
    );
    buffer.lineTo(
      wall_splits[0],
      wall_splits[1]
    );
    buffer.lineTo(
      wall_splits[4],
      wall_splits[5]
    );
    buffer.lineTo(
      -x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][1];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      x,
      -x
    );
    buffer.lineTo(
      wall_splits[2],
      wall_splits[3]
    );
    buffer.lineTo(
      wall_splits[6],
      wall_splits[7]
    );
    buffer.lineTo(
      x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][2];
    buffer.fill();

    buffer.beginPath();
    buffer.moveTo(
      -x,
      x
    );
    buffer.lineTo(
      wall_splits[4],
      wall_splits[5]
    );
    buffer.lineTo(
      wall_splits[6],
      wall_splits[7]
    );
    buffer.lineTo(
      x,
      x
    );
    buffer.closePath();
    buffer.fillStyle = colors[1][3];
    buffer.fill();

    // Restore buffer state.
    buffer.restore();

    // Draw current speed.
    buffer.font = '23pt sans-serif';
    buffer.textAlign = 'left';
    buffer.textBaseline = 'top';
    buffer.fillStyle = '#fff';
    buffer.fillText(
      speed + ' m/s',
      5,
      5
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(key_left){
        rotation -= speed / 10 + 1;
    }
    if(key_right){
        rotation += speed / 10 + 1;
    }

    if(key_speedminus
      && speed > 0){
        speed -= 1;
    }
    if(key_speedplus){
        speed += 1;
    }

    var do_split = 0;

    // Move wall split location.
    var loop_counter = 3;
    do{
        wall_splits[loop_counter * 2] += wall_splits[loop_counter * 2] >= 0
          ? speed
          : -speed;
        wall_splits[loop_counter * 2 + 1] += wall_splits[loop_counter * 2 + 1] >= 0
          ? speed
          : -speed;

        // Check if wall split reached edge of screen.
        if(wall_splits[loop_counter * 2] < -x
          || wall_splits[loop_counter * 2] > x){
            // Reset wall splits.
            wall_splits[loop_counter * 2] = [
              -2,
              -2,
              2,
              -2,
              -2,
              2,
              2,
              2,
            ][loop_counter * 2];
            wall_splits[loop_counter * 2 + 1] = [
              -2,
              -2,
              2,
              -2,
              -2,
              2,
              2,
              2,
            ][loop_counter * 2 + 1];

            do_split = 1;
        }
    }while(loop_counter--);

    if(do_split){
        colors[1] = colors[0];
        colors[0] = [
          random_hex(),
          random_hex(),
          random_hex(),
          random_hex(),
        ];
    }
}

function random_hex(){
    var choices = '0123456789abcdef';
    return '#'
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16));
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('audio-volume').value = 1;
    document.getElementById('key-slowdown').value = 'S';
    document.getElementById('key-speedup').value = 'W';
    document.getElementById('movement-keys').value = 'AD';
    document.getElementById('ms-per-frame').value = 30;

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    if(document.getElementById('audio-volume').value == 1){
        window.localStorage.removeItem('Tubes-2D3D.htm-audio-volume');
        settings['audio-volume'] = 1;

    }else{
        settings['audio-volume'] = parseFloat(document.getElementById('audio-volume').value);
        window.localStorage.setItem(
          'Tubes-2D3D.htm-audio-volume',
          settings['audio-volume']
        );
    }

    if(document.getElementById('key-slowdown').value == 'S'){
        window.localStorage.removeItem('Tubes-2D3D.htm-key-slowdown');
        settings['key-slowdown'] = 'S';

    }else{
        settings['key-slowdown'] = document.getElementById('key-slowdown').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-key-slowdown',
          settings['key-slowdown']
        );
    }

    if(document.getElementById('key-speedup').value == 'W'){
        window.localStorage.removeItem('Tubes-2D3D.htm-key-speedup');
        settings['key-speedup'] = 'W';

    }else{
        settings['key-speedup'] = document.getElementById('key-speedup').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-key-speedup',
          settings['key-speedup']
        );
    }

    if(document.getElementById('movement-keys').value == 'AD'){
        window.localStorage.removeItem('Tubes-2D3D.htm-movement-keys');
        settings['movement-keys'] = 'AD';

    }else{
        settings['movement-keys'] = document.getElementById('movement-keys').value;
        window.localStorage.setItem(
          'Tubes-2D3D.htm-movement-keys',
          settings['movement-keys']
        );
    }

    if(document.getElementById('ms-per-frame').value == 30
      || isNaN(document.getElementById('ms-per-frame').value)
      || document.getElementById('ms-per-frame').value < 1){
        window.localStorage.removeItem('Tubes-2D3D.htm-ms-per-frame');
        settings['ms-per-frame'] = 30;

    }else{
        settings['ms-per-frame'] = parseInt(document.getElementById('ms-per-frame').value);
        window.localStorage.setItem(
          'Tubes-2D3D.htm-ms-per-frame',
          settings['ms-per-frame']
        );
    }
}

function setmode(newmode){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    mode = newmode;

    // New game mode.
    if(mode > 0){
        save();

        key_left = false;
        key_right = false;
        key_speedminus = false;
        key_speedplus = false;
        speed = 10;
        rotation = 0;

        document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer style=display:none></canvas>';

        buffer = document.getElementById('buffer').getContext('2d');
        canvas = document.getElementById('canvas').getContext('2d');

        resize();

        wall_splits = [
          -2,
          -2,
          2,
          -2,
          -2,
          2,
          2,
          2,
        ];

        // Set initial tube colors.
        colors = [
          ['#f0f', '#06f', '#ff0', '#f60'],// Initial
          ['#0f0', '#f00', '#00f', '#0ff'],// First swap
        ];

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          'logic()',
          settings['ms-per-frame']
        );

    // Main menu mode.
    }else{
        buffer = 0;
        canvas = 0;

        document.getElementById('page').innerHTML = '

Enter the Tubes

<input disabled style=border:0 value=ESC>Main Menu
<input id=movement-keys maxlength=2 value='
          + settings['movement-keys'] + '>Move ←→
<input id=key-slowdown maxlength=1 value='
          + settings['key-slowdown'] + '>Speed--
<input id=key-speedup maxlength=1 value='
          + settings['key-speedup'] + '>Speed++

<input id=audio-volume max=1 min=0 step=.01 type=range value='
          + settings['audio-volume'] + '>Audio
<input id=ms-per-frame value='
          + settings['ms-per-frame'] + '>ms/Frame
Reset Settings

';
    }
}

var animationFrame = 0;
var buffer = 0;
var canvas = 0;
var colors = [];
var height = 0;
var interval = 0;
var key_left = false;
var key_right = false;
var key_speedminus = false;
var key_speedplus = false;
var mode = 0;
var mx = 0;
var my = 0;
var pi_divide_180 = Math.PI / 180;
var px = 0;
var py = 0;
var rotation = 0;
var settings = {
  'audio-volume': parseFloat(window.localStorage.getItem('Tubes-2D3D.htm-audio-volume')) || 1,
  'key-slowdown': window.localStorage.getItem('Tubes-2D3D.htm-key-slowdown') || 'S',
  'key-speedup': window.localStorage.getItem('Tubes-2D3D.htm-key-speedup') || 'W',
  'movement-keys': window.localStorage.getItem('Tubes-2D3D.htm-movement-keys') || 'AD',
  'ms-per-frame': parseInt(window.localStorage.getItem('Tubes-2D3D.htm-ms-per-frame')) || 30,
};
var speed = 0;
var wall_splits = [];
var width = 0;
var x = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        setmode(0);
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_left = true;

    }else if(key === settings['movement-keys'][1]){
        key_right = true;

    }else if(key === settings['key-slowdown']){
        key_speedminus = true;

    }else if(key === settings['key-speedup']){
        key_speedplus = true;
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_left = false;

    }else if(key === settings['movement-keys'][1]){
        key_right = false;

    }else if(key === settings['key-slowdown']){
        key_speedminus = false;

    }else if(key === settings['key-speedup']){
        key_speedplus = false;
    }
};

window.onload = function(e){
    setmode(0);
};

window.onresize = resize;
<|endoftext|>


<commit_before>
// Return the {x: {min: #, max: #}, y: {min: #, max: #}}
module.exports = {
  computeXySpans: function(points) {
    var spans = {
      x: { min: Infinity, max: -Infinity },
      y: { min: Infinity, max: -Infinity }
    };
    for (var i = 0; i < points.length; i++) {
      if (points[i].proj) {
        spans.x.min = Math.min(spans.x.min, points[i].proj.x);
        spans.x.max = Math.max(spans.x.max, points[i].proj.x);
        spans.y.min = Math.min(spans.y.min, points[i].proj.y);
        spans.y.max = Math.max(spans.y.max, points[i].proj.y);
      }
    }
    return spans;
  },
  supportsSVG: function() {
    return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect;
  },
  isIE8: function() {
    return navigator.userAgent.match(/MSIE [89]/);
  },
  isIphone: function() {
    return navigator.userAgent.match(/iPhone/);
  },
  supportsVis: function() {
    return this.supportsSVG() && !this.isIE8();
  }
};
<commit_msg>basic detection of android/ios/mobile - NOT PERFECT!<commit_after>
// Return the {x: {min: #, max: #}, y: {min: #, max: #}}
module.exports = {
  computeXySpans: function(points) {
    var spans = {
      x: { min: Infinity, max: -Infinity },
      y: { min: Infinity, max: -Infinity }
    };
    for (var i = 0; i < points.length; i++) {
      if (points[i].proj) {
        spans.x.min = Math.min(spans.x.min, points[i].proj.x);
        spans.x.max = Math.max(spans.x.max, points[i].proj.x);
        spans.y.min = Math.min(spans.y.min, points[i].proj.y);
        spans.y.max = Math.max(spans.y.max, points[i].proj.y);
      }
    }
    return spans;
  },
  supportsSVG: function() {
    return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect;
  },
  isIE8: function() {
    return navigator.userAgent.match(/MSIE [89]/);
  },
  isIphone: function() {
    return navigator.userAgent.match(/iPhone/);
  },
  isIpad: function() {
    return navigator.userAgent.match(/iPad/);
  },
  isAndroid: function() {
    return navigator.userAgent.match(/Android/);
  },
  isMobile: function() {
    return this.isIphone() || this.isIpad() || this.isAndroid();
  },
  supportsVis: function() {
    return this.supportsSVG() && !this.isIE8();
  }
};
<|endoftext|>


<commit_before>"use strict";

function verif_form_sortie() {
  if (parseInt(document.getElementById('najout').value) >= 1) {
    document.getElementById("formulaire").submit();
  }
}

function submanut(x) {
  var number = document.getElementById("number");

  if ((number.value - x) > 0 ) {
    number.value = (number.value - x).toFixed(2);
  }
}

function number_write(x) {
  var text_box = document.getElementById("number");
  text_box.value = text_box.value + x;
}

function number_clear() {
  const input = document.getElementById("number");
  input.value = "";
  input.setCustomValidity("");
}

/*
 * nom: HTML
 * id: HTML <input>
 * masse_max: float
 * masse_bac: float
 */

function masse_write(nom, id, masse_max, masse_bac) {
  const input = document.getElementById("number");
  const number_value = parseFloat(input.value);
  const masse_reele = number_value - masse_bac;

  if (masse_reele > 0.00) {
    if (number_value <= masse_max) {
      const masseTotale = document.getElementById("massetot");
      masseTotale.textContent = (parseFloat(masseTotale.textContent) + masse_reele).toFixed(2);

      id.value = (parseFloat(id.value) + masse_reele).toFixed(2);
      nom.textContent = (parseFloat(nom.textContent) + masse_reele).toFixed(2);
      input.value = "";

      const nAjout = document.getElementById("najout");
      nAjout.value = parseInt(nAjout.value) + 1;

      number_clear();
    } else {
      input.setCustomValidity("Masse supérieure aux limites de pesée de la balance.");
    }
  } else {
      input.setCustomValidity("Masse entrée inférieure au poids du conteneur ou inférieure ou égale à 0.");
  }
}

function masse_write_recycle(nom, id, masse_max, masse_bac) {
    const ref = document.getElementById("sel_filiere");
  const tabref = ref.value.split('|');

  const id_filiere = document.getElementById("id_filiere");
  id_filiere.value = tabref[0];

  const type_dechet = document.getElementById("type_dechet");
  type_dechet.value = tabref[1];

  ref.disabled = true;
  const input = document.getElementById("number");
  const number_value = parseFloat(input.value);
  const masse_reele = number_value - masse_bac;

  if (masse_reele > 0.00) {
    if (number_value <= masse_max) {
      const masseTotale = document.getElementById("massetot");
      masseTotale.textContent = (parseFloat(masseTotale.textContent) + masse_reele).toFixed(2);

      id.value = (parseFloat(id.value) + masse_reele).toFixed(2);
      nom.textContent = (parseFloat(nom.textContent) + masse_reele).toFixed(2);
      input.value = "";

      const nAjout = document.getElementById("najout");
      nAjout.value = parseInt(nAjout.value) + 1;

      number_clear();
    } else {
      input.setCustomValidity("Masse supérieure aux limites de pesée de la balance.");
    }
  } else {
      input.setCustomValidity("Masse entrée inférieure au poids du conteneur ou inférieure ou égale à 0.");
  }
}

function recocom() {
  document.getElementById("commentaire").value =
    document.getElementById("commentaireini").value;
}

function tdechet_add(pesee_max) {
  const ref = document.getElementById("sel_filiere");
  const tabref = ref.value.split('|');

  const id_filiere = document.getElementById("id_filiere");
  id_filiere.value = tabref[0];

  const id_type_dechet = document.getElementById("id_type_dechet");
  id_type_dechet.value = tabref[1];

  const type_dechet = document.getElementById("type_dechet");
  type_dechet.value = tabref[2];

  ref.disabled = true;
  masse_write(document.getElementById(tabref[1]), document.getElementById("m"+tabref[1]), pesee_max, 0.0);
}
function aff_dechets_recycle() {
  const ref2 = document.getElementById("sel_filiere");
  const tabref2 = ref2.value.split('|');
  ref2.disabled = true;

}
<commit_msg>transformation de l'interface de collecte de maniere à encaisser plusieurstypes_dechets_evac sur le meme bon de sortie recycleur et pour un meme recycleur...<commit_after>"use strict";

function verif_form_sortie() {
  if (parseInt(document.getElementById('najout').value) >= 1) {
    document.getElementById("formulaire").submit();
  }
}

function submanut(x) {
  var number = document.getElementById("number");

  if ((number.value - x) > 0 ) {
    number.value = (number.value - x).toFixed(2);
  }
}

function number_write(x) {
  var text_box = document.getElementById("number");
  text_box.value = text_box.value + x;
}

function number_clear() {
  const input = document.getElementById("number");
  input.value = "";
  input.setCustomValidity("");
}

/*
 * nom: HTML
 * id: HTML <input>
 * masse_max: float
 * masse_bac: float
 */

function masse_write(nom, id, masse_max, masse_bac) {
  const input = document.getElementById("number");
  const number_value = parseFloat(input.value);
  const masse_reele = number_value - masse_bac;

  if (masse_reele > 0.00) {
    if (number_value <= masse_max) {
      const masseTotale = document.getElementById("massetot");
      masseTotale.textContent = (parseFloat(masseTotale.textContent) + masse_reele).toFixed(2);

      id.value = (parseFloat(id.value) + masse_reele).toFixed(2);
      nom.textContent = (parseFloat(nom.textContent) + masse_reele).toFixed(2);
      input.value = "";

      const nAjout = document.getElementById("najout");
      nAjout.value = parseInt(nAjout.value) + 1;

      number_clear();
    } else {
      input.setCustomValidity("Masse supérieure aux limites de pesée de la balance.");
    }
  } else {
      input.setCustomValidity("Masse entrée inférieure au poids du conteneur ou inférieure ou égale à 0.");
  }
}

function aff_dechets_recycle() {
  const ref2 = document.getElementById("sel_filiere");
  const tabref2 = ref2.value.split('|');
  ref2.disabled = true;
    const id_filiere = document.getElementById("id_filiere");
  id_filiere.value = tabref2[0];

  const type_dechet = document.getElementById("type_dechet");
  type_dechet.value = tabref2[1];

  const tabtyps = tabref2.value.split('a');
  for (index = 0, len = tabtyps.length; index < len; ++index) {
    console.log(tabtyps[index]);
}

}

function masse_write_recycle(nom, id, masse_max, masse_bac) {
    const ref = document.getElementById("sel_filiere");
  const tabref = ref.value.split('|');

  const id_filiere = document.getElementById("id_filiere");
  id_filiere.value = tabref[0];

  const type_dechet = document.getElementById("type_dechet");
  type_dechet.value = tabref[1];

  ref.disabled = true;
  const input = document.getElementById("number");
  const number_value = parseFloat(input.value);
  const masse_reele = number_value - masse_bac;

  if (masse_reele > 0.00) {
    if (number_value <= masse_max) {
      const masseTotale = document.getElementById("massetot");
      masseTotale.textContent = (parseFloat(masseTotale.textContent) + masse_reele).toFixed(2);

      id.value = (parseFloat(id.value) + masse_reele).toFixed(2);
      nom.textContent = (parseFloat(nom.textContent) + masse_reele).toFixed(2);
      input.value = "";

      const nAjout = document.getElementById("najout");
      nAjout.value = parseInt(nAjout.value) + 1;

      number_clear();
    } else {
      input.setCustomValidity("Masse supérieure aux limites de pesée de la balance.");
    }
  } else {
      input.setCustomValidity("Masse entrée inférieure au poids du conteneur ou inférieure ou égale à 0.");
  }
}

function recocom() {
  document.getElementById("commentaire").value =
    document.getElementById("commentaireini").value;
}

function tdechet_add(pesee_max) {
  const ref = document.getElementById("sel_filiere");
  const tabref = ref.value.split('|');

  const id_filiere = document.getElementById("id_filiere");
  id_filiere.value = tabref[0];

  const id_type_dechet = document.getElementById("id_type_dechet");
  id_type_dechet.value = tabref[1];

  const type_dechet = document.getElementById("type_dechet");
  type_dechet.value = tabref[2];

  ref.disabled = true;
  masse_write(document.getElementById(tabref[1]), document.getElementById("m"+tabref[1]), pesee_max, 0.0);
}
<|endoftext|>


<commit_before>var ws = require('ws');
var WSServer = ws.Server;
var SCSocket = require('./scsocket');
var AuthEngine = require('./auth').AuthEngine;
var EventEmitter = require('events').EventEmitter;
var base64id = require('base64id');
var async = require('async');
var url = require('url');
var domain = require('domain');

var SCServer = function (options) {
  var self = this;

  var opts = {
    ackTimeout: 10000,
    allowClientPublish: true,
    path: '/socketcluster/'
  };

  var i;
  for (i in options) {
    opts[i] = options[i];
  }

  this.MIDDLEWARE_HANDSHAKE = 'handshake';
  this.MIDDLEWARE_EMIT = 'emit';
  this.MIDDLEWARE_SUBSCRIBE = 'subscribe';
  this.MIDDLEWARE_PUBLISH = 'publish';

  this.ERROR_NO_PUBLISH = 'Error: Client publish feature is disabled';

  this._middleware = {};
  this._middleware[this.MIDDLEWARE_HANDSHAKE] = [];
  this._middleware[this.MIDDLEWARE_EMIT] = [];
  this._middleware[this.MIDDLEWARE_SUBSCRIBE] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH] = [];

  this.origins = opts.origins;
  this._allowAllOrigins = this.origins.indexOf('*:*') != -1;

  this.ackTimeout = opts.ackTimeout;
  this.pingInterval = opts.pingInterval;
  this.pingTimeout = opts.pingTimeout;
  this.allowClientPublish = opts.allowClientPublish;
  this.perMessageDeflate = opts.perMessageDeflate;
  this.httpServer = opts.httpServer;

  this._ioClusterClient = opts.ioClusterClient;
  this.appName = opts.appName || '';
  this._path = opts.path;

  if (opts.authCookieName == null) {
    this._authCookieName = 'n/' + this.appName + '/auth';
  } else {
    this._authCookieName = opts.authCookieName;
  }

  this.auth = new AuthEngine({
    cookieName: this._authCookieName,
    defaultExpiryInMinutes: opts.defaultAuthTokenExpiryInMinutes,
    key: opts.authKey
  });

  this.clients = {};
  this.clientsCount = 0;

  this.global = this._ioClusterClient.global();

  this.wsServer = new WSServer({
    server: this.httpServer,
    clientTracking: false,
    perMessageDeflate: this.perMessageDeflate,
    handleProtocols: opts.handleProtocols,
    verifyClient: this.verifyHandshake.bind(this)
  });

  this.wsServer.on('error', this._handleServerError.bind(this));
  this.wsServer.on('connection', this._handleSocketConnection.bind(this));
};

SCServer.prototype = Object.create(EventEmitter.prototype);

SCServer.errorStatuses = {
  0: 'Failed handshake'
};

SCServer.prototype.sendErrorMessage = function (res, code) {
  res.writeHead(400, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({
    code: code,
    message: SCServer.errorStatuses[code]
  }));
};

SCServer.prototype._handleServerError = function (error) {
  this.emit('error', error);
};

SCServer.prototype._handleSocketError = function (error) {
  // We don't want to crash the entire worker on socket error
  // so we emit it as a notice instead.
  var errorPrefix = 'Socket Error: ';
  if (error.message) {
    error.message = errorPrefix + error.message;
  } else if (typeof error == 'string') {
    error = errorPrefix + error;
  }
  this.emit('notice', error);
};

SCServer.prototype.setAuthTokenVerifyOptionsFactory = function (factoryFn) {
  this.auth.setTokenVerifyOptionsFactory(factoryFn);
};

SCServer.prototype.getAuthTokenVerifyOptionsFactory = function () {
  return this.auth.getTokenVerifyOptionsFactory();
};

SCServer.prototype._handleSocketConnection = function (wsSocket) {
  var self = this;

  this.auth.parseToken(wsSocket.upgradeReq, function (err, authToken) {
    var id = self.generateId();

    // In case of an expired, malformed or invalid token, emit an event
    // and keep going without a token.
    if (err) {
      self.emit('badAuthToken', err);
    }

    var authData = {
      token: authToken
    };

    if (err) {
      authData.error = {
        name: err.name,
        message: err.message
      };
    }

    var socketDomain = domain.createDomain();
    var scSocket = new SCSocket(id, self, wsSocket, authData);

    self.clients[id] = scSocket;
    self.clientsCount++;

    socketDomain.on('error', function (err) {
      self._handleSocketError(err);
      scSocket.disconnect();
    });
    socketDomain.add(scSocket);

    self._ioClusterClient.bind(scSocket, function (err, sock, isNotice) {
      if (err) {
        var errorMessage = 'Failed to bind socket to io cluster - ' + err;
        scSocket.emit('fail', errorMessage);
        scSocket.disconnect();
        if (isNotice) {
          self.emit('notice', errorMessage);
        } else {
          self.emit('error', new Error(errorMessage));
        }
      } else {
        scSocket.global = self.global;
        self.emit('connection', scSocket);
      }
    });

    scSocket.once('_disconnect', function () {
      delete self.clients[id];
      self.clientsCount--;
      self._ioClusterClient.unbind(scSocket, function (err) {
        if (err) {
          self.emit('error', new Error('Failed to unbind socket from io cluster - ' + err));
        } else {
          self.emit('disconnection', scSocket);
        }
      });
    });
  });
};

SCServer.prototype.close = function () {
  this.wsServer.close();
};

SCServer.prototype.getPath = function () {
  return this._path;
};

SCServer.prototype.generateId = function () {
  return base64id.generateId();
};

SCServer.prototype.on = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.once(event, listener);
  } else {
    EventEmitter.prototype.on.apply(this, arguments);
  }
};

SCServer.prototype.removeListener = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.removeListener(event, listener);
  } else {
    EventEmitter.prototype.removeListener.apply(this, arguments);
  }
};

SCServer.prototype.addMiddleware = function (type, middleware) {
  this._middleware[type].push(middleware);
};

SCServer.prototype.verifyHandshake = function (info, cb) {
  var self = this;

  var req = info.req;
  var origin = info.origin;
  if (origin == 'null' || origin == null) {
    origin = '*';
  }

  if (this._allowAllOrigins) {
    cb(true);
  } else {
    var ok;
    try {
      var parts = url.parse(origin);
      parts.port = parts.port || 80;
      ok = ~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
        ~this.origins.indexOf(parts.hostname + ':*') ||
        ~this.origins.indexOf('*:' + parts.port);
    } catch (ex) {}

    if (ok) {
      var handshakeMiddleware = this._middleware[this.MIDDLEWARE_HANDSHAKE];
      if (handshakeMiddleware.length) {
        async.applyEachSeries(handshakeMiddleware, req, function (err) {
          if (err) {
            self.emit('notice', err);
            cb(false, 401, err);
          } else {
            cb(true);
          }
        });
      } else {
        cb(true);
      }
    } else {
      var err = 'Failed to authorize socket handshake - Invalid origin: ' + origin;
      this.emit('notice', err);
      cb(false, 403, err);
    }
  }
};

SCServer.prototype.verifyEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.MIDDLEWARE_SUBSCRIBE) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_SUBSCRIBE], socket, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  } else if (event == this.MIDDLEWARE_PUBLISH) {
    if (this.allowClientPublish) {
      async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH], socket, data.channel, data.data,
        function (err) {
          if (err) {
            self.emit('notice', err);
            cb(err);
          } else {
            self.global.publish(data.channel, data.data, function (err) {
              cb(err);
            });
          }
        }
      );
    } else {
      cb(this.ERROR_NO_PUBLISH);
    }
  } else {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_EMIT], socket, event, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  }
};

module.exports = SCServer;
<commit_msg>Fixed issue which caused MIDDLEWARE_HANDSHAKE to be bypassed<commit_after>var ws = require('ws');
var WSServer = ws.Server;
var SCSocket = require('./scsocket');
var AuthEngine = require('./auth').AuthEngine;
var EventEmitter = require('events').EventEmitter;
var base64id = require('base64id');
var async = require('async');
var url = require('url');
var domain = require('domain');

var SCServer = function (options) {
  var self = this;

  var opts = {
    ackTimeout: 10000,
    allowClientPublish: true,
    path: '/socketcluster/'
  };

  var i;
  for (i in options) {
    opts[i] = options[i];
  }

  this.MIDDLEWARE_HANDSHAKE = 'handshake';
  this.MIDDLEWARE_EMIT = 'emit';
  this.MIDDLEWARE_SUBSCRIBE = 'subscribe';
  this.MIDDLEWARE_PUBLISH = 'publish';

  this.ERROR_NO_PUBLISH = 'Error: Client publish feature is disabled';

  this._middleware = {};
  this._middleware[this.MIDDLEWARE_HANDSHAKE] = [];
  this._middleware[this.MIDDLEWARE_EMIT] = [];
  this._middleware[this.MIDDLEWARE_SUBSCRIBE] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH] = [];

  this.origins = opts.origins;
  this._allowAllOrigins = this.origins.indexOf('*:*') != -1;

  this.ackTimeout = opts.ackTimeout;
  this.pingInterval = opts.pingInterval;
  this.pingTimeout = opts.pingTimeout;
  this.allowClientPublish = opts.allowClientPublish;
  this.perMessageDeflate = opts.perMessageDeflate;
  this.httpServer = opts.httpServer;

  this._ioClusterClient = opts.ioClusterClient;
  this.appName = opts.appName || '';
  this._path = opts.path;

  if (opts.authCookieName == null) {
    this._authCookieName = 'n/' + this.appName + '/auth';
  } else {
    this._authCookieName = opts.authCookieName;
  }

  this.auth = new AuthEngine({
    cookieName: this._authCookieName,
    defaultExpiryInMinutes: opts.defaultAuthTokenExpiryInMinutes,
    key: opts.authKey
  });

  this.clients = {};
  this.clientsCount = 0;

  this.global = this._ioClusterClient.global();

  this.wsServer = new WSServer({
    server: this.httpServer,
    clientTracking: false,
    perMessageDeflate: this.perMessageDeflate,
    handleProtocols: opts.handleProtocols,
    verifyClient: this.verifyHandshake.bind(this)
  });

  this.wsServer.on('error', this._handleServerError.bind(this));
  this.wsServer.on('connection', this._handleSocketConnection.bind(this));
};

SCServer.prototype = Object.create(EventEmitter.prototype);

SCServer.errorStatuses = {
  0: 'Failed handshake'
};

SCServer.prototype.sendErrorMessage = function (res, code) {
  res.writeHead(400, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({
    code: code,
    message: SCServer.errorStatuses[code]
  }));
};

SCServer.prototype._handleServerError = function (error) {
  this.emit('error', error);
};

SCServer.prototype._handleSocketError = function (error) {
  // We don't want to crash the entire worker on socket error
  // so we emit it as a notice instead.
  var errorPrefix = 'Socket Error: ';
  if (error.message) {
    error.message = errorPrefix + error.message;
  } else if (typeof error == 'string') {
    error = errorPrefix + error;
  }
  this.emit('notice', error);
};

SCServer.prototype.setAuthTokenVerifyOptionsFactory = function (factoryFn) {
  this.auth.setTokenVerifyOptionsFactory(factoryFn);
};

SCServer.prototype.getAuthTokenVerifyOptionsFactory = function () {
  return this.auth.getTokenVerifyOptionsFactory();
};

SCServer.prototype._handleSocketConnection = function (wsSocket) {
  var self = this;

  this.auth.parseToken(wsSocket.upgradeReq, function (err, authToken) {
    var id = self.generateId();

    // In case of an expired, malformed or invalid token, emit an event
    // and keep going without a token.
    if (err) {
      self.emit('badAuthToken', err);
    }

    var authData = {
      token: authToken
    };

    if (err) {
      authData.error = {
        name: err.name,
        message: err.message
      };
    }

    var socketDomain = domain.createDomain();
    var scSocket = new SCSocket(id, self, wsSocket, authData);

    self.clients[id] = scSocket;
    self.clientsCount++;

    socketDomain.on('error', function (err) {
      self._handleSocketError(err);
      scSocket.disconnect();
    });
    socketDomain.add(scSocket);

    self._ioClusterClient.bind(scSocket, function (err, sock, isNotice) {
      if (err) {
        var errorMessage = 'Failed to bind socket to io cluster - ' + err;
        scSocket.emit('fail', errorMessage);
        scSocket.disconnect();
        if (isNotice) {
          self.emit('notice', errorMessage);
        } else {
          self.emit('error', new Error(errorMessage));
        }
      } else {
        scSocket.global = self.global;
        self.emit('connection', scSocket);
      }
    });

    scSocket.once('_disconnect', function () {
      delete self.clients[id];
      self.clientsCount--;
      self._ioClusterClient.unbind(scSocket, function (err) {
        if (err) {
          self.emit('error', new Error('Failed to unbind socket from io cluster - ' + err));
        } else {
          self.emit('disconnection', scSocket);
        }
      });
    });
  });
};

SCServer.prototype.close = function () {
  this.wsServer.close();
};

SCServer.prototype.getPath = function () {
  return this._path;
};

SCServer.prototype.generateId = function () {
  return base64id.generateId();
};

SCServer.prototype.on = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.once(event, listener);
  } else {
    EventEmitter.prototype.on.apply(this, arguments);
  }
};

SCServer.prototype.removeListener = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.removeListener(event, listener);
  } else {
    EventEmitter.prototype.removeListener.apply(this, arguments);
  }
};

SCServer.prototype.addMiddleware = function (type, middleware) {
  this._middleware[type].push(middleware);
};

SCServer.prototype.verifyHandshake = function (info, cb) {
  var self = this;

  var req = info.req;
  var origin = info.origin;
  if (origin == 'null' || origin == null) {
    origin = '*';
  }
  var ok = false;

  if (this._allowAllOrigins) {
    ok = true;
  } else {
    try {
      var parts = url.parse(origin);
      parts.port = parts.port || 80;
      ok = ~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
        ~this.origins.indexOf(parts.hostname + ':*') ||
        ~this.origins.indexOf('*:' + parts.port);
    } catch (e) {}
  }

  if (ok) {
    var handshakeMiddleware = this._middleware[this.MIDDLEWARE_HANDSHAKE];
    if (handshakeMiddleware.length) {
      async.applyEachSeries(handshakeMiddleware, req, function (err) {
        if (err) {
          self.emit('notice', err);
          cb(false, 401, err);
        } else {
          cb(true);
        }
      });
    } else {
      cb(true);
    }
  } else {
    var err = 'Failed to authorize socket handshake - Invalid origin: ' + origin;
    this.emit('notice', err);
    cb(false, 403, err);
  }
};

SCServer.prototype.verifyEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.MIDDLEWARE_SUBSCRIBE) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_SUBSCRIBE], socket, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  } else if (event == this.MIDDLEWARE_PUBLISH) {
    if (this.allowClientPublish) {
      async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH], socket, data.channel, data.data,
        function (err) {
          if (err) {
            self.emit('notice', err);
            cb(err);
          } else {
            self.global.publish(data.channel, data.data, function (err) {
              cb(err);
            });
          }
        }
      );
    } else {
      cb(this.ERROR_NO_PUBLISH);
    }
  } else {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_EMIT], socket, event, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  }
};

module.exports = SCServer;
<|endoftext|>


<commit_before>// if page on local machine, add warning
var localwarning = '

QML File cannot be loaded from your Local Machine! Upload the Demo on a Web server to see it working correctly!

';
switch(window.location.protocol) {
   case 'http:': break;
   case 'https:': break;
   case 'file:':
     document.body.innerHTML += localwarning;
     break;
   default:
     document.body.innerHTML += localwarning;
}
// end if page on local machine, add warning

// only implement if no native isArray implementation is available (for backward compatibility with old browsers)
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.toString.call(obj) === '[object Array]';
  }
};
// end backward compatibility isArray

function addPlayer(targetdiv,qmlsource,playerid) {
	qmlsource = (typeof qmlsource === "undefined") ? "http://jaruba.github.io/WebchimeraGUI/qml/default.qml" : qmlsource; // if no qmlsource set, default to latest Webchimera Player Default QML
	playerid = (typeof playerid === "undefined") ? "webchimera" : playerid; // if no playerid set, default to "webchimera"

	var playerbody = "";
	playerbody += '<object id="' + playerid + '" type="application/x-chimera-plugin" width="100%" height="100%">';
	playerbody += '<param name="qmlsrc" value="' + qmlsource + '" />';
	playerbody += '</object>';
	document.getElementById(targetdiv).innerHTML = playerbody;
//	container.appendChild(embed);

}

// function to add playlist items
function addPlaylist(playlist, playerid) {
	 playerid = (typeof playerid === "undefined") ? "webchimera" : playerid; // if no playerid set, default to "webchimera"
     var videoelem = document.getElementById(playerid);
	 if (typeof playlist === 'string') {
		 videoelem.playlist.add(playlist); // if Playlist has one Element
	 } else {
		 if (Array.isArray(playlist) === true && Array.isArray(playlist[0]) === true) {
			 // if Playlist has Custom Titles
			 for (item = 0; item < playlist.length; item++) {
				  videoelem.playlist.items[item].mrl = playlist[item][0];
				  if (typeof playlist[item][1] !== 'undefined' && typeof playlist[item][1] === 'string') videoelem.playlist.items[item].title = playlist[item][1];
			 }
			 // end if Playlist has Custom Titles
		 } else if (Array.isArray(playlist) === true) {
			 for (item = 0; typeof playlist[item] !== 'undefined'; item++) videoelem.playlist.items[item].mrl = playlist[item]; // if Playlist is Array
		 }
	 }
}
// end function to add playlist items

// function to Start Playback
function startPlayer(playerid) {
	playerid = (typeof playerid === "undefined") ? "webchimera" : playerid;  // if no playerid set, default to "webchimera"
    var videoelem = document.getElementById(playerid);
    videoelem.playlist.setCurrentItem(0); // Set Current Item to first
    videoelem.playlist.play(); // Play Current Item
    videoelem.playlist.Normal; // Set Normal Playback (options: Normal, Loop, Single)
}
// end function to Start Playback<commit_msg>Revert to Previous Add to Playlist<commit_after>// if page on local machine, add warning
var localwarning = '

QML File cannot be loaded from your Local Machine! Upload the Demo on a Web server to see it working correctly!

';
switch(window.location.protocol) {
   case 'http:': break;
   case 'https:': break;
   case 'file:':
     document.body.innerHTML += localwarning;
     break;
   default:
     document.body.innerHTML += localwarning;
}
// end if page on local machine, add warning

// only implement if no native isArray implementation is available (for backward compatibility with old browsers)
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.toString.call(obj) === '[object Array]';
  }
};
// end backward compatibility isArray

function addPlayer(targetdiv,qmlsource,playerid) {
	qmlsource = (typeof qmlsource === "undefined") ? "http://jaruba.github.io/WebchimeraGUI/qml/default.qml" : qmlsource; // if no qmlsource set, default to latest Webchimera Player Default QML
	playerid = (typeof playerid === "undefined") ? "webchimera" : playerid; // if no playerid set, default to "webchimera"

	var playerbody = "";
	playerbody += '<object id="' + playerid + '" type="application/x-chimera-plugin" width="100%" height="100%">';
	playerbody += '<param name="qmlsrc" value="' + qmlsource + '" />';
	playerbody += '</object>';
	document.getElementById(targetdiv).innerHTML = playerbody;
//	container.appendChild(embed);

}

// function to add playlist items
function addPlaylist(playlist, playerid) {
	 playerid = (typeof playerid === "undefined") ? "webchimera" : playerid; // if no playerid set, default to "webchimera"
     var videoelem = document.getElementById(playerid);
	 if (typeof playlist === 'string') {
		 videoelem.playlist.add(playlist); // if Playlist has one Element
	 } else {
		 if (Array.isArray(playlist) === true && Array.isArray(playlist[0]) === true) {
			 // if Playlist has Custom Titles
			 for (item = 0; item < playlist.length; item++) {
				  videoelem.playlist.add(playlist[item][0]);
				  if (typeof playlist[item][1] !== 'undefined' && typeof playlist[item][1] === 'string') videoelem.playlist.items[item].title = playlist[item][1];
			 }
			 // end if Playlist has Custom Titles
		 } else if (Array.isArray(playlist) === true) {
			 for (item = 0; typeof playlist[item] !== 'undefined'; item++) videoelem.playlist.add(playlist[item]); // if Playlist is Array
		 }
	 }
}
// end function to add playlist items

// function to Start Playback
function startPlayer(playerid) {
	playerid = (typeof playerid === "undefined") ? "webchimera" : playerid;  // if no playerid set, default to "webchimera"
    var videoelem = document.getElementById(playerid);
    videoelem.playlist.setCurrentItem(0); // Set Current Item to first
    videoelem.playlist.play(); // Play Current Item
    videoelem.playlist.Normal; // Set Normal Playback (options: Normal, Loop, Single)
}
// end function to Start Playback<|endoftext|>