<commit_before>import {Button} from 'widget/button'
import {Form} from 'widget/form/form'
import {Input} from 'widget/input'
import {ScrollableList} from 'widget/list'
import {Subject} from 'rxjs'
import {compose} from 'compose'
import {connect} from 'store'
import {delay} from 'rxjs/operators'
import {isMobile} from 'widget/userAgent'
import {selectFrom} from 'stateUtils'
import AutoFocus from 'widget/autoFocus'
import FloatingBox from 'widget/floatingBox'
import Keybinding from 'widget/keybinding'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import escapeStringRegexp from 'escape-string-regexp'
import styles from './combo.module.css'
import withSubscriptions from 'subscription'

const SELECTION_DELAY_MS = 350

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class _Combo extends React.Component {
    inputContainer = React.createRef()
    input = React.createRef()
    list = React.createRef()
    select$ = new Subject()
    state = {
        showOptions: false,
        filter: '',
        filteredOptions: [],
        flattenedOptions: [],
        selectedOption: null,
        selected: false,
        focused: false
    }

    constructor() {
        super()
        this.onBlur = this.onBlur.bind(this)
        this.handleBlur = this.handleBlur.bind(this)
    }

    isActive() {
        const {busyMessage, disabled} = this.props
        return !(disabled || busyMessage)
    }

    render() {
        const {errorMessage, busyMessage, standalone, disabled, className, label, labelButtons, tooltip, tooltipPlacement, onCancel} = this.props
        const {showOptions} = this.state
        const onClick = e => {
            if (this.isActive()) {
                return standalone
                    ? onCancel && onCancel(e)
                    : showOptions
                        ? this.hideOptions()
                        : this.showOptions()
            }
        }
        return (
            <Form.FieldSet
                className={[styles.container, className].join(' ')}
                label={label}
                labelButtons={labelButtons}
                tooltip={tooltip}
                tooltipPlacement={tooltipPlacement}
                disabled={disabled}
                errorMessage={errorMessage}
                busyMessage={busyMessage}>
                <div
                    ref={this.inputContainer}
                    onClick={onClick}>
                    {this.renderInput()}
                </div>
                {showOptions ? this.renderOptions() : null}
            </Form.FieldSet>
        )
    }

    renderInput() {
        const {placeholder, autoFocus, standalone, readOnly, inputClassName, additionalButtons = []} = this.props
        const {focused, filter, selectedOption, showOptions} = this.state
        const showOptionsKeyBinding = showOptions ? undefined : () => this.showOptions()
        const keymap = {
            ArrowUp: showOptionsKeyBinding,
            ArrowDown: showOptionsKeyBinding,
            ArrowLeft: showOptionsKeyBinding,
            ArrowRight: showOptionsKeyBinding,
            Home: showOptionsKeyBinding,
            End: showOptionsKeyBinding
        }
        return (
            <Keybinding
                disabled={!this.isActive() || !focused}
                keymap={keymap}>
                <AutoFocus element={this.input.current} enabled={autoFocus}>
                    <Input
                        ref={this.input}
                        className={[
                            styles.input,
                            standalone ? styles.standalone : null,
                            selectedOption && !showOptions ? styles.fakePlaceholder : null,
                            inputClassName
                        ].join(' ')}
                        value={filter}
                        placeholder={selectedOption && !standalone ? selectedOption.label : placeholder}
                        disabled={!this.isActive()}
                        readOnly={readOnly || isMobile()}
                        buttons={[
                            this.renderClearButton(),
                            this.renderToggleOptionsButton()
                        ]}
                        additionalButtons={additionalButtons}
                        onChange={e => this.setFilter(e.target.value)}
                        onFocus={() => this.setState({focused: true})}
                        onBlur={this.onBlur}
                    />
                </AutoFocus>
            </Keybinding>
        )
    }

    onBlur(e) {
        const {onBlur} = this.props
        const {showOptions} = this.state
        if (showOptions) {
            this.input.current.focus()
        } else {
            onBlur && onBlur(e)
            this.setState({focused: false})
        }
    }

    renderClearButton() {
        const {allowClear} = this.props
        const {selectedOption} = this.state
        return allowClear && selectedOption
            ? (
                <Button
                    key='clear'
                    chromeless
                    shape='none'
                    air='none'
                    icon='times'
                    iconFixedWidth
                    tabIndex={-1}
                    onClick={() => this.select$.next()}
                />
            )
            : null
    }

    renderToggleOptionsButton() {
        const {placement} = this.props
        const {showOptions} = this.state
        const icon = {
            below: 'chevron-down',
            above: 'chevron-up'
        }
        return (
            <Button
                key='toggle'
                chromeless
                shape='none'
                air='none'
                icon={icon[placement]}
                iconFlipVertical={showOptions}
                iconFixedWidth
                tabIndex={-1}
                disabled={!this.isActive()}
                onClick={() => showOptions
                    ? this.hideOptions()
                    : this.showOptions()
                }
            />
        )
    }

    renderOptions() {
        const {placement, optionsClassName, optionTooltipPlacement, alignment} = this.props
        const {flattenedOptions, selectedOption, selected} = this.state
        return (
            <FloatingBox
                element={this.inputContainer.current}
                placement={placement}
                alignment='fit'
                onBlur={this.handleBlur}>
                <ScrollableList
                    ref={this.list}
                    air='more'
                    className={optionsClassName || styles.options}
                    options={flattenedOptions}
                    selectedOption={selectedOption}
                    onSelect={option => this.select$.next(option)}
                    onCancel={() => this.resetFilter()}
                    autoCenter={!selected}
                    tooltipPlacement={optionTooltipPlacement}
                    autoHighlight
                    keyboard
                    alignment={alignment}
                />
            </FloatingBox>
        )
    }

    showOptions() {
        this.setState({showOptions: true})
    }

    hideOptions() {
        this.setState({showOptions: false})
    }

    setFilter(filter = '') {
        const {standalone} = this.props
        this.setState({
            showOptions: !!filter || standalone,
            filter
        }, this.updateOptions)
    }

    resetFilter() {
        const {onCancel, standalone} = this.props
        const {filter} = this.state
        if (standalone && onCancel && !filter) {
            onCancel()
        } else {
            this.setFilter()
        }
    }

    setSelectedOption(selectedOption) {
        this.updateState({
            selectedOption,
            selected: !!selectedOption
        })
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    handleSelect() {
        const {onChange, addSubscription} = this.props
        addSubscription(
            this.select$.subscribe(
                option => {
                    this.setSelectedOption(option)
                    onChange && onChange(option)
                }
            ),
            this.select$.pipe(
                delay(SELECTION_DELAY_MS)
            ).subscribe(
                () => this.setState({selected: false}, this.setFilter)
            )
        )
    }

    handleBlur(e) {
        const {onCancel} = this.props
        const isInputClick = e => this.inputContainer.current && this.inputContainer.current.contains(e.target)
        const isListClick = e => this.list.current && this.list.current.contains && this.list.current.contains(e.target)
        if (!isInputClick(e) && !isListClick(e)) {
            this.setFilter()
            onCancel && onCancel(e)
        }
    }

    componentDidMount() {
        this.setFilter()
        this.handleSelect()
    }

    shouldComponentUpdate() {
        return !this.state.selected
    }

    componentDidUpdate() {
        this.updateOptions()
    }

    matcher(filter) {
        // match beginning of multiple words in any order (e.g. both "u k" and "k u" match "United Kingdom")
        const parts = filter
            .trim()
            .split(/\s+/)
            // .map(part => part ? `(?=.*\\b${escapeStringRegexp(part)})` : '')
            .map(part => part ? `(?=.*${escapeStringRegexp(part)})` : '')
            .join('')
        return RegExp(`^${parts}.*$`, 'i')
    }

    updateOptions() {
        const {options} = this.props
        const {filter} = this.state
        const matcher = this.matcher(filter)
        const filterGroup = group => {
            const filtered = {...group, options: getFilteredOptions(group.options)}
            return filtered.options.length ? filtered : null
        }
        const getFilteredOptions = options =>
            _.compact(
                options.map(option =>
                    option.options
                        ? filterGroup(option)
                        : matcher.test(option.searchableText || option.label)
                            ? option
                            : null
                )
            )
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? [{label: option.label, group: true}, ...option.options]
                        : option
                )
            )
        const filteredOptions = getFilteredOptions(options)
        const flattenedOptions = getFlattenedOptions(filteredOptions)

        const getInputOption = () => {
            const {value} = this.props
            return flattenedOptions && flattenedOptions.find(option => !option.group && option.value === value)
        }

        const getSelectedOption = selectedOption => {
            const validatedSelectedOption = selectedOption && flattenedOptions.find(option => option.value === selectedOption.value)
            return validatedSelectedOption || getInputOption()
        }

        this.updateState(prevState =>
            ({
                filteredOptions,
                flattenedOptions,
                selectedOption: getSelectedOption.bind(this)(prevState.selectedOption)
            }))
    }
}

export const Combo = compose(
    _Combo,
    withSubscriptions(),
    connect(mapStateToProps)
)

Combo.propTypes = {
    options: PropTypes.any.isRequired,
    additionalButtons: PropTypes.arrayOf(PropTypes.node),
    alignment: PropTypes.oneOf(['left', 'center', 'right', 'fit']),
    allowClear: PropTypes.any,
    autoFocus: PropTypes.any,
    busyMessage: PropTypes.any,
    className: PropTypes.string,
    disabled: PropTypes.any,
    errorMessage: PropTypes.any,
    inputClassName: PropTypes.string,
    keyboard: PropTypes.any,
    label: PropTypes.any,
    labelButtons: PropTypes.any,
    optionsClassName: PropTypes.string,
    optionTooltipPlacement: PropTypes.string,
    placeholder: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    readOnly: PropTypes.any,
    standalone: PropTypes.any,
    tooltip: PropTypes.string,
    tooltipPlacement: PropTypes.string,
    value: PropTypes.any,
    onBlur: PropTypes.func,
    onCancel: PropTypes.func,
    onChange: PropTypes.func
}

Combo.defaultProps = {
    alignment: 'left',
    placement: 'below',
    tooltipPlacement: 'top'
}
<commit_msg>Update selection when combo input changes.<commit_after>import {Button} from 'widget/button'
import {Form} from 'widget/form/form'
import {Input} from 'widget/input'
import {ScrollableList} from 'widget/list'
import {Subject} from 'rxjs'
import {compose} from 'compose'
import {connect} from 'store'
import {delay} from 'rxjs/operators'
import {isMobile} from 'widget/userAgent'
import {selectFrom} from 'stateUtils'
import AutoFocus from 'widget/autoFocus'
import FloatingBox from 'widget/floatingBox'
import Keybinding from 'widget/keybinding'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import escapeStringRegexp from 'escape-string-regexp'
import styles from './combo.module.css'
import withSubscriptions from 'subscription'

const SELECTION_DELAY_MS = 350

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class _Combo extends React.Component {
    inputContainer = React.createRef()
    input = React.createRef()
    list = React.createRef()
    select$ = new Subject()
    state = {
        showOptions: false,
        filter: '',
        filteredOptions: [],
        flattenedOptions: [],
        selectedOption: null,
        selected: false,
        focused: false
    }

    constructor() {
        super()
        this.onBlur = this.onBlur.bind(this)
        this.handleBlur = this.handleBlur.bind(this)
    }

    isActive() {
        const {busyMessage, disabled} = this.props
        return !(disabled || busyMessage)
    }

    render() {
        const {errorMessage, busyMessage, standalone, disabled, className, label, labelButtons, tooltip, tooltipPlacement, onCancel} = this.props
        const {showOptions} = this.state
        const onClick = e => {
            if (this.isActive()) {
                return standalone
                    ? onCancel && onCancel(e)
                    : showOptions
                        ? this.hideOptions()
                        : this.showOptions()
            }
        }
        return (
            <Form.FieldSet
                className={[styles.container, className].join(' ')}
                label={label}
                labelButtons={labelButtons}
                tooltip={tooltip}
                tooltipPlacement={tooltipPlacement}
                disabled={disabled}
                errorMessage={errorMessage}
                busyMessage={busyMessage}>
                <div
                    ref={this.inputContainer}
                    onClick={onClick}>
                    {this.renderInput()}
                </div>
                {showOptions ? this.renderOptions() : null}
            </Form.FieldSet>
        )
    }

    renderInput() {
        const {placeholder, autoFocus, standalone, readOnly, inputClassName, additionalButtons = []} = this.props
        const {focused, filter, selectedOption, showOptions} = this.state
        const showOptionsKeyBinding = showOptions ? undefined : () => this.showOptions()
        const keymap = {
            ArrowUp: showOptionsKeyBinding,
            ArrowDown: showOptionsKeyBinding,
            ArrowLeft: showOptionsKeyBinding,
            ArrowRight: showOptionsKeyBinding,
            Home: showOptionsKeyBinding,
            End: showOptionsKeyBinding
        }
        return (
            <Keybinding
                disabled={!this.isActive() || !focused}
                keymap={keymap}>
                <AutoFocus element={this.input.current} enabled={autoFocus}>
                    <Input
                        ref={this.input}
                        className={[
                            styles.input,
                            standalone ? styles.standalone : null,
                            selectedOption && !showOptions ? styles.fakePlaceholder : null,
                            inputClassName
                        ].join(' ')}
                        value={filter}
                        placeholder={selectedOption && !standalone ? selectedOption.label : placeholder}
                        disabled={!this.isActive()}
                        readOnly={readOnly || isMobile()}
                        buttons={[
                            this.renderClearButton(),
                            this.renderToggleOptionsButton()
                        ]}
                        additionalButtons={additionalButtons}
                        onChange={e => this.setFilter(e.target.value)}
                        onFocus={() => this.setState({focused: true})}
                        onBlur={this.onBlur}
                    />
                </AutoFocus>
            </Keybinding>
        )
    }

    onBlur(e) {
        const {onBlur} = this.props
        const {showOptions} = this.state
        if (showOptions) {
            this.input.current.focus()
        } else {
            onBlur && onBlur(e)
            this.setState({focused: false})
        }
    }

    renderClearButton() {
        const {allowClear} = this.props
        const {selectedOption} = this.state
        return allowClear && selectedOption
            ? (
                <Button
                    key='clear'
                    chromeless
                    shape='none'
                    air='none'
                    icon='times'
                    iconFixedWidth
                    tabIndex={-1}
                    onClick={() => this.select$.next()}
                />
            )
            : null
    }

    renderToggleOptionsButton() {
        const {placement} = this.props
        const {showOptions} = this.state
        const icon = {
            below: 'chevron-down',
            above: 'chevron-up'
        }
        return (
            <Button
                key='toggle'
                chromeless
                shape='none'
                air='none'
                icon={icon[placement]}
                iconFlipVertical={showOptions}
                iconFixedWidth
                tabIndex={-1}
                disabled={!this.isActive()}
                onClick={() => showOptions
                    ? this.hideOptions()
                    : this.showOptions()
                }
            />
        )
    }

    renderOptions() {
        const {placement, optionsClassName, optionTooltipPlacement, alignment} = this.props
        const {flattenedOptions, selectedOption, selected} = this.state
        return (
            <FloatingBox
                element={this.inputContainer.current}
                placement={placement}
                alignment='fit'
                onBlur={this.handleBlur}>
                <ScrollableList
                    ref={this.list}
                    air='more'
                    className={optionsClassName || styles.options}
                    options={flattenedOptions}
                    selectedOption={selectedOption}
                    onSelect={option => this.select$.next(option)}
                    onCancel={() => this.resetFilter()}
                    autoCenter={!selected}
                    tooltipPlacement={optionTooltipPlacement}
                    autoHighlight
                    keyboard
                    alignment={alignment}
                />
            </FloatingBox>
        )
    }

    showOptions() {
        this.setState({showOptions: true})
    }

    hideOptions() {
        this.setState({showOptions: false})
    }

    setFilter(filter = '') {
        const {standalone} = this.props
        this.setState({
            showOptions: !!filter || standalone,
            filter
        }, this.updateOptions)
    }

    resetFilter() {
        const {onCancel, standalone} = this.props
        const {filter} = this.state
        if (standalone && onCancel && !filter) {
            onCancel()
        } else {
            this.setFilter()
        }
    }

    setSelectedOption(selectedOption) {
        this.updateState({
            selectedOption,
            selected: !!selectedOption
        })
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    handleSelect() {
        const {onChange, addSubscription} = this.props
        addSubscription(
            this.select$.subscribe(
                option => {
                    this.setSelectedOption(option)
                    onChange && onChange(option)
                }
            ),
            this.select$.pipe(
                delay(SELECTION_DELAY_MS)
            ).subscribe(
                () => this.setState({selected: false}, this.setFilter)
            )
        )
    }

    handleBlur(e) {
        const {onCancel} = this.props
        const isInputClick = e => this.inputContainer.current && this.inputContainer.current.contains(e.target)
        const isListClick = e => this.list.current && this.list.current.contains && this.list.current.contains(e.target)
        if (!isInputClick(e) && !isListClick(e)) {
            this.setFilter()
            onCancel && onCancel(e)
        }
    }

    componentDidMount() {
        this.setFilter()
        this.handleSelect()
    }

    shouldComponentUpdate() {
        return !this.state.selected
    }

    componentDidUpdate(prevProps) {
        const {value} = this.props
        const {value: prevValue} = prevProps
        this.updateOptions(value !== prevValue && value)
    }

    matcher(filter) {
        // match beginning of multiple words in any order (e.g. both "u k" and "k u" match "United Kingdom")
        const parts = filter
            .trim()
            .split(/\s+/)
            // .map(part => part ? `(?=.*\\b${escapeStringRegexp(part)})` : '')
            .map(part => part ? `(?=.*${escapeStringRegexp(part)})` : '')
            .join('')
        return RegExp(`^${parts}.*$`, 'i')
    }

    updateOptions(inputChanged) {
        const {options} = this.props
        const {filter} = this.state
        const matcher = this.matcher(filter)
        const filterGroup = group => {
            const filtered = {...group, options: getFilteredOptions(group.options)}
            return filtered.options.length ? filtered : null
        }
        const getFilteredOptions = options =>
            _.compact(
                options.map(option =>
                    option.options
                        ? filterGroup(option)
                        : matcher.test(option.searchableText || option.label)
                            ? option
                            : null
                )
            )
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? [{label: option.label, group: true}, ...option.options]
                        : option
                )
            )
        const filteredOptions = getFilteredOptions(options)
        const flattenedOptions = getFlattenedOptions(filteredOptions)

        const getInputOption = () => {
            const {value} = this.props
            return flattenedOptions && flattenedOptions.find(option => !option.group && option.value === value)
        }

        const getSelectedOption = selectedOption => {
            const validatedSelectedOption = selectedOption && flattenedOptions.find(option => option.value === selectedOption.value)
            return inputChanged
                ? getInputOption()
                : validatedSelectedOption || getInputOption()
        }

        this.updateState(prevState =>
            ({
                filteredOptions,
                flattenedOptions,
                selectedOption: getSelectedOption.bind(this)(prevState.selectedOption)
            }))
    }
}

export const Combo = compose(
    _Combo,
    withSubscriptions(),
    connect(mapStateToProps)
)

Combo.propTypes = {
    options: PropTypes.any.isRequired,
    additionalButtons: PropTypes.arrayOf(PropTypes.node),
    alignment: PropTypes.oneOf(['left', 'center', 'right', 'fit']),
    allowClear: PropTypes.any,
    autoFocus: PropTypes.any,
    busyMessage: PropTypes.any,
    className: PropTypes.string,
    disabled: PropTypes.any,
    errorMessage: PropTypes.any,
    inputClassName: PropTypes.string,
    keyboard: PropTypes.any,
    label: PropTypes.any,
    labelButtons: PropTypes.any,
    optionsClassName: PropTypes.string,
    optionTooltipPlacement: PropTypes.string,
    placeholder: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    readOnly: PropTypes.any,
    standalone: PropTypes.any,
    tooltip: PropTypes.string,
    tooltipPlacement: PropTypes.string,
    value: PropTypes.any,
    onBlur: PropTypes.func,
    onCancel: PropTypes.func,
    onChange: PropTypes.func
}

Combo.defaultProps = {
    alignment: 'left',
    placement: 'below',
    tooltipPlacement: 'top'
}
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const { existsSync } = require('../../utils/file_utils');
const fs = require('fs');

/*
 * This module defines the job execution context on the worker nodes.
 */

module.exports = function module(context) {
    let opPath = '';
    const config = context.sysconfig.teraslice;
    if (config.ops_directory) opPath = config.ops_directory;

    const types = ['readers', 'processors'];

    /*
     * This will request a connection based on the 'connection' attribute of
     * an opConfig. Intended as a context API endpoint.
     */
    function getClient(opConfig, type) {
        const clientConfig = {};
        const events = context.apis.foundation.getSystemEvents();
        clientConfig.type = type;

        if (opConfig && Object.prototype.hasOwnProperty.call(opConfig, 'connection')) {
            clientConfig.endpoint = opConfig.connection ? opConfig.connection : 'default';
            clientConfig.cached =
                opConfig.connection_cache !== undefined ? opConfig.connection_cache : true;
        } else {
            clientConfig.endpoint = 'default';
            clientConfig.cached = true;
        }

        try {
            return context.apis.foundation.getConnection(clientConfig).client;
        } catch (err) {
            const errMsg = `No configuration for endpoint ${clientConfig.endpoint} was found in the terafoundation connectors config, error: ${err.stack}`;
            context.logger.error(errMsg);
            events.emit('client:initialization:error', { error: errMsg });
            return false;
        }
    }

    context.apis.registerAPI('op_runner', {
        getClient
    });

    function findOp(name, assetsPath, executionAssets) {
        let filePath;
        let codeName;

        if (!name.match(/.js/)) {
            codeName = `${name}.js`;
        }

        function findCode(rootDir) {
            fs.readdirSync(rootDir).forEach((filename) => {
                const nextPath = path.join(rootDir, filename);

                // if name is same as filename/dir then we found it
                if (filename === name || filename === codeName) {
                    filePath = nextPath;
                }

                if (!filePath && filename !== 'node_modules' && fs.statSync(nextPath).isDirectory()) {
                    findCode(nextPath);
                }
            });
        }
        // we want to check assets first for code
        if (assetsPath && existsSync(assetsPath)) {
            executionAssets.forEach((assetID) => {
                const assetOpPath = `${assetsPath}/${assetID}`;
                // if the path is not found yet and the opPath exists
                if (!filePath && existsSync(assetOpPath)) {
                    findCode(assetOpPath);
                }
            });
        }

        // if found, don't do extra searches
        if (filePath) return filePath;

        types.forEach((type) => {
            const pathType = path.resolve(`${__dirname}/../../${type}`);
            if (!filePath) findCode(pathType);
        });

        // if found, don't do extra searches
        if (filePath) return filePath;

        if (opPath && existsSync(opPath)) {
            types.forEach((type) => {
                const pathType = path.resolve(`${opPath}/${type}`);
                if (!filePath && existsSync(pathType)) {
                    findCode(pathType);
                }
            });
        }

        return filePath;
    }

    function load(opName, assetPath, executionAssets) {
        isString(opName);

        const codePath = findOp(opName, assetPath, executionAssets);
        try {
            return require(codePath);
        } catch (error) {
            try {
                return require(opName);
            } catch (err) {
                // if it cant be required check first error to see if it exists
                // or had an error loading
                if (error.message !== 'missing path') {
                    throw new Error(`Error loading module: ${opName}, the following error occurred while attempting to load the code: ${error.message}`);
                }

                if (err.code && err.code === 'MODULE_NOT_FOUND') {
                    throw new Error(`Could not retrieve code for: ${opName} , error message: ${err}`);
                }

                throw new Error(`Error loading module: ${opName} , error: ${err.stack}`);
            }
        }
    }

    function isString(str) {
        const type = typeof str;
        if (type !== 'string') {
            throw new Error('Error: please verify that ops_directory in config and _op for each job operations are strings');
        }
    }

    return {
        findOp,
        load
    };
};
<commit_msg>disable double registrying op_runner<commit_after>'use strict';

const path = require('path');
const { existsSync } = require('../../utils/file_utils');
const fs = require('fs');

/*
 * This module defines the job execution context on the worker nodes.
 */

module.exports = function module(context) {
    let opPath = '';
    const config = context.sysconfig.teraslice;
    if (config.ops_directory) opPath = config.ops_directory;

    const types = ['readers', 'processors'];

    /*
     * This will request a connection based on the 'connection' attribute of
     * an opConfig. Intended as a context API endpoint.
     */
    function getClient(opConfig, type) {
        const clientConfig = {};
        const events = context.apis.foundation.getSystemEvents();
        clientConfig.type = type;

        if (opConfig && Object.prototype.hasOwnProperty.call(opConfig, 'connection')) {
            clientConfig.endpoint = opConfig.connection ? opConfig.connection : 'default';
            clientConfig.cached =
                opConfig.connection_cache !== undefined ? opConfig.connection_cache : true;
        } else {
            clientConfig.endpoint = 'default';
            clientConfig.cached = true;
        }

        try {
            return context.apis.foundation.getConnection(clientConfig).client;
        } catch (err) {
            const errMsg = `No configuration for endpoint ${clientConfig.endpoint} was found in the terafoundation connectors config, error: ${err.stack}`;
            context.logger.error(errMsg);
            events.emit('client:initialization:error', { error: errMsg });
            return false;
        }
    }

    if (context.apis.op_runner && context.apis.op_runner.getClient) {
        context.apis.registerAPI('op_runner', {
            getClient
        });
    }

    function findOp(name, assetsPath, executionAssets) {
        let filePath;
        let codeName;

        if (!name.match(/.js/)) {
            codeName = `${name}.js`;
        }

        function findCode(rootDir) {
            fs.readdirSync(rootDir).forEach((filename) => {
                const nextPath = path.join(rootDir, filename);

                // if name is same as filename/dir then we found it
                if (filename === name || filename === codeName) {
                    filePath = nextPath;
                }

                if (!filePath && filename !== 'node_modules' && fs.statSync(nextPath).isDirectory()) {
                    findCode(nextPath);
                }
            });
        }
        // we want to check assets first for code
        if (assetsPath && existsSync(assetsPath)) {
            executionAssets.forEach((assetID) => {
                const assetOpPath = `${assetsPath}/${assetID}`;
                // if the path is not found yet and the opPath exists
                if (!filePath && existsSync(assetOpPath)) {
                    findCode(assetOpPath);
                }
            });
        }

        // if found, don't do extra searches
        if (filePath) return filePath;

        types.forEach((type) => {
            const pathType = path.resolve(`${__dirname}/../../${type}`);
            if (!filePath) findCode(pathType);
        });

        // if found, don't do extra searches
        if (filePath) return filePath;

        if (opPath && existsSync(opPath)) {
            types.forEach((type) => {
                const pathType = path.resolve(`${opPath}/${type}`);
                if (!filePath && existsSync(pathType)) {
                    findCode(pathType);
                }
            });
        }

        return filePath;
    }

    function load(opName, assetPath, executionAssets) {
        isString(opName);

        const codePath = findOp(opName, assetPath, executionAssets);
        try {
            return require(codePath);
        } catch (error) {
            try {
                return require(opName);
            } catch (err) {
                // if it cant be required check first error to see if it exists
                // or had an error loading
                if (error.message !== 'missing path') {
                    throw new Error(`Error loading module: ${opName}, the following error occurred while attempting to load the code: ${error.message}`);
                }

                if (err.code && err.code === 'MODULE_NOT_FOUND') {
                    throw new Error(`Could not retrieve code for: ${opName} , error message: ${err}`);
                }

                throw new Error(`Error loading module: ${opName} , error: ${err.stack}`);
            }
        }
    }

    function isString(str) {
        const type = typeof str;
        if (type !== 'string') {
            throw new Error('Error: please verify that ops_directory in config and _op for each job operations are strings');
        }
    }

    return {
        findOp,
        load
    };
};
<|endoftext|>


<commit_before>/*

The MIT License (MIT)

Copyright (c) 2015 Micheal Parks

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

(function(window, sf) {

  if (typeof module !== 'undefined') module.exports = sf()
  else window.Starfield = sf()

})(this, function() {

'use strict'

/*
 * config:
 * {
 *   canvas: string or HTML element
 *   numStars: number, default 500
 *   vx: number, rate of x movement, default 0.05
 *   vy: number, rate of y movement, default 0.05
 *   maxRadius: number, default 2
 * }
 */
function Starfield(config) {
  this.canvas = typeof config.canvas === 'string' ?
    document.querySelector(config.canvas) :
    config.canvas
  this.ctx = this.canvas.getContext('2d')
  this.style = getComputedStyle(this.canvas)

  this.vx = config.vx || 0.05
  this.vy = config.vy || 0.05

  this.maxStars = config.numStars || 500
  this.maxRadius = config.maxRadius

  this.onResize()

  window.addEventListener('resize', this.onResize.bind(this))
}

Starfield.prototype.loadStars = function() {
  this.stars = []

  for (var i = 0, l = this.numStars; i < l; i++) this.stars.push({
    x: Math.round(Math.random() * this.canvas.width),
    y: Math.round(Math.random() * this.canvas.height),
    r: 0.5 + (Math.random() * (this.maxRadius || 500)),
    l: Math.random(),
    bl: 0.1 * (Math.random()*6 + 2),
    dl: Math.round(Math.random()) === 1? 0.01: -0.01
  })
}

Starfield.prototype.onResize = function() {
  this.canvas.width = Number(this.style.width.replace('px', '')) * window.devicePixelRatio
  this.canvas.height = Number(this.style.height.replace('px', '')) * window.devicePixelRatio

  if (this.canvas.width / window.devicePixelRatio < 500) this.numStars = 100
  else this.numStars = this.maxStars

  this.loadStars();
}

Starfield.prototype.start = function() {
  var tick = function() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
    this.ctx.fillStyle = 'black'
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)

    var i = this.stars.length
    while (i-- > 0) {
      var star = this.stars[i]
      this.ctx.beginPath()
      this.ctx.fillStyle = 'rgba(255,255,255,' + star.l + ')'
      this.ctx.arc(star.x, star.y, star.r, 0, 2 * Math.PI, false)
      this.ctx.fill()

      star.y += this.vy
      star.x += this.vx
      star.l += star.dl

      if (Math.abs(star.l - star.bl) >= 0.25) star.dl = -star.dl
      if (star.x > this.canvas.width) star.x = this.vx > 0? -1: this.canvas.width + 1
      if (star.y > this.canvas.height) star.y = this.vy > 0? -1: this.canvas.height + 1
    }

    this.frameId = window.requestAnimationFrame(tick)

  }.bind(this)

  this.frameId = window.requestAnimationFrame(tick)
}

return Starfield

})<commit_msg>added shooting stars<commit_after>/*

The MIT License (MIT)

Copyright (c) 2015 Micheal Parks

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

(function(window, sf) {

  if (typeof module !== 'undefined') module.exports = sf()
  else window.Starfield = sf()

})(this, function() {

'use strict'

/*
 * config:
 * {
 *   canvas: string or HTML element
 *   numStars: number, default 500
 *   vx: number, rate of x movement, default 0.05
 *   vy: number, rate of y movement, default 0.05
 *   maxRadius: number, default 2
 * }
 */
function Starfield(config) {
  this.canvas = typeof config.canvas === 'string' ?
    document.querySelector(config.canvas) :
    config.canvas
  this.ctx = this.canvas.getContext('2d')
  this.style = getComputedStyle(this.canvas)

  this.vx = config.vx || 0.05
  this.vy = config.vy || 0.05

  this.maxStars = config.numStars || 500
  this.maxRadius = config.maxRadius

  this.shootingStarInterval = config.shootingStarInterval || undefined
  this.lastShootingStar = this.shootingStarInterval ? Date.now() : undefined
  this.shootingStar = undefined;

  this.onResize()

  window.addEventListener('resize', this.onResize.bind(this))
}

Starfield.prototype.star = function() {
  return {
    x: Math.round(Math.random() * this.canvas.width),
    y: Math.round(Math.random() * this.canvas.height),
    r: 0.5 + (Math.random() * (this.maxRadius || 500)),
    l: Math.random(),
    bl: 0.1 * (Math.random()*6 + 2),
    dl: Math.round(Math.random()) === 1? 0.01: -0.01
  }
}

Starfield.prototype.loadStars = function() {
  this.stars = []

  for (var i = 0, l = this.numStars; i < l; i++)
    this.stars.push(this.star())
}

Starfield.prototype.onResize = function() {
  this.canvas.width = Number(this.style.width.replace('px', '')) * window.devicePixelRatio
  this.canvas.height = Number(this.style.height.replace('px', '')) * window.devicePixelRatio

  if (this.canvas.width / window.devicePixelRatio < 500) this.numStars = 100
  else this.numStars = this.maxStars

  this.loadStars();
}

Starfield.prototype.draw = function(star) {
  this.ctx.beginPath()
  this.ctx.fillStyle = 'rgba(255,255,255,' + star.l + ')'
  this.ctx.arc(star.x, star.y, star.r, 0, 2 * Math.PI, false)
  this.ctx.fill()
}

Starfield.prototype.start = function() {
  var tick = function() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
    this.ctx.fillStyle = 'black'
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)

    var i = this.stars.length
    while (i-- > 0) {
      var star = this.stars[i]

      this.draw(star)

      star.y += this.vy
      star.x += this.vx
      star.l += star.dl

      if (Math.abs(star.l - star.bl) >= 0.25) star.dl = -star.dl
      if (star.x > this.canvas.width) star.x = this.vx > 0? -1: this.canvas.width + 1
      if (star.y > this.canvas.height) star.y = this.vy > 0? -1: this.canvas.height + 1
    }

    if (this.shootingStar) {
      var star = this.shootingStar;

      this.draw(star)

      star.y += 15
      star.x += 15
      star.l += star.dl
      star.r -= .1

      if (star.r <= 0) this.shootingStar = undefined
    } else if (this.shootingStarInterval) {
      var i = this.shootingStarInterval
      var t = Date.now()

      if (t - this.lastShootingStar >= i) {
        this.shootingStar = this.star()
        this.lastShootingStar = Date.now()

        this.shootingStar.r = 3
      }
    }

    this.frameId = window.requestAnimationFrame(tick)

  }.bind(this)

  this.frameId = window.requestAnimationFrame(tick)
}

return Starfield

})<|endoftext|>


<commit_before>var net = require('net');

function Server(handler) {

	this.netServer = net.createServer(function(socket) {

		socket.setEncoding('ascii');

		socket.on('data', function(data) {

			var url = data.toString();
			url = url.substr(0, url.length - 2); // remove \r\n

			var request = {
				url: url
			};

			var response = {
				write: socket.write.bind(socket),
				end: socket.end.bind(socket)
			};

			handler(request, response);

		});

	});

};

Server.prototype.listen = function listen(port, callback) {
	this.netServer.listen(port || 70, callback || function() {});
};

module.exports = Server;
<commit_msg>better trimming of URL<commit_after>var net = require('net');

function Server(handler) {

	this.netServer = net.createServer(function(socket) {

		socket.setEncoding('ascii');

		socket.on('data', function(data) {

			var url = data.toString().trim();

			var request = {
				url: url
			};

			var response = {
				write: socket.write.bind(socket),
				end: socket.end.bind(socket)
			};

			handler(request, response);

		});

	});

};

Server.prototype.listen = function listen(port, callback) {
	this.netServer.listen(port || 70, callback || function() {});
};

module.exports = Server;
<|endoftext|>


<commit_before>import {Scrollable, ScrollableContainer} from 'widget/scrollable'
import {connect} from 'store'
import {filter} from 'rxjs/operators'
import {fromEvent} from 'rxjs'
import {isMobile} from 'widget/userAgent'
import {selectFrom} from 'stateUtils'
import Keybinding from 'widget/keybinding'
import Portal from 'widget/portal'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import escapeStringRegexp from 'escape-string-regexp'
import lookStyles from 'style/look.module.css'
import styles from './combo.module.css'

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class Combo extends React.Component {
    subscriptions = []
    input = React.createRef()
    list = React.createRef()
    highlighted = React.createRef()
    state = {
        dimensions: {},
        showOptions: false,
        filter: '',
        filteredOptions: [],
        flattenedOptions: [],
        highlightedOption: null,
        selectedOption: null,
        mouseOver: null
    }

    render() {
        const {showOptions} = this.state
        return (

 showOptions ? this.hideOptions() : this.showOptions()}>
                    {this.renderInput()}

                {showOptions ? this.renderOptions() : null}

        )
    }

    renderInput() {
        const {placeholder, autoFocus, disabled, busy} = this.props
        const {filter, selectedOption} = this.state
        const keymap = {
            ArrowUp: () => this.showOptions(),
            ArrowDown: () => this.showOptions()
        }
        return (
            <Keybinding
                disabled={disabled}
                keymap={keymap}>
                <input
                    className={selectedOption ? styles.fakePlaceholder : null}
                    type='search'
                    value={filter}
                    placeholder={selectedOption ? selectedOption.label : placeholder}
                    autoFocus={autoFocus}
                    disabled={disabled || busy || isMobile()}
                    onChange={e => this.setFilter(e.target.value)}/>
            </Keybinding>
        )
    }

    renderOptions() {
        const {placement = 'below'} = this.props
        const {dimensions: {height, top, bottom, left, right}} = this.state
        const keymap = {
            Enter: () => this.selectHighlighted(),
            Escape: () => this.setFilter(),
            ArrowUp: () => this.highlightPrevious(),
            ArrowDown: () => this.highlightNext(),
            Home: () => this.highlightFirst(),
            End: () => this.highlightLast()
        }
        const style = {
            '--left': left,
            '--width': right - left,
            '--above-height': top,
            '--above-bottom': height - top,
            '--below-height': height - bottom,
            '--below-top': bottom
        }
        return (
            <Portal>
                <Keybinding keymap={keymap}>

                        <ScrollableContainer>
                            <Scrollable className={styles.items}>

                                    {this.renderItems()}

                            </Scrollable>
                        </ScrollableContainer>

                </Keybinding>
            </Portal>
        )
    }

    renderItems() {
        const {filteredOptions} = this.state
        return filteredOptions.length
            ? filteredOptions.map((item, index) => this.renderItem(item, index))
            : this.renderItem({label: 'No results'}) // [TODO] msg
    }

    renderItem(item, index) {
        return item.value
            ? this.renderSelectableItem(item)
            : item.options
                ? this.renderGroup(item, index)
                : this.renderNonSelectableItem(item, index)
    }

    renderGroup(item) {
        return item.options.map((item, index) => this.renderItem(item, index))
    }

    renderNonSelectableItem(item, index) {
        return (

                {item.label}

        )
    }

    isHighlighted(option) {
        const {highlightedOption} = this.state
        return highlightedOption && option && highlightedOption.value === option.value
    }

    renderSelectableItem(item) {
        const {mouseOver} = this.state
        const highlighted = this.isHighlighted(item)
        const ref = highlighted
            ? this.highlighted
            : null
        return (

 this.highlightOption(item)}
                onClick={() => this.selectOption(item)}>
                {item.label}

        )
    }

    showOptions() {
        const {showOptions, flattenedOptions, selectedOption} = this.state
        if (!showOptions) {
            const highlightedOption = selectedOption || flattenedOptions[0]
            this.setState({
                showOptions: true,
                highlightedOption
            }, this.scroll)
        }
    }

    hideOptions() {
        this.setState({
            showOptions: false
        })
    }

    selectHighlighted() {
        const {highlightedOption} = this.state
        if (highlightedOption) {
            this.selectOption(highlightedOption)
        }
    }

    highlightPrevious() {
        const previousOption = (options, option) => {
            const index = _.indexOf(options, option)
            return index === -1
                ? null
                : options[Math.max(0, index - 1)]
        }
        this.setState(prevState => ({
            highlightedOption: previousOption(prevState.flattenedOptions, prevState.highlightedOption),
            mouseOver: false
        }), this.scroll)
    }

    highlightNext() {
        const nextOption = (options, option) => {
            const index = _.indexOf(options, option)
            return index === -1
                ? null
                : options[Math.min(options.length - 1, index + 1)]
        }
        this.setState(prevState => ({
            highlightedOption: nextOption(prevState.flattenedOptions, prevState.highlightedOption),
            mouseOver: false
        }), this.scroll)
    }

    highlightFirst() {
        const firstOption = options => options[0]
        this.setState(prevState => ({
            highlightedOption: firstOption(prevState.flattenedOptions),
            mouseOver: false
        }), this.scroll)
    }

    highlightLast() {
        const lastOption = options => options[options.length - 1]
        this.setState(prevState => ({
            highlightedOption: lastOption(prevState.flattenedOptions),
            mouseOver: false
        }), this.scroll)
    }

    scroll() {
        this.highlighted.current && this.highlighted.current.scrollIntoView({
            behavior: 'auto',
            block: 'nearest'
        })
    }

    setFilter(filter = '') {
        this.setState({
            showOptions: !!filter,
            filter,
            highlightedOption: null
        }, this.updateOptions)
    }

    selectOption(item) {
        const {input, onChange} = this.props
        this.setSelectedOption(item)
        this.setFilter()
        input.set(item.value)
        onChange && onChange({
            value: item.value
        })
    }

    highlightOption(highlightedOption) {
        this.setState({
            highlightedOption,
            mouseOver: true
        })
    }

    setSelectedOption(selectedOption) {
        this.updateState({selectedOption})
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    componentDidMount() {
        const click$ = fromEvent(document, 'click').pipe(
            filter(() => this.state.showOptions)
        )
        const isInternalClick = e =>
            this.list.current.contains(e.target) || this.input.current.contains(e.target)

        this.subscriptions.push(
            click$.subscribe(
                e => isInternalClick(e) || this.setFilter()
            )
        )
        this.setFilter()
        this.updateDimensions()
    }

    componentDidUpdate() {
        const {options, input} = this.props
        const selectedOption = options && input && options.find(option => option.value === input.value)
        this.setSelectedOption(selectedOption)
        this.updateOptions()
        this.updateDimensions()
    }

    componentWillUnmount() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe())
    }

    matcher(filter) {
        // match beginning of multiple words in order (e.g. "u k" matches "United Kingdom")
        return RegExp(filter.split(/\s/).map(part => '\\b' + escapeStringRegexp(part)).join('.*'), 'i')
    }

    updateOptions() {
        const {options} = this.props
        const {filter} = this.state
        const matcher = this.matcher(filter)
        const getFilteredOptions = options =>
            _.compact(
                options.map(option =>
                    option.options
                        ? {...option, options: getFilteredOptions(option.options)}
                        : matcher.test(option.label)
                            ? option
                            : null
                )
            )
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? option.options
                        : option
                )
            )
        const filteredOptions = getFilteredOptions(options)
        const flattenedOptions = getFlattenedOptions(filteredOptions)
        this.updateState(prevState => ({
            filteredOptions,
            flattenedOptions,
            highlightedOption: prevState.highlightedOption || flattenedOptions[0]
        }))
    }

    updateDimensions() {
        const {dimensions: {height}} = this.props
        const {top, bottom, left, right} = this.getBoundingBox()
        this.updateState({dimensions: {height, top, bottom, left, right}})
    }

    getBoundingBox() {
        const ref = this.input.current
        return ref
            ? ref.getBoundingClientRect()
            : {}
    }
}

export default connect(mapStateToProps)(Combo)

Combo.propTypes = {
    input: PropTypes.any.isRequired,
    options: PropTypes.any.isRequired,
    autoFocus: PropTypes.any,
    busy: PropTypes.any,
    disabled: PropTypes.any,
    placeholder: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    onChange:  PropTypes.func
}
<commit_msg>Implemented Combo keepOpen prop.<commit_after>import {Scrollable, ScrollableContainer} from 'widget/scrollable'
import {connect} from 'store'
import {filter} from 'rxjs/operators'
import {fromEvent} from 'rxjs'
import {isMobile} from 'widget/userAgent'
import {selectFrom} from 'stateUtils'
import Keybinding from 'widget/keybinding'
import Portal from 'widget/portal'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import escapeStringRegexp from 'escape-string-regexp'
import lookStyles from 'style/look.module.css'
import styles from './combo.module.css'

const mapStateToProps = state => ({
    dimensions: selectFrom(state, 'dimensions') || []
})

class Combo extends React.Component {
    subscriptions = []
    input = React.createRef()
    list = React.createRef()
    highlighted = React.createRef()
    state = {
        dimensions: {},
        showOptions: false,
        filter: '',
        filteredOptions: [],
        flattenedOptions: [],
        highlightedOption: null,
        selectedOption: null,
        mouseOver: null
    }

    render() {
        const {showOptions} = this.state
        return (

 showOptions ? this.hideOptions() : this.showOptions()}>
                    {this.renderInput()}

                {showOptions ? this.renderOptions() : null}

        )
    }

    renderInput() {
        const {placeholder, autoFocus, disabled, busy} = this.props
        const {filter, selectedOption} = this.state
        const keymap = {
            ArrowUp: () => this.showOptions(),
            ArrowDown: () => this.showOptions()
        }
        return (
            <Keybinding
                disabled={disabled}
                keymap={keymap}>
                <input
                    className={selectedOption ? styles.fakePlaceholder : null}
                    type='search'
                    value={filter}
                    placeholder={selectedOption ? selectedOption.label : placeholder}
                    autoFocus={autoFocus}
                    disabled={disabled || busy || isMobile()}
                    onChange={e => this.setFilter(e.target.value)}/>
            </Keybinding>
        )
    }

    renderOptions() {
        const {placement = 'below'} = this.props
        const {dimensions: {height, top, bottom, left, right}} = this.state
        const keymap = {
            Enter: () => this.selectHighlighted(),
            Escape: () => this.setFilter(),
            ArrowUp: () => this.highlightPrevious(),
            ArrowDown: () => this.highlightNext(),
            Home: () => this.highlightFirst(),
            End: () => this.highlightLast()
        }
        const style = {
            '--left': left,
            '--width': right - left,
            '--above-height': top,
            '--above-bottom': height - top,
            '--below-height': height - bottom,
            '--below-top': bottom
        }
        return (
            <Portal>
                <Keybinding keymap={keymap}>

                        <ScrollableContainer>
                            <Scrollable className={styles.items}>

                                    {this.renderItems()}

                            </Scrollable>
                        </ScrollableContainer>

                </Keybinding>
            </Portal>
        )
    }

    renderItems() {
        const {filteredOptions} = this.state
        return filteredOptions.length
            ? filteredOptions.map((item, index) => this.renderItem(item, index))
            : this.renderItem({label: 'No results'}) // [TODO] msg
    }

    renderItem(item, index) {
        return item.value
            ? this.renderSelectableItem(item)
            : item.options
                ? this.renderGroup(item, index)
                : this.renderNonSelectableItem(item, index)
    }

    renderGroup(item) {
        return item.options.map((item, index) => this.renderItem(item, index))
    }

    renderNonSelectableItem(item, index) {
        return (

                {item.label}

        )
    }

    isHighlighted(option) {
        const {highlightedOption} = this.state
        return highlightedOption && option && highlightedOption.value === option.value
    }

    renderSelectableItem(item) {
        const {mouseOver} = this.state
        const highlighted = this.isHighlighted(item)
        const ref = highlighted
            ? this.highlighted
            : null
        return (

 this.highlightOption(item)}
                onClick={() => this.selectOption(item)}>
                {item.label}

        )
    }

    showOptions() {
        const {showOptions, flattenedOptions, selectedOption} = this.state
        if (!showOptions) {
            const highlightedOption = selectedOption || flattenedOptions[0]
            this.setState({
                showOptions: true,
                highlightedOption
            }, this.scroll)
        }
    }

    hideOptions() {
        this.setState({
            showOptions: false
        })
    }

    selectHighlighted() {
        const {highlightedOption} = this.state
        if (highlightedOption) {
            this.selectOption(highlightedOption)
        }
    }

    highlightPrevious() {
        const previousOption = (options, option) => {
            const index = _.indexOf(options, option)
            return index === -1
                ? null
                : options[Math.max(0, index - 1)]
        }
        this.setState(prevState => ({
            highlightedOption: previousOption(prevState.flattenedOptions, prevState.highlightedOption),
            mouseOver: false
        }), this.scroll)
    }

    highlightNext() {
        const nextOption = (options, option) => {
            const index = _.indexOf(options, option)
            return index === -1
                ? null
                : options[Math.min(options.length - 1, index + 1)]
        }
        this.setState(prevState => ({
            highlightedOption: nextOption(prevState.flattenedOptions, prevState.highlightedOption),
            mouseOver: false
        }), this.scroll)
    }

    highlightFirst() {
        const firstOption = options => options[0]
        this.setState(prevState => ({
            highlightedOption: firstOption(prevState.flattenedOptions),
            mouseOver: false
        }), this.scroll)
    }

    highlightLast() {
        const lastOption = options => options[options.length - 1]
        this.setState(prevState => ({
            highlightedOption: lastOption(prevState.flattenedOptions),
            mouseOver: false
        }), this.scroll)
    }

    scroll() {
        this.highlighted.current && this.highlighted.current.scrollIntoView({
            behavior: 'auto',
            block: 'nearest'
        })
    }

    setFilter(filter = '') {
        this.setState({
            showOptions: !!filter,
            filter,
            highlightedOption: null
        }, this.updateOptions)
    }

    selectOption(item) {
        const {input, onChange} = this.props
        this.setSelectedOption(item)
        this.setFilter()
        input.set(item.value)
        onChange && onChange({
            value: item.value
        })
    }

    highlightOption(highlightedOption) {
        this.setState({
            highlightedOption,
            mouseOver: true
        })
    }

    setSelectedOption(selectedOption) {
        this.updateState({selectedOption})
    }

    updateState(state, callback) {
        const updatedState = (prevState, state) =>
            _.isEqual(_.pick(prevState, _.keys(state)), state) ? null : state
        this.setState(
            prevState =>
                updatedState(prevState, _.isFunction(state) ? state(prevState) : state),
            callback
        )
    }

    componentDidMount() {
        const click$ = fromEvent(document, 'click').pipe(
            filter(() => this.state.showOptions)
        )
        const isInternalClick = e =>
            this.list.current.contains(e.target) || this.input.current.contains(e.target)

        this.subscriptions.push(
            click$.subscribe(
                e => isInternalClick(e) || this.setFilter()
            )
        )
        this.setFilter()
        this.updateDimensions()
    }

    componentDidUpdate() {
        const {options, input} = this.props
        const selectedOption = options && input && options.find(option => option.value === input.value)
        this.setSelectedOption(selectedOption)
        this.updateOptions()
        this.updateDimensions()
    }

    componentWillUnmount() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe())
    }

    matcher(filter) {
        // match beginning of multiple words in order (e.g. "u k" matches "United Kingdom")
        return RegExp(filter.split(/\s/).map(part => '\\b' + escapeStringRegexp(part)).join('.*'), 'i')
    }

    updateOptions() {
        const {options} = this.props
        const {filter} = this.state
        const matcher = this.matcher(filter)
        const getFilteredOptions = options =>
            _.compact(
                options.map(option =>
                    option.options
                        ? {...option, options: getFilteredOptions(option.options)}
                        : matcher.test(option.label)
                            ? option
                            : null
                )
            )
        const getFlattenedOptions = options =>
            _.flatten(
                options.map(option =>
                    option.options
                        ? option.options
                        : option
                )
            )
        const filteredOptions = getFilteredOptions(options)
        const flattenedOptions = getFlattenedOptions(filteredOptions)
        this.updateState(prevState => ({
            filteredOptions,
            flattenedOptions,
            highlightedOption: prevState.highlightedOption || flattenedOptions[0]
        }))
    }

    updateDimensions() {
        const {dimensions: {height}} = this.props
        const {top, bottom, left, right} = this.getBoundingBox()
        this.updateState({dimensions: {height, top, bottom, left, right}})
    }

    getBoundingBox() {
        const ref = this.input.current
        return ref
            ? ref.getBoundingClientRect()
            : {}
    }
}

export default connect(mapStateToProps)(Combo)

Combo.propTypes = {
    input: PropTypes.any.isRequired,
    options: PropTypes.any.isRequired,
    autoFocus: PropTypes.any,
    busy: PropTypes.any,
    disabled: PropTypes.any,
    keepOpen: PropTypes.any,
    placeholder: PropTypes.string,
    placement: PropTypes.oneOf(['above', 'below']),
    onChange:  PropTypes.func
}
<|endoftext|>


<commit_before>import React from "react";
import { Modal as BsModal } from "react-bootstrap";

import { DialogOverlay, DialogContent } from "@reach/dialog";

import styled, { keyframes } from "styled-components";
import { BoxGroupSection, Box } from "./Box";
import { Alert } from "./Alert";

export const Modal = styled(BsModal)`
    ${Alert} {
        border-left: none;
        border-radius: 0;
        border-right: none;
        margin: -1px 0 0;
    }
`;

const modalOverlayOpen = keyframes`
    0% {
        opacity: 0;
    }
`;

const modalOverlayClose = keyframes`
    100% {
      opacity: 0;
    }
`;

const modalContentOpen = keyframes`
    100% {
        transform: translate(0,100px);
    }
`;

const modalContentClose = keyframes`
    0% {
        transform: translate(0,100px);
    }
    100% {
        opacity: 0;
    }
`;
export const ModalDialogOverlay = styled(({ close, ...rest }) => <DialogOverlay {...rest} />)`
    animation: ${props => (props.close ? modalOverlayClose : modalOverlayOpen)} 0.3s;
    animation-fill-mode: forwards;
    background: hsla(0, 0%, 0%, 0.33);
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: auto;
    position: fixed;
    z-index: 9999;
`;

export const ModalDialogContent = styled(({ close, size, ...rest }) => <DialogContent {...rest} />)`
    animation: ${props => (props.close ? modalContentClose : modalContentOpen)} 0.3s;
    animation-fill-mode: forwards;
    background: white;
    box-shadow: rgba(0, 0, 0, 0.5) 0 5px 15px;
    margin: -70px auto;
    padding: 0;
    position: relative;
    width: ${props => (props.size === "lg" ? "900px" : "600px")};

    @media (max-width: 991px) {
        width: 600px;
    }
`;

const DialogHeader = styled(({ modalStyle, headerBorderBottom, capitalize, ...rest }) => <BoxGroupSection {...rest} />)`
    background-color: ${props => (props.modalStyle === "danger" ? "#d44b40" : "")};
    color: ${props => (props.modalStyle === "danger" ? "white" : "")};
    height: 55px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: ${props => props.headerBorderBottom} !important;
    text-transform: ${props => props.capitalize};
`;

export const DialogBody = styled.div`
    padding: 15px;
`;

<<<<<<< 7f895b5b7da896b0162356599074b00ef990069b
export const DialogFooter = styled(Box)`
    display: flex;
    justify-content: end;
=======
export const DialogFooter = styled(({ modalStyle, ...rest }) => <Box {...rest} />)`
    border-left: none;
    border-right: none;
    border-bottom: none;
    border-top: ${props => (props.modalStyle === "danger" ? "none" : "")}
    justify-content: end;
    text-align: right;
    overflow-y: auto;
`;

export class ModalDialog extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            open: false,
            close: false
        };
    }

    static getDerivedStateFromProps(props) {
        if (props.show === true) {
            return {
                open: true
            };
        }
        return null;
    }

    onClose = () => {
        this.setState({ close: true });
    };

    onClosed = () => {
        if (this.state.close === true) {
            this.setState({ open: false, close: false });

            if (this.props.onExited) {
                this.props.onExited();
            }
        }
    };

    onOpen = () => {
        if (this.state.open === true && this.state.close === false && this.props.onEnter) {
            this.props.onEnter();
        }
    };

    render() {
        return (

                <ModalDialogOverlay
                    isOpen={this.state.open}
                    close={this.state.close}
                    onAnimationEnd={this.onClosed}
                    onDismiss={() => {
                        this.props.onHide();
                        this.onClose();
                    }}
                >
                    <ModalDialogContent
                        size={this.props.size}
                        aria-labelledby={this.props.label}
                        close={this.state.close}
                        onAnimationEnd={this.onClosed}
                        onAnimationStart={this.onOpen}
                    >
                        <DialogHeader
                            modalStyle={this.props.modalStyle}
                            headerBorderBottom={this.props.headerBorderBottom}
                            capitalize={this.props.capitalize}
                        >
                            {this.props.headerText}
                            {CloseButton}
                        </DialogHeader>
>>>>>>> Replace bootstrap modal in base RemoveModal Component
                        {this.props.children}
                    </ModalDialogContent>
                </ModalDialogOverlay>

        );
    }
}
<commit_msg>Fix Modal issue<commit_after>import React from "react";
import { Modal as BsModal } from "react-bootstrap";
import { DialogOverlay, DialogContent } from "@reach/dialog";
import styled, { keyframes } from "styled-components";
import { Icon } from "./Icon";
import { BoxGroupSection, Box } from "./Box";

const modalOverlayOpen = keyframes`
    0% {
        opacity: 0;
    }
`;

const modalOverlayClose = keyframes`
    100% {
      opacity: 0;
    }
`;

const modalContentOpen = keyframes`
    100% {
        transform: translate(0,100px);
    }
`;

const modalContentClose = keyframes`
    0% {
        transform: translate(0,100px);
    }
    100% {
        opacity: 0;
    }
`;
export const ModalDialogOverlay = styled(({ close, ...rest }) => <DialogOverlay {...rest} />)`
    animation: ${props => (props.close ? modalOverlayClose : modalOverlayOpen)} 0.3s;
    animation-fill-mode: forwards;
    background: hsla(0, 0%, 0%, 0.33);
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: auto;
    position: fixed;
    z-index: 9999;
`;

export const ModalDialogContent = styled(({ close, size, ...rest }) => <DialogContent {...rest} />)`
    animation: ${props => (props.close ? modalContentClose : modalContentOpen)} 0.3s;
    animation-fill-mode: forwards;
    background: white;
    box-shadow: rgba(0, 0, 0, 0.5) 0 5px 15px;
    margin: -70px auto;
    padding: 0;
    position: relative;
    width: ${props => (props.size === "lg" ? "900px" : "600px")};

    @media (max-width: 991px) {
        width: 600px;
    }
`;

const DialogHeader = styled(({ modalStyle, headerBorderBottom, capitalize, ...rest }) => <BoxGroupSection {...rest} />)`
    background-color: ${props => (props.modalStyle === "danger" ? "#d44b40" : "")};
    color: ${props => (props.modalStyle === "danger" ? "white" : "")};
    height: 55px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: ${props => props.headerBorderBottom} !important;
    text-transform: ${props => props.capitalize};
`;

export const DialogBody = styled.div`
    padding: 15px;
`;

export const DialogFooter = styled(({ modalStyle, ...rest }) => <Box {...rest} />)`
    border-left: none;
    border-right: none;
    border-bottom: none;
    border-top: ${props => (props.modalStyle === "danger" ? "none" : "")}
    justify-content: end;
    text-align: right;
    overflow-y: auto;
`;

export class ModalDialog extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            open: false,
            close: false
        };
    }

    static getDerivedStateFromProps(props) {
        if (props.show === true) {
            return {
                open: true
            };
        }
        return null;
    }

    onClose = () => {
        this.setState({ close: true });
    };

    onClosed = () => {
        if (this.state.close === true) {
            this.setState({ open: false, close: false });

            if (this.props.onExited) {
                this.props.onExited();
            }
        }
    };

    onOpen = () => {
        if (this.state.open === true && this.state.close === false && this.props.onEnter) {
            this.props.onEnter();
        }
    };

    render() {
        const CloseButton = (
            <Icon
                name="times"
                onClick={() => {
                    this.props.onHide();
                    this.onClose();
                }}
                style={{ color: "grey" }}
            />
        );

        return (

                <ModalDialogOverlay
                    isOpen={this.state.open}
                    close={this.state.close}
                    onAnimationEnd={this.onClosed}
                    onDismiss={() => {
                        this.props.onHide();
                        this.onClose();
                    }}
                >
                    <ModalDialogContent
                        size={this.props.size}
                        aria-labelledby={this.props.label}
                        close={this.state.close}
                        onAnimationEnd={this.onClosed}
                        onAnimationStart={this.onOpen}
                    >
                        <DialogHeader
                            modalStyle={this.props.modalStyle}
                            headerBorderBottom={this.props.headerBorderBottom}
                            capitalize={this.props.capitalize}
                        >
                            {this.props.headerText}
                            {CloseButton}
                        </DialogHeader>
                        {this.props.children}
                    </ModalDialogContent>
                </ModalDialogOverlay>

        );
    }
}
<|endoftext|>


<commit_before>/**
 *
 * Get the [cookie](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object)
 * with the given name for current page.
 *
 * @param {String} name name of requested cookie
 * @returns {Object|null} requested cookie if existing
 *
 * @uses protocol/cookie
 *
 */

var async = require('async');

module.exports = function getCookie (name) {

    /*!
     * make sure that callback contains chainit callback
     */
    var callback = arguments[arguments.length - 1];

    /*!
     * paramter check
     */
    if(typeof name !== 'string') {
        name = null;
    }

    var self = this,
        response = {};

    async.waterfall([
        function(cb) {
            self.cookie(cb);
        },
        function(res, cb) {
            response.cookie = res;
            cb();
        }
    ], function(err) {

        var cookie = response.cookie.value;

        if(name) {
            cookie = cookie.filter(function(obj) {
                return obj.name === name;
            })[0] || null;
        }

        callback(err, cookie || {} ,response);

    });

};<commit_msg>getCookie: return null if no cookie was found<commit_after>/**
 *
 * Get the [cookie](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object)
 * with the given name for current page.
 *
 * @param {String} name name of requested cookie
 * @returns {Object|null} requested cookie if existing
 *
 * @uses protocol/cookie
 *
 */

var async = require('async');

module.exports = function getCookie (name) {

    /*!
     * make sure that callback contains chainit callback
     */
    var callback = arguments[arguments.length - 1];

    /*!
     * paramter check
     */
    if(typeof name !== 'string') {
        name = null;
    }

    var self = this,
        response = {};

    async.waterfall([
        function(cb) {
            self.cookie(cb);
        },
        function(res, cb) {
            response.cookie = res;
            cb();
        }
    ], function(err) {

        var cookie = response.cookie.value;

        if(name) {
            cookie = cookie.filter(function(obj) {
                return obj.name === name;
            })[0] || null;
        }

        if(cookie instanceof Array && cookie.length === 0) {
            cookie = null;
        }

        callback(err, cookie || null ,response);

    });

};<|endoftext|>


<commit_before>const fs = require('fs')
const _ = require('lodash')
const chai = require('chai')
const path = require('path')
const nock = require('nock')
const unirest = require('unirest')
const nodeUrl = 'http://127.0.0.1:9999'
const nodeMock = nock(nodeUrl)

const appDir = (path.resolve(__dirname) + '/').replace('lib/hash/', '')
const libDir = (path.resolve(__dirname) + '/').replace('hash/', '')

const mainFile = require(appDir + 'index.js')
const hash = mainFile.hash
const utils = mainFile.utils

const mock = require(libDir + 'testAssets/assets.js')
const nodes = require(appDir + 'lib/nodes.js')

describe('Testing has module', () => {
  describe('getHashData Funciton', () => {
    it('should return hashData', function (done) {
      hash
        .getHashData(mock.html.hashPage)
        .then(res => {
          var err = null

          try {
            if (!_.isEqual(res, mock.parsedPageObject)) throw new Error('Object is not the same')
          } catch (e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))
    })
  })
  describe('getPage Function', () => {
    it('should return haspage', function (done) {
      const mockOpts = {
        html: mock.html.hashPage,
        url: nodeUrl
      }

      const page = 'h'

      const address = {
        ip: '127.0.0.1',
        port: '9999'
      }

      nodeMock.get('/' + page).reply(200, mockOpts.html)

      utils
        .getPage(address, 'h')
        .then(res => {
          var err = null

          try {

          } catch (e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))
    })
  })
  describe('getHashDataFromNodes Function', () => {
    it('should return haspage', function (done) {
      /**
       * Nock is not handling too many requests at once, but I have tested this
       * with a real mining node. It's working alright
       */
      // const mockOpts = {
      //   html: mock.html.hashPage,
      //   url: nodeUrl
      // }
      //
      // const page = 'h'
      //
      // const address = {
      //   ip: '127.0.0.1',
      //   port: '9999'
      // }
      //
      // nodeMock.get('/'+page).reply(200, mockOpts.html)
      //
      // hash
      //   .getHashDataFromNodes(nodes)
      //   .then(res => {
      //     var err = null
      //     try {
      //       console.log(res)
      //     } catch(e) {
      //       err = e
      //     }
      //
      //     done(err)
      //   })
      //   .catch(err => done(err))
      done()
    })
  })
  describe('getHashSum Function', () => {
    it('should return hashsum', function (done) {

      hash
        .getHashSum(mock.parsedNodesTotal)
        .then(res => {
          var err = null

          try {
            if (!_.isEqual(res, mock.totalHashSum)) throw new Error('Total is not as expected')
          } catch(e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))

    })
  })
})
<commit_msg>Space fix<commit_after>const fs = require('fs')
const _ = require('lodash')
const chai = require('chai')
const path = require('path')
const nock = require('nock')
const unirest = require('unirest')
const nodeUrl = 'http://127.0.0.1:9999'
const nodeMock = nock(nodeUrl)

const appDir = (path.resolve(__dirname) + '/').replace('lib/hash/', '')
const libDir = (path.resolve(__dirname) + '/').replace('hash/', '')

const mainFile = require(appDir + 'index.js')
const hash = mainFile.hash
const utils = mainFile.utils

const mock = require(libDir + 'testAssets/assets.js')
const nodes = require(appDir + 'lib/nodes.js')

describe('Testing has module', () => {
  describe('getHashData Funciton', () => {
    it('should return hashData', function (done) {
      hash
        .getHashData(mock.html.hashPage)
        .then(res => {
          var err = null

          try {
            if (!_.isEqual(res, mock.parsedPageObject)) throw new Error('Object is not the same')
          } catch (e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))
    })
  })
  describe('getPage Function', () => {
    it('should return haspage', function (done) {
      const mockOpts = {
        html: mock.html.hashPage,
        url: nodeUrl
      }

      const page = 'h'

      const address = {
        ip: '127.0.0.1',
        port: '9999'
      }

      nodeMock.get('/' + page).reply(200, mockOpts.html)

      utils
        .getPage(address, 'h')
        .then(res => {
          var err = null

          try {

          } catch (e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))
    })
  })
  describe('getHashDataFromNodes Function', () => {
    it('should return haspage', function (done) {
      /**
       * Nock is not handling too many requests at once, but I have tested this
       * with a real mining node. It's working alright
       */
      // const mockOpts = {
      //   html: mock.html.hashPage,
      //   url: nodeUrl
      // }
      //
      // const page = 'h'
      //
      // const address = {
      //   ip: '127.0.0.1',
      //   port: '9999'
      // }
      //
      // nodeMock.get('/'+page).reply(200, mockOpts.html)
      //
      // hash
      //   .getHashDataFromNodes(nodes)
      //   .then(res => {
      //     var err = null
      //     try {
      //       console.log(res)
      //     } catch(e) {
      //       err = e
      //     }
      //
      //     done(err)
      //   })
      //   .catch(err => done(err))
      done()
    })
  })
  describe('getHashSum Function', () => {
    it('should return hashsum', function (done) {

      hash
        .getHashSum(mock.parsedNodesTotal)
        .then(res => {
          var err = null

          try {
            if (!_.isEqual(res, mock.totalHashSum)) throw new Error('Total is not as expected')
          } catch(e) {
            err = e
          }

          done(err)
        })
        .catch(err => done(err))

    })
  })
})
<|endoftext|>