<commit_before>/*
 * grunt-cssrb
 * https://github.com/iadramelk/grunt-cssrb
 *
 * Copyright (c) 2013 Aleksey Ivanov
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function( grunt ) {

    var path = require( 'path' );

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

    grunt.registerMultiTask( 'cssrb', 'CSS resources rebase plugun', function() {

        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options( {
            copy: false,
            move: false,
            patterns: { '': '' }
        } ),
        cssURLSEdit = require( 'css-url-edit' ),
        URLS,
        urls_collection;

        if ( !grunt.file.isPathAbsolute( options.old_base ) ) {

            options.old_base = path.join( process.cwd(), options.old_base );

        }

        if ( !grunt.file.isPathAbsolute( options.new_base ) ) {

            options.new_base = path.join( process.cwd(), options.new_base );

        }

        // Iterate over all specified file groups.
        this.files.forEach( function( f ) {

            // Concat specified files.
            var src = f.src.filter( function( filepath ) {

                // Warn on and remove invalid source files (if nonull was set).
                if ( !grunt.file.exists( filepath ) ) {

                    grunt.log.warn( 'Source file "' + filepath + '" not found.' );
                    return false;

                } else {

                    return true;

                }

            } ).map(function( filepath ) {

                // Read file source.
                return grunt.file.read( filepath );

            }).join( grunt.util.normalizelf('\n') );

            URLS = cssURLSEdit( src );

            var patterns = options.patterns,
            key,
            mask;

            for ( key in patterns) {

                if ( patterns.hasOwnProperty( key ) ) {

                    if ( typeof key === 'string' ) {

                        mask = new RegExp( key );

                    } else if ( key instanceof RegExp === true ) {

                        mask = key;

                    } else {

                        grunt.log.error( '"' + key + '" pattern is ignored. Must be RegExp or String.' );

                    }

                    urls_collection = URLS.getURLs( mask );

                    urls_collection.forEach( function ( path_url ) {

                        var path_old = path.join( options.old_base, path_url ),
                            path_new = path.join( options.new_base, patterns[ key ], path.basename( path_url ) ),
                            file_exists;

                        if ( path_old.indexOf('?') !== -1 ) {

                            path_old = path_old.slice( 0, path_old.indexOf('?') );
                            path_new = path_new.slice( 0, path_new.indexOf('?') );
                        }

                        if ( path_old.indexOf('#') !== -1 ) {

                            path_old = path_old.slice( 0, path_old.indexOf('#') );
                            path_new = path_new.slice( 0, path_new.indexOf('#') );
                        }

                        file_exists = grunt.file.exists( path_old );

                        var path_regex = path_url.replace(/\//gi, '\\/');
                            path_regex = path_regex.replace(/\?/gi, '\\?');
                            path_regex = path_regex.replace(/\./gi, '\\.');

                        URLS.changeURLContent( new RegExp(path_regex), path.join( patterns[ key ], path.basename( path_url ) ) );

                        if ( options.move && file_exists ) {

                             grunt.file.copy( path_old, path_new );
                             grunt.file.delete( path_old );

                             grunt.log.writeln('Moved "' + path.relative( process.cwd(), path_old ) + '" to "' + path.relative( process.cwd(), path_new ) + '".');

                        } else if ( options.copy && file_exists ) {

                             grunt.file.copy( path_old, path_new );

                             grunt.log.writeln('Copied "' + path.relative( process.cwd(), path_old ) + '" to "' + path.relative( process.cwd(), path_new ) + '".');

                        } else if ( options.copy || options.move ) {

                             grunt.log.warn('File not found "' + path_old + '".');

                        }

                    } );

                }

            }

            // Write the destination file.
            grunt.file.write( f.dest, URLS.rebuildCSS() );

            // Print a success message.
            grunt.log.writeln( 'File "' + f.dest + '" created.' );

        } );

    } );

};
<commit_msg>Fixed #1 bug with generation path to the images on windows<commit_after>/*
 * grunt-cssrb
 * https://github.com/iadramelk/grunt-cssrb
 *
 * Copyright (c) 2013 Aleksey Ivanov
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function( grunt ) {

    var path = require( 'path' );

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

    grunt.registerMultiTask( 'cssrb', 'CSS resources rebase plugun', function() {

        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options( {
            copy: false,
            move: false,
            patterns: { '': '' }
        } ),
        cssURLSEdit = require( 'css-url-edit' ),
        URLS,
        urls_collection;

        if ( !grunt.file.isPathAbsolute( options.old_base ) ) {

            options.old_base = path.join( process.cwd(), options.old_base );

        }

        if ( !grunt.file.isPathAbsolute( options.new_base ) ) {

            options.new_base = path.join( process.cwd(), options.new_base );

        }

        // Iterate over all specified file groups.
        this.files.forEach( function( f ) {

            // Concat specified files.
            var src = f.src.filter( function( filepath ) {

                // Warn on and remove invalid source files (if nonull was set).
                if ( !grunt.file.exists( filepath ) ) {

                    grunt.log.warn( 'Source file "' + filepath + '" not found.' );
                    return false;

                } else {

                    return true;

                }

            } ).map(function( filepath ) {

                // Read file source.
                return grunt.file.read( filepath );

            }).join( grunt.util.normalizelf('\n') );

            URLS = cssURLSEdit( src );

            var patterns = options.patterns,
            key,
            mask;

            for ( key in patterns) {

                if ( patterns.hasOwnProperty( key ) ) {

                    if ( typeof key === 'string' ) {

                        mask = new RegExp( key );

                    } else if ( key instanceof RegExp === true ) {

                        mask = key;

                    } else {

                        grunt.log.error( '"' + key + '" pattern is ignored. Must be RegExp or String.' );

                    }

                    urls_collection = URLS.getURLs( mask );

                    urls_collection.forEach( function ( path_url ) {

                        var path_old = path.join( options.old_base, path_url ),
                            path_new = path.join( options.new_base, patterns[ key ], path.basename( path_url ) ),
                            file_exists;

                        if ( path_old.indexOf('?') !== -1 ) {

                            path_old = path_old.slice( 0, path_old.indexOf('?') );
                            path_new = path_new.slice( 0, path_new.indexOf('?') );
                        }

                        if ( path_old.indexOf('#') !== -1 ) {

                            path_old = path_old.slice( 0, path_old.indexOf('#') );
                            path_new = path_new.slice( 0, path_new.indexOf('#') );
                        }

                        file_exists = grunt.file.exists( path_old );

                        var path_regex = path_url.replace(/\//gi, '\\/');
                            path_regex = path_regex.replace(/\?/gi, '\\?');
                            path_regex = path_regex.replace(/\./gi, '\\.');

                        URLS.changeURLContent( new RegExp(path_regex), path.join( patterns[ key ],
                            path.basename( path_url )).replace(/\\/gi, '/')  );

                        if ( options.move && file_exists ) {

                             grunt.file.copy( path_old, path_new );
                             grunt.file.delete( path_old );

                             grunt.log.writeln('Moved "' + path.relative( process.cwd(), path_old ) + '" to "' + path.relative( process.cwd(), path_new ) + '".');

                        } else if ( options.copy && file_exists ) {

                             grunt.file.copy( path_old, path_new );

                             grunt.log.writeln('Copied "' + path.relative( process.cwd(), path_old ) + '" to "' + path.relative( process.cwd(), path_new ) + '".');

                        } else if ( options.copy || options.move ) {

                             grunt.log.warn('File not found "' + path_old + '".');

                        }

                    } );

                }

            }

            // Write the destination file.
            grunt.file.write( f.dest, URLS.rebuildCSS() );

            // Print a success message.
            grunt.log.writeln( 'File "' + f.dest + '" created.' );

        } );

    } );

};
<|endoftext|>


<commit_before>import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/base';
import { darken, lighten } from '@mui/system';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';
import capitalize from '../utils/capitalize';
import Paper from '../Paper';
import alertClasses, { getAlertUtilityClass } from './alertClasses';
import IconButton from '../IconButton';
import SuccessOutlinedIcon from '../internal/svg-icons/SuccessOutlined';
import ReportProblemOutlinedIcon from '../internal/svg-icons/ReportProblemOutlined';
import ErrorOutlineIcon from '../internal/svg-icons/ErrorOutline';
import InfoOutlinedIcon from '../internal/svg-icons/InfoOutlined';
import CloseIcon from '../internal/svg-icons/Close';

const useUtilityClasses = (ownerState) => {
  const { variant, color, severity, classes } = ownerState;

  const slots = {
    root: ['root', `${variant}${capitalize(color || severity)}`, `${variant}`],
    icon: ['icon'],
    message: ['message'],
    action: ['action'],
  };

  return composeClasses(slots, getAlertUtilityClass, classes);
};

const AlertRoot = styled(Paper, {
  name: 'MuiAlert',
  slot: 'Root',
  overridesResolver: (props, styles) => {
    const { ownerState } = props;

    return [
      styles.root,
      styles[ownerState.variant],
      styles[`${ownerState.variant}${capitalize(ownerState.color || ownerState.severity)}`],
    ];
  },
})(({ theme, ownerState }) => {
  const getColor = theme.palette.mode === 'light' ? darken : lighten;
  const getBackgroundColor = theme.palette.mode === 'light' ? lighten : darken;
  const color = ownerState.color || ownerState.severity;

  return {
    ...theme.typography.body2,
    backgroundColor: 'transparent',
    display: 'flex',
    padding: '6px 16px',
    ...(color &&
      ownerState.variant === 'standard' && {
        color: getColor(theme.palette[color].light, 0.6),
        backgroundColor: getBackgroundColor(theme.palette[color].light, 0.9),
        [`& .${alertClasses.icon}`]: {
          color:
            theme.palette.mode === 'dark' ? theme.palette[color].main : theme.palette[color].light,
        },
      }),
    ...(color &&
      ownerState.variant === 'outlined' && {
        color: getColor(theme.palette[color].light, 0.6),
        border: `1px solid ${theme.palette[color].light}`,
        [`& .${alertClasses.icon}`]: {
          color:
            theme.palette.mode === 'dark' ? theme.palette[color].main : theme.palette[color].light,
        },
      }),
    ...(color &&
      ownerState.variant === 'filled' && {
        color: '#fff',
        fontWeight: theme.typography.fontWeightMedium,
        backgroundColor:
          theme.palette.mode === 'dark' ? theme.palette[color].dark : theme.palette[color].main,
      }),
  };
});

const AlertIcon = styled('div', {
  name: 'MuiAlert',
  slot: 'Icon',
  overridesResolver: (props, styles) => styles.icon,
})({
  marginRight: 12,
  padding: '7px 0',
  display: 'flex',
  fontSize: 22,
  opacity: 0.9,
});

const AlertMessage = styled('div', {
  name: 'MuiAlert',
  slot: 'Message',
  overridesResolver: (props, styles) => styles.message,
})({
  padding: '8px 0',
  minWidth: 0,
  overflow: 'auto',
});

const AlertAction = styled('div', {
  name: 'MuiAlert',
  slot: 'Action',
  overridesResolver: (props, styles) => styles.action,
})({
  display: 'flex',
  alignItems: 'flex-start',
  padding: '4px 0 0 16px',
  marginLeft: 'auto',
  marginRight: -8,
});

const defaultIconMapping = {
  success: <SuccessOutlinedIcon fontSize="inherit" />,
  warning: <ReportProblemOutlinedIcon fontSize="inherit" />,
  error: <ErrorOutlineIcon fontSize="inherit" />,
  info: <InfoOutlinedIcon fontSize="inherit" />,
};

const Alert = React.forwardRef(function Alert(inProps, ref) {
  const props = useThemeProps({ props: inProps, name: 'MuiAlert' });
  const {
    action,
    children,
    className,
    closeText = 'Close',
    color,
    icon,
    iconMapping = defaultIconMapping,
    onClose,
    role = 'alert',
    severity = 'success',
    variant = 'standard',
    ...other
  } = props;

  const ownerState = {
    ...props,
    color,
    severity,
    variant,
  };

  const classes = useUtilityClasses(ownerState);

  return (
    <AlertRoot
      role={role}
      elevation={0}
      ownerState={ownerState}
      className={clsx(classes.root, className)}
      ref={ref}
      {...other}
    >
      {icon !== false ? (
        <AlertIcon ownerState={ownerState} className={classes.icon}>
          {icon || iconMapping[severity] || defaultIconMapping[severity]}
        </AlertIcon>
      ) : null}
      <AlertMessage ownerState={ownerState} className={classes.message}>
        {children}
      </AlertMessage>
      {action != null ? (
        <AlertAction ownerState={ownerState} className={classes.action}>
          {action}
        </AlertAction>
      ) : null}
      {action == null && onClose ? (
        <AlertAction ownerState={ownerState} className={classes.action}>
          <IconButton
            size="small"
            aria-label={closeText}
            title={closeText}
            color="inherit"
            onClick={onClose}
          >
            <CloseIcon fontSize="small" />
          </IconButton>
        </AlertAction>
      ) : null}
    </AlertRoot>
  );
});

Alert.propTypes /* remove-proptypes */ = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * The action to display. It renders after the message, at the end of the alert.
   */
  action: PropTypes.node,
  /**
   * The content of the component.
   */
  children: PropTypes.node,
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * Override the default label for the *close popup* icon button.
   *
   * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).
   * @default 'Close'
   */
  closeText: PropTypes.string,
  /**
   * The color of the component. Unless provided, the value is taken from the `severity` prop.
   * It supports both default and custom theme colors, which can be added as shown in the
   * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
   */
  color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
    PropTypes.oneOf(['error', 'info', 'success', 'warning']),
    PropTypes.string,
  ]),
  /**
   * Override the icon displayed before the children.
   * Unless provided, the icon is mapped to the value of the `severity` prop.
   * Set to `false` to remove the `icon`.
   */
  icon: PropTypes.node,
  /**
   * The component maps the `severity` prop to a range of different icons,
   * for instance success to `<SuccessOutlined>`.
   * If you wish to change this mapping, you can provide your own.
   * Alternatively, you can use the `icon` prop to override the icon displayed.
   */
  iconMapping: PropTypes.shape({
    error: PropTypes.node,
    info: PropTypes.node,
    success: PropTypes.node,
    warning: PropTypes.node,
  }),
  /**
   * Callback fired when the component requests to be closed.
   * When provided and no `action` prop is set, a close icon button is displayed that triggers the callback when clicked.
   * @param {React.SyntheticEvent} event The event source of the callback.
   */
  onClose: PropTypes.func,
  /**
   * The ARIA role attribute of the element.
   * @default 'alert'
   */
  role: PropTypes.string,
  /**
   * The severity of the alert. This defines the color and icon used.
   * @default 'success'
   */
  severity: PropTypes.oneOf(['error', 'info', 'success', 'warning']),
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),
    PropTypes.func,
    PropTypes.object,
  ]),
  /**
   * The variant to use.
   * @default 'standard'
   */
  variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
    PropTypes.oneOf(['filled', 'outlined', 'standard']),
    PropTypes.string,
  ]),
};

export default Alert;
<commit_msg>[Alert] Use getContrastText for filled variant font color (#29813)<commit_after>import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/base';
import { darken, lighten } from '@mui/system';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';
import capitalize from '../utils/capitalize';
import Paper from '../Paper';
import alertClasses, { getAlertUtilityClass } from './alertClasses';
import IconButton from '../IconButton';
import SuccessOutlinedIcon from '../internal/svg-icons/SuccessOutlined';
import ReportProblemOutlinedIcon from '../internal/svg-icons/ReportProblemOutlined';
import ErrorOutlineIcon from '../internal/svg-icons/ErrorOutline';
import InfoOutlinedIcon from '../internal/svg-icons/InfoOutlined';
import CloseIcon from '../internal/svg-icons/Close';

const useUtilityClasses = (ownerState) => {
  const { variant, color, severity, classes } = ownerState;

  const slots = {
    root: ['root', `${variant}${capitalize(color || severity)}`, `${variant}`],
    icon: ['icon'],
    message: ['message'],
    action: ['action'],
  };

  return composeClasses(slots, getAlertUtilityClass, classes);
};

const AlertRoot = styled(Paper, {
  name: 'MuiAlert',
  slot: 'Root',
  overridesResolver: (props, styles) => {
    const { ownerState } = props;

    return [
      styles.root,
      styles[ownerState.variant],
      styles[`${ownerState.variant}${capitalize(ownerState.color || ownerState.severity)}`],
    ];
  },
})(({ theme, ownerState }) => {
  const getColor = theme.palette.mode === 'light' ? darken : lighten;
  const getBackgroundColor = theme.palette.mode === 'light' ? lighten : darken;
  const color = ownerState.color || ownerState.severity;

  return {
    ...theme.typography.body2,
    backgroundColor: 'transparent',
    display: 'flex',
    padding: '6px 16px',
    ...(color &&
      ownerState.variant === 'standard' && {
        color: getColor(theme.palette[color].light, 0.6),
        backgroundColor: getBackgroundColor(theme.palette[color].light, 0.9),
        [`& .${alertClasses.icon}`]: {
          color:
            theme.palette.mode === 'dark' ? theme.palette[color].main : theme.palette[color].light,
        },
      }),
    ...(color &&
      ownerState.variant === 'outlined' && {
        color: getColor(theme.palette[color].light, 0.6),
        border: `1px solid ${theme.palette[color].light}`,
        [`& .${alertClasses.icon}`]: {
          color:
            theme.palette.mode === 'dark' ? theme.palette[color].main : theme.palette[color].light,
        },
      }),
    ...(color &&
      ownerState.variant === 'filled' && {
        color: theme.palette.getContrastText(
          theme.palette.mode === 'dark' ? theme.palette[color].dark : theme.palette[color].main,
        ),
        fontWeight: theme.typography.fontWeightMedium,
        backgroundColor:
          theme.palette.mode === 'dark' ? theme.palette[color].dark : theme.palette[color].main,
      }),
  };
});

const AlertIcon = styled('div', {
  name: 'MuiAlert',
  slot: 'Icon',
  overridesResolver: (props, styles) => styles.icon,
})({
  marginRight: 12,
  padding: '7px 0',
  display: 'flex',
  fontSize: 22,
  opacity: 0.9,
});

const AlertMessage = styled('div', {
  name: 'MuiAlert',
  slot: 'Message',
  overridesResolver: (props, styles) => styles.message,
})({
  padding: '8px 0',
  minWidth: 0,
  overflow: 'auto',
});

const AlertAction = styled('div', {
  name: 'MuiAlert',
  slot: 'Action',
  overridesResolver: (props, styles) => styles.action,
})({
  display: 'flex',
  alignItems: 'flex-start',
  padding: '4px 0 0 16px',
  marginLeft: 'auto',
  marginRight: -8,
});

const defaultIconMapping = {
  success: <SuccessOutlinedIcon fontSize="inherit" />,
  warning: <ReportProblemOutlinedIcon fontSize="inherit" />,
  error: <ErrorOutlineIcon fontSize="inherit" />,
  info: <InfoOutlinedIcon fontSize="inherit" />,
};

const Alert = React.forwardRef(function Alert(inProps, ref) {
  const props = useThemeProps({ props: inProps, name: 'MuiAlert' });
  const {
    action,
    children,
    className,
    closeText = 'Close',
    color,
    icon,
    iconMapping = defaultIconMapping,
    onClose,
    role = 'alert',
    severity = 'success',
    variant = 'standard',
    ...other
  } = props;

  const ownerState = {
    ...props,
    color,
    severity,
    variant,
  };

  const classes = useUtilityClasses(ownerState);

  return (
    <AlertRoot
      role={role}
      elevation={0}
      ownerState={ownerState}
      className={clsx(classes.root, className)}
      ref={ref}
      {...other}
    >
      {icon !== false ? (
        <AlertIcon ownerState={ownerState} className={classes.icon}>
          {icon || iconMapping[severity] || defaultIconMapping[severity]}
        </AlertIcon>
      ) : null}
      <AlertMessage ownerState={ownerState} className={classes.message}>
        {children}
      </AlertMessage>
      {action != null ? (
        <AlertAction ownerState={ownerState} className={classes.action}>
          {action}
        </AlertAction>
      ) : null}
      {action == null && onClose ? (
        <AlertAction ownerState={ownerState} className={classes.action}>
          <IconButton
            size="small"
            aria-label={closeText}
            title={closeText}
            color="inherit"
            onClick={onClose}
          >
            <CloseIcon fontSize="small" />
          </IconButton>
        </AlertAction>
      ) : null}
    </AlertRoot>
  );
});

Alert.propTypes /* remove-proptypes */ = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * The action to display. It renders after the message, at the end of the alert.
   */
  action: PropTypes.node,
  /**
   * The content of the component.
   */
  children: PropTypes.node,
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * Override the default label for the *close popup* icon button.
   *
   * For localization purposes, you can use the provided [translations](/material-ui/guides/localization/).
   * @default 'Close'
   */
  closeText: PropTypes.string,
  /**
   * The color of the component. Unless provided, the value is taken from the `severity` prop.
   * It supports both default and custom theme colors, which can be added as shown in the
   * [palette customization guide](https://mui.com/material-ui/customization/palette/#adding-new-colors).
   */
  color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
    PropTypes.oneOf(['error', 'info', 'success', 'warning']),
    PropTypes.string,
  ]),
  /**
   * Override the icon displayed before the children.
   * Unless provided, the icon is mapped to the value of the `severity` prop.
   * Set to `false` to remove the `icon`.
   */
  icon: PropTypes.node,
  /**
   * The component maps the `severity` prop to a range of different icons,
   * for instance success to `<SuccessOutlined>`.
   * If you wish to change this mapping, you can provide your own.
   * Alternatively, you can use the `icon` prop to override the icon displayed.
   */
  iconMapping: PropTypes.shape({
    error: PropTypes.node,
    info: PropTypes.node,
    success: PropTypes.node,
    warning: PropTypes.node,
  }),
  /**
   * Callback fired when the component requests to be closed.
   * When provided and no `action` prop is set, a close icon button is displayed that triggers the callback when clicked.
   * @param {React.SyntheticEvent} event The event source of the callback.
   */
  onClose: PropTypes.func,
  /**
   * The ARIA role attribute of the element.
   * @default 'alert'
   */
  role: PropTypes.string,
  /**
   * The severity of the alert. This defines the color and icon used.
   * @default 'success'
   */
  severity: PropTypes.oneOf(['error', 'info', 'success', 'warning']),
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),
    PropTypes.func,
    PropTypes.object,
  ]),
  /**
   * The variant to use.
   * @default 'standard'
   */
  variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
    PropTypes.oneOf(['filled', 'outlined', 'standard']),
    PropTypes.string,
  ]),
};

export default Alert;
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    'use strict';

    grunt.initConfig({
        pkg: grunt.file.readJSON( 'package.json' ),
        jshint: {
            all: [
                'bot.js',
                '*.botplug.js'
            ],
            options: {
                jshintrc: '.jshintrc'
            }
        }
    });

    grunt.loadNpmTasks( 'grunt-contrib-jshint' );

    grunt.registerTask( 'test', [ 'jshint' ] );
    grunt.registerTask( 'default', [ 'test' ] );
};
<commit_msg>Fix formatting in Gruntfile.js<commit_after>module.exports = function( grunt ) {
    'use strict';

    grunt.initConfig({
        pkg: grunt.file.readJSON( 'package.json' ),
        jshint: {
            all: [
                'bot.js',
                '*.botplug.js'
            ],
            options: {
                jshintrc: '.jshintrc'
            }
        }
    });

    grunt.loadNpmTasks( 'grunt-contrib-jshint' );

    grunt.registerTask( 'test', [ 'jshint' ] );
    grunt.registerTask( 'default', [ 'test' ] );
};
<|endoftext|>


<commit_before>var DHT = require('../')
var once = require('once')
var test = require('tape')

// TODO: Improve reliability by not using live network

test('Find nodes (Pride & Prejudice)', function (t) {
  t.plan(1)

  var hash = '1E69917FBAA2C767BCA463A96B5572785C6D8A12' // Pride & Prejudice
  var dht = new DHT(new Buffer(hash, 'hex'))
  dht.findPeers(300)

  dht.on('node', once(function (peer) {
    t.pass('Found at least one other DHT node')
    dht.close()
  }))

  // TODO
  // dht.on('peer', once(function (peer) {
  //   t.pass('Found at least one peer that has the file')
  // }))
})<commit_msg>one minute timeout<commit_after>var DHT = require('../')
var once = require('once')
var test = require('tape')

// TODO: Improve reliability by not using live network

test('Find nodes (Pride & Prejudice)', function (t) {
  t.plan(1)

  var hash = '1E69917FBAA2C767BCA463A96B5572785C6D8A12' // Pride & Prejudice
  var dht = new DHT(new Buffer(hash, 'hex'))
  dht.findPeers(300)

  dht.on('node', once(function (peer) {
    t.pass('Found at least one other DHT node')
    dht.close()
  }))

  // TODO
  // dht.on('peer', once(function (peer) {
  //   t.pass('Found at least one peer that has the file')
  // }))

  setTimeout(function () {
    t.end()
  }, 60000)
})<|endoftext|>


<commit_before>
goog.provide('bounce.start');

goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('goog.style');
goog.require('goog.async.Delay');
//goog.require('goog.ui.Button');
//goog.require('goog.ui.ButtonSide');
//goog.require('goog.ui.Component.EventType');
//goog.require('goog.ui.Component.State');
//goog.require('goog.ui.Menu');
//goog.require('goog.ui.MenuItem');
goog.require('goog.ui.Toolbar');
//goog.require('goog.ui.ToolbarRenderer');
goog.require('goog.ui.ToolbarButton');
goog.require('goog.ui.ToolbarMenuButton');

goog.require('bounce.Nodemcu.scan');

// Core Bockly.
goog.require('Blockly');
// Choose a language.
// goog.require('Blockly.Msg.en');

goog.require('Blockly.Block');
goog.require('Blockly.BlockSvg');
goog.require('Blockly.Blocks');
goog.require('Blockly.Bubble');
goog.require('Blockly.Comment');
goog.require('Blockly.Connection');
goog.require('Blockly.ConnectionDB');
goog.require('Blockly.ContextMenu');
goog.require('Blockly.Css');
goog.require('Blockly.Field');
goog.require('Blockly.FieldAngle');
goog.require('Blockly.FieldCheckbox');
goog.require('Blockly.FieldColour');
goog.require('Blockly.FieldDropdown');
goog.require('Blockly.FieldImage');
goog.require('Blockly.FieldLabel');
goog.require('Blockly.FieldTextInput');
goog.require('Blockly.FieldVariable');
goog.require('Blockly.Flyout');
goog.require('Blockly.Generator');
goog.require('Blockly.Icon');
goog.require('Blockly.Input');
goog.require('Blockly.Msg');
goog.require('Blockly.Mutator');
goog.require('Blockly.Names');
goog.require('Blockly.Procedures');
goog.require('Blockly.Scrollbar');
goog.require('Blockly.ScrollbarPair');
goog.require('Blockly.Toolbox');
goog.require('Blockly.Tooltip');
goog.require('Blockly.Trashcan');
goog.require('Blockly.Variables');
goog.require('Blockly.Warning');
goog.require('Blockly.WidgetDiv');
goog.require('Blockly.Workspace');
goog.require('Blockly.WorkspaceSvg');
goog.require('Blockly.Xml');
goog.require('Blockly.ZoomControls');
goog.require('Blockly.inject');
goog.require('Blockly.utils');

var workspace;

//function changed() {
//    console.log("Workspace changed");
//    if (is_preparing) {
//        is_preparing = false;
//    } else {
//        blocklyLua.notifyDocumentChanged();
//    }
//}
var data_from_file;

var OutputConsole = function (output_element) {
    this.write = function(data) {
        var safe_data = goog.string.htmlEscape(data);
        safe_data = goog.string.newLineToBr(safe_data);
        output_element.append(output_element, safe_data);
    };

    this.writeLine = function(line) {
        this.write(line + '\n')
    };

    this.writeLine('Console initialised');
};

var mcu_console;

function prepare_blockly_workspace() {
    var blocklyArea = document.getElementById('blocklyArea');
    var blocklyDiv = document.getElementById('blocklyDiv');
    workspace = Blockly.inject(blocklyDiv,
      {toolbox: goog.dom.$('toolbox'), media: "blockly-nodemcu/media/" });
    var onresize = function(e) {
        // Compute the absolute coordinates and dimensions of blocklyArea.
        var element = blocklyArea;
        var x = 0;
        var y = 0;
        do {
          x += element.offsetLeft;
          y += element.offsetTop;
          element = element.offsetParent;
        } while (element);
        // Position blocklyDiv over blocklyArea.
        blocklyDiv.style.left = x + 'px';
        blocklyDiv.style.top = y + 'px';
        blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
        blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
    };
    window.addEventListener('resize', onresize, false);
    onresize();
}

$(function () {
    prepare_blockly_workspace();
    //workspace.addChangeListener(changed);

    mcu_console = new OutputConsole($('#output'));
    var ui = new BounceUI();
});

/**
 * Send the code directly to the mcu repl.
 * @param mcu
 */
function run(mcu) {
    var code = Blockly.Lua.workspaceToCode(workspace);
    // make a work list of lines..
    var lines = code.split("\n");
    var current_line = 0;
    var last_timer;
    // Send each one, with the sent callback priming the next.
    function _send_next() {
        if (current_line < lines.length) {
            mcu.send_data(lines[current_line++] + "\n", function() {
                // Calling send next, but not immediately.
                // First - so node has time to respond.
                // Second - to prevent very large stack recursion.
                new goog.async.Delay(_send_next, 100).start();
            });
        }
    }

    _send_next();
}

function export_document() {
    var xml = Blockly.Xml.workspaceToDom(workspace);

    var xml_text = Blockly.Xml.domToPrettyText(xml);
    return xml_text;
}
var is_preparing = false;

function load_document(text) {
    is_preparing = true;
    var xml = Blockly.Xml.textToDom(text);
    Blockly.Xml.domToWorkspace(workspace, xml);
}

function new_document() {
    is_preparing = true;
    Blockly.mainWorkspace.clear();
}

/**
 * Open a file from the filesystem. Load into blockly workspace.
 *
 * @private
 */
function _open_file() {
    var accepts = [{
        mimeTypes: ['text/*'],
        extensions: ['xml', 'node']
    }];
    // Show a file open
    chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(theEntry) {
        if (!theEntry) {
            mcu_console.writeLine('No file selected.');
            return;
        }
        // On ok
        // use local storage to retain access to this file
        //chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
        // Inject that code.
        console.log("turning entry into file");
        theEntry.file(function(file) {
            console.log("opening file");
            var reader = new FileReader();
            reader.onloadend = function(e) {
                new_document();
                load_document(e.target.result);
            };
            reader.readAsText(file);
        });
    });
}

function BounceUI() {
    var toolbar, runButton, stopButton;
    var currentMcu;
    var connectMenu;

    toolbar = new goog.ui.Toolbar();
    toolbar.decorate(goog.dom.getElement('toolbar'));
    connectMenu = new goog.ui.Menu();
    connectMenu.decorate(goog.dom.getElement('connect_menu'));

    goog.events.listen(goog.dom.getElement("run_button"),
        goog.events.EventType.CLICK,
        function(e) {
            run(currentMcu);
    });

    goog.events.listen(goog.dom.getElement("open_button"),
        goog.events.EventType.CLICK,
        _open_file
    );

    // Callback to add found items to the menu.
    var found_item = function(mcu) {
        mcu_console.writeLine('Adding found item...');
        var connectItem = new goog.ui.MenuItem(mcu.port);
        connectItem.setCheckable(true);
        connectMenu.addItem(connectItem);
        goog.events.listen(connectItem.getContentElement(),
            goog.events.EventType.CLICK,
            function(e) {
                _connect_menu_item_clicked(connectItem, mcu);
            }
        );
    };

    // When the scanButton is clicked, scan for mcu's to add.
    goog.events.listen(goog.dom.getElement("scan_button"),
        goog.events.EventType.CLICK,
        function(e) {
            bounce.Nodemcu.scan(mcu_console, found_item);
    });

    /**
     *
     * @param connectItem Menu item that was clicked
     * @param mcu The associated NodeMCU device
     * @private
     */
    function _connect_menu_item_clicked(connectItem, mcu) {
        mcu.connect(function() {
            // We've now connected the mcu. Update the UI
            mcu_console.writeLine("Connected");
            currentMcu = mcu;
            // Add a tick (Check) to the connection menu item
            connectItem.setChecked(true);
            // disconnect any others
            // Enable the run menu
            runButton.setEnabled(true);
            stopButton.setEnabled(true);
        });
    }
}
<commit_msg>Fix maximise/restore button issue<commit_after>
goog.provide('bounce.start');

goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('goog.style');
goog.require('goog.async.Delay');
//goog.require('goog.ui.Button');
//goog.require('goog.ui.ButtonSide');
//goog.require('goog.ui.Component.EventType');
//goog.require('goog.ui.Component.State');
//goog.require('goog.ui.Menu');
//goog.require('goog.ui.MenuItem');
goog.require('goog.ui.Toolbar');
//goog.require('goog.ui.ToolbarRenderer');
goog.require('goog.ui.ToolbarButton');
goog.require('goog.ui.ToolbarMenuButton');

goog.require('bounce.Nodemcu.scan');

// Core Bockly.
goog.require('Blockly');
// Choose a language.
// goog.require('Blockly.Msg.en');

goog.require('Blockly.Block');
goog.require('Blockly.BlockSvg');
goog.require('Blockly.Blocks');
goog.require('Blockly.Bubble');
goog.require('Blockly.Comment');
goog.require('Blockly.Connection');
goog.require('Blockly.ConnectionDB');
goog.require('Blockly.ContextMenu');
goog.require('Blockly.Css');
goog.require('Blockly.Field');
goog.require('Blockly.FieldAngle');
goog.require('Blockly.FieldCheckbox');
goog.require('Blockly.FieldColour');
goog.require('Blockly.FieldDropdown');
goog.require('Blockly.FieldImage');
goog.require('Blockly.FieldLabel');
goog.require('Blockly.FieldTextInput');
goog.require('Blockly.FieldVariable');
goog.require('Blockly.Flyout');
goog.require('Blockly.Generator');
goog.require('Blockly.Icon');
goog.require('Blockly.Input');
goog.require('Blockly.Msg');
goog.require('Blockly.Mutator');
goog.require('Blockly.Names');
goog.require('Blockly.Procedures');
goog.require('Blockly.Scrollbar');
goog.require('Blockly.ScrollbarPair');
goog.require('Blockly.Toolbox');
goog.require('Blockly.Tooltip');
goog.require('Blockly.Trashcan');
goog.require('Blockly.Variables');
goog.require('Blockly.Warning');
goog.require('Blockly.WidgetDiv');
goog.require('Blockly.Workspace');
goog.require('Blockly.WorkspaceSvg');
goog.require('Blockly.Xml');
goog.require('Blockly.ZoomControls');
goog.require('Blockly.inject');
goog.require('Blockly.utils');

var workspace;

//function changed() {
//    console.log("Workspace changed");
//    if (is_preparing) {
//        is_preparing = false;
//    } else {
//        blocklyLua.notifyDocumentChanged();
//    }
//}
var data_from_file;

var OutputConsole = function (output_element) {
    this.write = function(data) {
        var safe_data = goog.string.htmlEscape(data);
        safe_data = goog.string.newLineToBr(safe_data);
        output_element.append(output_element, safe_data);
    };

    this.writeLine = function(line) {
        this.write(line + '\n')
    };

    this.writeLine('Console initialised');
};

var mcu_console;

function prepare_blockly_workspace() {
    var blocklyArea = document.getElementById('blocklyArea');
    var blocklyDiv = document.getElementById('blocklyDiv');
    workspace = Blockly.inject(blocklyDiv,
      {toolbox: goog.dom.$('toolbox'), media: "blockly-nodemcu/media/" });
    var onresize = function(e) {
        // Compute the absolute coordinates and dimensions of blocklyArea.
        var element = blocklyArea;
        var x = 0;
        var y = 0;
        do {
          x += element.offsetLeft;
          y += element.offsetTop;
          element = element.offsetParent;
        } while (element);
        // Position blocklyDiv over blocklyArea.
        blocklyDiv.style.left = x + 'px';
        blocklyDiv.style.top = y + 'px';
        blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
        blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
        Blockly.svgResize(workspace);
    };
    window.addEventListener('resize', onresize, false);
    onresize();
}

$(function () {
    prepare_blockly_workspace();
    //workspace.addChangeListener(changed);

    mcu_console = new OutputConsole($('#output'));
    var ui = new BounceUI();
});

/**
 * Send the code directly to the mcu repl.
 * @param mcu
 */
function run(mcu) {
    var code = Blockly.Lua.workspaceToCode(workspace);
    // make a work list of lines..
    var lines = code.split("\n");
    var current_line = 0;
    var last_timer;
    // Send each one, with the sent callback priming the next.
    function _send_next() {
        if (current_line < lines.length) {
            mcu.send_data(lines[current_line++] + "\n", function() {
                // Calling send next, but not immediately.
                // First - so node has time to respond.
                // Second - to prevent very large stack recursion.
                new goog.async.Delay(_send_next, 100).start();
            });
        }
    }

    _send_next();
}

function export_document() {
    var xml = Blockly.Xml.workspaceToDom(workspace);

    var xml_text = Blockly.Xml.domToPrettyText(xml);
    return xml_text;
}
var is_preparing = false;

function load_document(text) {
    is_preparing = true;
    var xml = Blockly.Xml.textToDom(text);
    Blockly.Xml.domToWorkspace(workspace, xml);
}

function new_document() {
    is_preparing = true;
    Blockly.mainWorkspace.clear();
}

/**
 * Open a file from the filesystem. Load into blockly workspace.
 *
 * @private
 */
function _open_file() {
    var accepts = [{
        mimeTypes: ['text/*'],
        extensions: ['xml', 'node']
    }];
    // Show a file open
    chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(theEntry) {
        if (!theEntry) {
            mcu_console.writeLine('No file selected.');
            return;
        }
        // On ok
        // use local storage to retain access to this file
        //chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
        // Inject that code.
        console.log("turning entry into file");
        theEntry.file(function(file) {
            console.log("opening file");
            var reader = new FileReader();
            reader.onloadend = function(e) {
                new_document();
                load_document(e.target.result);
            };
            reader.readAsText(file);
        });
    });
}

function BounceUI() {
    var toolbar, runButton, stopButton;
    var currentMcu;
    var connectMenu;

    toolbar = new goog.ui.Toolbar();
    toolbar.decorate(goog.dom.getElement('toolbar'));
    connectMenu = new goog.ui.Menu();
    connectMenu.decorate(goog.dom.getElement('connect_menu'));

    goog.events.listen(goog.dom.getElement("run_button"),
        goog.events.EventType.CLICK,
        function(e) {
            run(currentMcu);
    });

    goog.events.listen(goog.dom.getElement("open_button"),
        goog.events.EventType.CLICK,
        _open_file
    );

    // Callback to add found items to the menu.
    var found_item = function(mcu) {
        mcu_console.writeLine('Adding found item...');
        var connectItem = new goog.ui.MenuItem(mcu.port);
        connectItem.setCheckable(true);
        connectMenu.addItem(connectItem);
        goog.events.listen(connectItem.getContentElement(),
            goog.events.EventType.CLICK,
            function(e) {
                _connect_menu_item_clicked(connectItem, mcu);
            }
        );
    };

    // When the scanButton is clicked, scan for mcu's to add.
    goog.events.listen(goog.dom.getElement("scan_button"),
        goog.events.EventType.CLICK,
        function(e) {
            bounce.Nodemcu.scan(mcu_console, found_item);
    });

    /**
     *
     * @param connectItem Menu item that was clicked
     * @param mcu The associated NodeMCU device
     * @private
     */
    function _connect_menu_item_clicked(connectItem, mcu) {
        mcu.connect(function() {
            // We've now connected the mcu. Update the UI
            mcu_console.writeLine("Connected");
            currentMcu = mcu;
            // Add a tick (Check) to the connection menu item
            connectItem.setChecked(true);
            // disconnect any others
            // Enable the run menu
            runButton.setEnabled(true);
            stopButton.setEnabled(true);
        });
    }
}
<|endoftext|>


<commit_before>//  gruntfile.js
//
// Author: blinklv <blinklv@icloud.com>
// Create Time: 2017-03-22
// Maintainer: blinklv <blinklv@icloud.com>
// Last Change: 2018-06-08
//
// The gruntfile.js for my Web development.  Many settings are personalized for me, but
// how it works I will explain in README.md file.  So If you like it, you can copy this
// file (grunfile.js) and package.json file to your project. I left many tips in comments,
// which can help me to configure this file :)

module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        // Project metadata is imported into the Grunt config from the project's package.json.
        pkg: grunt.file.readJSON("package.json"),

        // Configure task-named properties. When a task is run, Grunt looks for
        // its configuration under a property of the same name.
        // NOTE: This anonymous object may contain any arbitrary data. As long as
        // properties don't conflict with properties the tasks require, they will
        // be otherwise ignored.

        copy: {
            // Multi-tasks can hae multiple configurations. The copy task
            // has devel and release targets. Specifying both a task and
            // target like 'grunt copy:devel' or 'grunt copy:release' will
            // process just the specified target's configuration, while
            // running 'grunt copy' will iterate over all targets.
            devel: {
                // Copy files from the working directory and its subdirectory to build/devel
                // directory. (build is a subdirectory of your working directory)
                src: [
                    "index.html", "html/**/*.html",
                    "css/**/*.{css,css.map}", "!css/**/*.min.css",
                    "js/**/*.js", "!js/**/*.min.js",
                    "font/**/*.{woff,woff2,eot,ttf,otf,svg}",
                    // For bitmap, we need to resize and compress them. But for vector
                    // images, we copy them to the destination directory directly.
                    "img/**/*.svg",

                    // Because the vendor directory contains third party resources. It's
                    // hard to control their content, so the current strategy is copying
                    // almost all files (except for some compress files) to the dest.
                    "vendor/**", "!vendor/**/*.min.*"
                ],
                dest: "build/devel/"
            },
            release: {
            }
        },

        // Compile Pug to HTML.
        pug: {
            devel: {
                options: {
                    // Output indented HTML. It's easier to debug. We don't concern about
                    // how many spaces it takes up, because the htmlmin task will reduce
                    // its size in the release version.
                    pretty: true
                },
                files: [{
                    expand: true,
                    src: "index.pug",
                    dest: "build/devel/",
                    ext: ".html",
                    extDot: "last"
                },{
                    expand: true,
                    cwd: "pug/",
                    src: "**/*.pug",
                    dest: "build/devel/html/",
                    ext: ".html",
                    extDot: "last"
                }]
            }
        },

        // Compile Sass to CSS.
        sass: {
            devel: {
                options: {
                  // Output style: expanded is a more typical human-made CSS style, with each
                  // property and rule taking up one line. Although this style takes up many
                  // spaces, it's easier to debug and the cssmin task will reduce its size
                  // in the release version.
                  style: "expanded"
                },
                expand: true,
                cwd: "sass/",
                src: "**/*.{sass,scss}",
                dest: "build/devel/css/",

                // Replace any existing extension with '.css' in generated path.
                ext: ".css",

                // Used to indicate where the period indicating the extension is located.
                // 'last' means the exntension begins after the last period.
                extDot: "last"
            }
        },

        // Sometimes, the css files of the vendor directory contain some external
        // relative url references. But they are based on their specific package
        // directory instead of your custom root directory. We will use the uncss to
        // remove unused CSS and generate a single css file (main.css); it will be
        // placed in a different directory (build/devel/css/). However, the relative
        // url references in the main.css are based on the original root path; it's not
        // correct. The following task will replace any original relative url with
        // a new one based on the root path, which gurantees finding resources correctly.
        css_relative_url_replace: {
            devel: {
                options: {
                    staticRoot: "build/devel/"
                },
                expand: true,
                cwd: "build/devel/vendor/",
                src: "**/*.css",
                // The conventional example doesn't satisfy my need, which combines multiple
                // source files and generate a signle target file. But I want to one
                // target file corresponds one source file. It doesn't be permitted if
                // I only set the dest field to a directory, but can work when I add
                // the following rename function :)
                dest: "build/devel/vendor/",
                rename: function(dest, src) {
                    return dest + src;
                }
            }
        },

        // Remove unused CSS and generate a main.css file.
        uncss: {
            devel: {
                files: {
                    "build/devel/css/main.css": ["build/devel/index.html", "build/devel/html/**/*.html"]
                }
            }
        },

        concat: {
            // Concate all JS files of build/devel/js/ directory and its subdirectories
            // and generate a main.js file.
            devel: {
                src: "build/devel/js/**/*.js",
                dest: "build/devel/js/main.js"
            }
        },

        responsive_images: {
            devel: {
                // An options property may be specified to override built-in defaults.
                // In addition, each target may have an options property which is specific
                // to that target. Target-level options will override task-level options.
                options: {
                    // Chooses which graphics engine to use when resizing images. To use
                    // GraphicsMagick, set this to 'gm'. To use ImageMagick, set this to
                    // 'im'.
                    engine: "im",

                    // Only process files that do not already exist in the destination directory.
                    newFilesOnly: true,

                    // An array of objects containing the sizes and settings we want to resize
                    // our image to.
                    sizes: [{
                        // If a name is specified, then the file will be suffixed with this name.
                        // eg: my-image-s.jpg, your-image-xl.png.
                        name: "s",
                        width: 320,

                        // JPEG format only. The quality of the image, 100 being the highest
                        // quality and 1 being the lowest.
                        quality: 70
                    },{
                        name: "m",
                        width: 480,
                        quality: 70
                    },{
                        name: "l",
                        width: 720,
                        quality: 70
                    },{
                        name: "xl",
                        width: 1024,
                        quality: 70
                    },{
                        name: "xxl",
                        width: 1440,
                        quality: 70
                    }]
                },

                // Handle all specified format images in the 'img/' subdirectory and all
                // of its subdirectories. Move the results to 'build/devel/img/' dir.
                expand: true,
                src: "img/**/*.{jpg,jpeg,png,gif,webp}",
                dest: "build/devel/"
            }
        },

        // Flag suspicious usage in programs written in JavaScript.
        jshint: {
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                globals: {
                    jQuery: true
                },
            },
            target: ["gruntfile.js", "js/**/*.js"]
        },

        // Minifying HTML files.
        htmlmin: {
            release: {
                options: {
                    removeComments: true, // Strip HTML comments.

                    // Collapse white space that contributes to text nodes in a document tree.
                    collapseWhitespace: true,

                    // Omit attribute values from boolean attributes.
                    collapseBooleanAttributes: true
                },
                expand: true,
                cwd: "build/devel/",
                src: ["index.html", "html/**/*.html"],
                dest: "build/release/"
            }
        },

        // Minifying CSS files.
        cssmin: {
            release: {
                // In fact, there is only one CSS file (main.css) we need to minify.
                src: "build/devel/css/main.css",
                dest: "build/release/css/main.min.css"
            }
        },

        // Minifying JS files.
        uglify: {
            options: {
                mangle: false,
                compress: {
                    // Discard calls to console.* functions.
                    drop_console: true
                }
            },
            release: {
                expand: true,
                cwd: "build/devel/js/",
                src: "**/*.js",
                dest: "build/release/js/",
                ext: ".min.js",
                extDot: "last"
            }
        }
    });

    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-copy");
    grunt.loadNpmTasks("grunt-responsive-images");
    grunt.loadNpmTasks("grunt-contrib-pug");
    grunt.loadNpmTasks("grunt-contrib-sass");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-uncss");
    grunt.loadNpmTasks("grunt-contrib-htmlmin");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-css-relative-url-replace");
};

<commit_msg>Add copy:release and devel and release task.<commit_after>//  gruntfile.js
//
// Author: blinklv <blinklv@icloud.com>
// Create Time: 2017-03-22
// Maintainer: blinklv <blinklv@icloud.com>
// Last Change: 2018-06-11
//
// The gruntfile.js for my Web development.  Many settings are personalized for me, but
// how it works I will explain in README.md file.  So If you like it, you can copy this
// file (grunfile.js) and package.json file to your project. I left many tips in comments,
// which can help me to configure this file :)

module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        // Project metadata is imported into the Grunt config from the project's package.json.
        pkg: grunt.file.readJSON("package.json"),

        // Configure task-named properties. When a task is run, Grunt looks for
        // its configuration under a property of the same name.
        // NOTE: This anonymous object may contain any arbitrary data. As long as
        // properties don't conflict with properties the tasks require, they will
        // be otherwise ignored.

        copy: {
            // Multi-tasks can hae multiple configurations. The copy task
            // has devel and release targets. Specifying both a task and
            // target like 'grunt copy:devel' or 'grunt copy:release' will
            // process just the specified target's configuration, while
            // running 'grunt copy' will iterate over all targets.
            devel: {
                // Copy files from the working directory and its subdirectory to build/devel
                // directory. (build is a subdirectory of your working directory)
                src: [
                    "index.html", "html/**/*.html",
                    "css/**/*.{css,css.map}", "!css/**/*.min.css",
                    "js/**/*.js", "!js/**/*.min.js",
                    "font/**/*.{woff,woff2,eot,ttf,otf,svg}",
                    // For bitmap, we need to resize and compress them. But for vector
                    // images, we copy them to the destination directory directly.
                    "img/**/*.svg",

                    // Because the vendor directory contains third party resources. It's
                    // hard to control their content, so the current strategy is copying
                    // almost all files (except for some compress files) to the dest.
                    "vendor/**", "!vendor/**/*.min.*"
                ],
                dest: "build/devel/"
            },
            release: {
                expand: true,
                cwd: "build/devel/",
                src: [
                    // HTML, CSS and JS files are handled by other tasks; we only
                    // need to copy some auxiliary resources.
                    "vendor/**", "!vendor/**/*.js", "!vendor/**/*.css",
                    "img/**", "font/**"

                ],
                dest: "build/release/"
            }
        },

        // Compile Pug to HTML.
        pug: {
            devel: {
                options: {
                    // Output indented HTML. It's easier to debug. We don't concern about
                    // how many spaces it takes up, because the htmlmin task will reduce
                    // its size in the release version.
                    pretty: true
                },
                files: [{
                    expand: true,
                    src: "index.pug",
                    dest: "build/devel/",
                    ext: ".html",
                    extDot: "last"
                },{
                    expand: true,
                    cwd: "pug/",
                    src: "**/*.pug",
                    dest: "build/devel/html/",
                    ext: ".html",
                    extDot: "last"
                }]
            }
        },

        // Compile Sass to CSS.
        sass: {
            devel: {
                options: {
                  // Output style: expanded is a more typical human-made CSS style, with each
                  // property and rule taking up one line. Although this style takes up many
                  // spaces, it's easier to debug and the cssmin task will reduce its size
                  // in the release version.
                  style: "expanded"
                },
                expand: true,
                cwd: "sass/",
                src: "**/*.{sass,scss}",
                dest: "build/devel/css/",

                // Replace any existing extension with '.css' in generated path.
                ext: ".css",

                // Used to indicate where the period indicating the extension is located.
                // 'last' means the exntension begins after the last period.
                extDot: "last"
            }
        },

        // Sometimes, the css files of the vendor directory contain some external
        // relative url references. But they are based on their specific package
        // directory instead of your custom root directory. We will use the uncss to
        // remove unused CSS and generate a single css file (main.css); it will be
        // placed in a different directory (build/devel/css/). However, the relative
        // url references in the main.css are based on the original root path; it's not
        // correct. The following task will replace any original relative url with
        // a new one based on the root path, which gurantees finding resources correctly.
        css_relative_url_replace: {
            devel: {
                options: {
                    staticRoot: "build/devel/"
                },
                expand: true,
                cwd: "build/devel/vendor/",
                src: "**/*.css",
                // The conventional example doesn't satisfy my need, which combines multiple
                // source files and generate a signle target file. But I want to one
                // target file corresponds one source file. It doesn't be permitted if
                // I only set the dest field to a directory, but can work when I add
                // the following rename function :)
                dest: "build/devel/vendor/",
                rename: function(dest, src) {
                    return dest + src;
                }
            }
        },

        // Remove unused CSS and generate a main.css file.
        uncss: {
            release: {
                files: {
                    "build/devel/css/main.css": ["build/devel/index.html", "build/devel/html/**/*.html"]
                }
            }
        },

        concat: {
            // Concate all JS files of build/devel/js/ directory and its subdirectories
            // and generate a main.js file.
            release: {
                src: "build/devel/js/**/*.js",
                dest: "build/devel/js/main.js"
            }
        },

        responsive_images: {
            devel: {
                // An options property may be specified to override built-in defaults.
                // In addition, each target may have an options property which is specific
                // to that target. Target-level options will override task-level options.
                options: {
                    // Chooses which graphics engine to use when resizing images. To use
                    // GraphicsMagick, set this to 'gm'. To use ImageMagick, set this to
                    // 'im'.
                    engine: "im",

                    // Only process files that do not already exist in the destination directory.
                    newFilesOnly: true,

                    // An array of objects containing the sizes and settings we want to resize
                    // our image to.
                    sizes: [{
                        // If a name is specified, then the file will be suffixed with this name.
                        // eg: my-image-s.jpg, your-image-xl.png.
                        name: "s",
                        width: 320,

                        // JPEG format only. The quality of the image, 100 being the highest
                        // quality and 1 being the lowest.
                        quality: 70
                    },{
                        name: "m",
                        width: 480,
                        quality: 70
                    },{
                        name: "l",
                        width: 720,
                        quality: 70
                    },{
                        name: "xl",
                        width: 1024,
                        quality: 70
                    },{
                        name: "xxl",
                        width: 1440,
                        quality: 70
                    }]
                },

                // Handle all specified format images in the 'img/' subdirectory and all
                // of its subdirectories. Move the results to 'build/devel/img/' dir.
                expand: true,
                src: "img/**/*.{jpg,jpeg,png,gif,webp}",
                dest: "build/devel/"
            }
        },

        // Flag suspicious usage in programs written in JavaScript.
        jshint: {
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                globals: {
                    jQuery: true
                },
            },
            target: ["gruntfile.js", "js/**/*.js"]
        },

        // Minifying HTML files.
        htmlmin: {
            release: {
                options: {
                    removeComments: true, // Strip HTML comments.

                    // Collapse white space that contributes to text nodes in a document tree.
                    collapseWhitespace: true,

                    // Omit attribute values from boolean attributes.
                    collapseBooleanAttributes: true
                },
                expand: true,
                cwd: "build/devel/",
                src: ["index.html", "html/**/*.html"],
                dest: "build/release/"
            }
        },

        // Minifying CSS files.
        cssmin: {
            release: {
                // In fact, there is only one CSS file (main.css) we need to minify.
                src: "build/devel/css/main.css",
                dest: "build/release/css/main.min.css"
            }
        },

        // Minifying JS files.
        uglify: {
            options: {
                mangle: false,
                compress: {
                    // Discard calls to console.* functions.
                    drop_console: true
                }
            },
            release: {
                files: [{
                    // In the build/devel/js directory, the only one JS file we need to
                    // minimize is the main.js file, which is generated by concat:devel
                    // task.
                    src: "build/devel/js/main.js",
                    dest: "build/release/js/main.min.js"
                },{
                    expand: true,
                    cwd: "build/devel/vendor/",
                    // We don't need to filter JS files ending with '.min.js'. Because
                    // they have already been skipped in copy:devel task.
                    src: "**/*.js",
                    dest: "build/release/vendor/",
                    ext: ".min.js",
                    extDot: "last"
                }]
            }
        }
    });

    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-copy");
    grunt.loadNpmTasks("grunt-responsive-images");
    grunt.loadNpmTasks("grunt-contrib-pug");
    grunt.loadNpmTasks("grunt-contrib-sass");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-uncss");
    grunt.loadNpmTasks("grunt-contrib-htmlmin");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-css-relative-url-replace");

    grunt.registerTask("devel", ["pug", "sass", "jshint", "responsive_images", "copy:devel"]);
    grunt.registerTask("release", ["devel", "htmlmin", "uncss", "cssmin", "concat", "uglify", "copy:release"]);
};

<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var elastic = require('elasticsearch');

module.exports = function(grunt) {
  grunt.registerMultiTask("elasticsearchbulk", "Grunt task for working with the elasticsearch bulk api", function() {
    var done = this.async();
    var options = this.options();
    var files = this.filesSrc;

   	var defaults = {
   		elastic : {
	    host: 'http://127.0.0.1:9200',
	    client: {
	      apiVersion: "1.0",
	      log: "warning"
	    }
	  }
	};

	var options = _.extend(defaults, options);
	var client = new elastic.Client(options);

  	files.forEach(function(file){
  		grunt.log.ok('starting elastic search bulk for ', file);

    	var data = grunt.file.readJSON(file);

    	client.bulk({ body: data }, function(err){
    		if (err) {
      			grunt.fail.warn('Unable to connect to elastic search');
    		}

			if (!err) {
				grunt.log.ok('elastic search bulk run complete.');
			}

			done();
		});
  	});
  });
};<commit_msg>fixing issue with importer exiting to early when multiple files<commit_after>'use strict';

var _ = require('lodash');
var elastic = require('elasticsearch');

module.exports = function(grunt) {
  grunt.registerMultiTask("elasticsearchbulk", "Grunt task for working with the elasticsearch bulk api", function() {
    var done = this.async();
    var options = this.options();
    var files = this.filesSrc;

   	var defaults = {
   		elastic : {
	    host: 'http://127.0.0.1:9200',
	    client: {
	      apiVersion: "1.0",
	      log: "warning"
	    }
	  }
	};

	var options = _.extend(defaults, options);
	var client = new elastic.Client(options);

  	files.forEach(function(file){
  		grunt.log.ok('starting elastic search bulk for ', file);

    	var data = grunt.file.readJSON(file);

    	client.bulk({ body: data }, function(err){
    		if (err) {
      			grunt.fail.warn('Unable to connect to elastic search');
    		}

			if (!err) {
				grunt.log.ok('elastic search bulk run complete.');
			}
		});
  	});

  	done();
  });
};<|endoftext|>


<commit_before>// @flow

import os from 'os'
import pMap from 'p-map'
import pReduce from 'p-reduce'
import flatten from 'lodash/flatten'
import promiseDefer from 'promise.defer'
import {
  Job,
  PundleError,
  getChunk,
  getFileImportHash,
  type Chunk,
  type ImportResolved,
  type ImportRequest,
  type ComponentFileResolverResult,
  type WorkerProcessResult,
} from 'pundle-api'
import type { Config } from 'pundle-core-load-config'

import { getOutputPath } from './helpers'
import WorkerDelegate from '../worker/delegate'
import type { RunOptions } from '../types'

// TODO: Locks for files and chunks
export default class Master {
  config: Config
  options: RunOptions
  resolverWorker: WorkerDelegate
  processorWorkers: Array<WorkerDelegate>
  queue: Array<{| payload: {}, resolve: Function, reject: Function |}>

  constructor(config: Config, options: RunOptions) {
    this.config = config
    this.options = options
    this.queue = []

    this.resolverWorker = new WorkerDelegate('resolver', options)
    this.processorWorkers = os.cpus().map(() => new WorkerDelegate('processor', options))

    this.getAllWorkers().forEach(worker => {
      worker.setMaster(this)
    })
  }
  getAllWorkers(): Array<WorkerDelegate> {
    return [this.resolverWorker].concat(this.processorWorkers)
  }
  async spawnWorkers() {
    try {
      await Promise.all(
        this.getAllWorkers().map(async worker => {
          if (worker.isAlive()) return
          try {
            await worker.spawn()
          } catch (error) {
            worker.dispose()
            throw error
          }
        }),
      )
    } catch (error) {
      throw new PundleError('DAEMON', 'WORKER_CRASHED', null, null, `Worker crashed during initial spawn: ${error.message}`)
    }
  }
  dispose() {
    this.getAllWorkers().forEach(function(worker) {
      worker.dispose()
    })
  }
  report(issue: $FlowFixMe) {
    console.log('issue reported to master', issue)
  }

  async execute(): Promise<void> {
    const job = new Job()
    const entries = await Promise.all(
      this.config.entry.map(entry =>
        this.resolve({
          request: entry,
          requestRoot: this.config.rootDirectory,
          ignoredResolvers: [],
        }),
      ),
    )
    await pMap(entries, entry => this.processChunk(getChunk(entry.format, null, entry.resolved), job))
    const generated = await this.generate(job)

    // TODO: Maybe do something else?
    return generated
  }
  async generate(
    givenJob: Job,
  ): Promise<Array<{ id: string, filePath: string | false, format: string, contents: string | Buffer }>> {
    let job = givenJob.clone()
    const jobTransformers = this.config.components.filter(c => c.type === 'job-transformer')

    job = await pReduce(
      jobTransformers,
      async (value, component) => {
        const result = await component.callback(value)
        // TODO: Validation
        return result || value
      },
      job,
    )

    const chunkGenerators = this.config.components.filter(c => c.type === 'chunk-generator')
    if (!chunkGenerators.length) {
      throw new Error('No chunk-generator components configured')
    }

    const generated = await pMap(job.chunks.values(), async chunk => {
      for (let i = 0, { length } = chunkGenerators; i < length; i++) {
        const generator = chunkGenerators[i]
        const result = await generator.callback(chunk, job, {
          getOutputPath: (output: { id: string, entry: ?string, format: string }) => getOutputPath(this.config, output),
        })
        if (result) {
          return result.map(item => ({ ...item, id: chunk.id, filePath: getOutputPath(this.config, chunk) }))
        }
      }
      throw new Error(
        `All generators refused to generate chunk of format '${chunk.format}' with label '${chunk.label}' and entry '${
          chunk.entry
        }'`,
      )
    })

    return flatten(generated)
  }
  async processChunk(chunk: Chunk, job: Job): Promise<void> {
    const { entry } = chunk
    if (!entry) {
      // TODO: Return silently instead?
      throw new Error('Cannot process chunk without entry')
    }
    if (job.locks.has(chunk.id)) return
    if (job.chunks.has(chunk.id)) return

    job.locks.add(chunk.id)
    try {
      job.chunks.set(chunk.id, chunk)

      await this.processFileTree(
        {
          format: 'js',
          filePath: entry,
        },
        false,
        job,
      )
    } catch (error) {
      job.chunks.delete(chunk.id)
      throw error
    } finally {
      job.locks.delete(chunk.id)
    }
  }
  // TODO: Use cached old files here if present on the job?
  async processFileTree(request: ImportResolved, forcedOverwrite: boolean, job: Job): Promise<void> {
    const lockKey = getFileImportHash(request.filePath, request.format)
    const oldFile = job.files.get(lockKey)
    if (job.locks.has(lockKey)) {
      return
    }
    if (oldFile && !forcedOverwrite) {
      return
    }
    job.locks.add(lockKey)

    try {
      const newFile = await this.queuedProcess(request)
      job.files.set(newFile.id, newFile)
      await Promise.all([
        pMap(newFile.imports, fileImport => this.processFileTree(fileImport, false, job)),
        pMap(newFile.chunks, fileChunk => this.processChunk(fileChunk, job)),
      ])
    } catch (error) {
      if (oldFile) {
        job.files.set(lockKey, oldFile)
      } else {
        job.files.delete(lockKey)
      }
      throw error
    } finally {
      job.locks.delete(lockKey)
    }
  }
  async resolve(request: ImportRequest): Promise<ComponentFileResolverResult> {
    return this.resolverWorker.send('resolve', request)
  }
  async queuedProcess(payload: ImportResolved): Promise<WorkerProcessResult> {
    const currentWorker = this.processorWorkers.find(worker => worker.isWorking === 0)
    if (currentWorker) {
      return currentWorker.send('process', payload, () => {
        const itemToProcess = this.queue.pop()
        if (itemToProcess) {
          currentWorker.send('process', itemToProcess.payload).then(itemToProcess.resolve, itemToProcess.reject)
        }
      })
    }
    const deferred = promiseDefer()
    this.queue.push({
      payload,
      resolve: deferred.resolve,
      reject: deferred.reject,
    })
    return deferred.promise
  }
}
<commit_msg>:bug: Fix hard-coded chunk format<commit_after>// @flow

import os from 'os'
import pMap from 'p-map'
import pReduce from 'p-reduce'
import flatten from 'lodash/flatten'
import promiseDefer from 'promise.defer'
import {
  Job,
  PundleError,
  getChunk,
  getFileImportHash,
  type Chunk,
  type ImportResolved,
  type ImportRequest,
  type ComponentFileResolverResult,
  type WorkerProcessResult,
} from 'pundle-api'
import type { Config } from 'pundle-core-load-config'

import { getOutputPath } from './helpers'
import WorkerDelegate from '../worker/delegate'
import type { RunOptions } from '../types'

// TODO: Locks for files and chunks
export default class Master {
  config: Config
  options: RunOptions
  resolverWorker: WorkerDelegate
  processorWorkers: Array<WorkerDelegate>
  queue: Array<{| payload: {}, resolve: Function, reject: Function |}>

  constructor(config: Config, options: RunOptions) {
    this.config = config
    this.options = options
    this.queue = []

    this.resolverWorker = new WorkerDelegate('resolver', options)
    this.processorWorkers = os.cpus().map(() => new WorkerDelegate('processor', options))

    this.getAllWorkers().forEach(worker => {
      worker.setMaster(this)
    })
  }
  getAllWorkers(): Array<WorkerDelegate> {
    return [this.resolverWorker].concat(this.processorWorkers)
  }
  async spawnWorkers() {
    try {
      await Promise.all(
        this.getAllWorkers().map(async worker => {
          if (worker.isAlive()) return
          try {
            await worker.spawn()
          } catch (error) {
            worker.dispose()
            throw error
          }
        }),
      )
    } catch (error) {
      throw new PundleError('DAEMON', 'WORKER_CRASHED', null, null, `Worker crashed during initial spawn: ${error.message}`)
    }
  }
  dispose() {
    this.getAllWorkers().forEach(function(worker) {
      worker.dispose()
    })
  }
  report(issue: $FlowFixMe) {
    console.log('issue reported to master', issue)
  }

  async execute(): Promise<void> {
    const job = new Job()
    const entries = await Promise.all(
      this.config.entry.map(entry =>
        this.resolve({
          request: entry,
          requestRoot: this.config.rootDirectory,
          ignoredResolvers: [],
        }),
      ),
    )
    await pMap(entries, entry => this.processChunk(getChunk(entry.format, null, entry.resolved), job))
    const generated = await this.generate(job)

    // TODO: Maybe do something else?
    return generated
  }
  async generate(
    givenJob: Job,
  ): Promise<Array<{ id: string, filePath: string | false, format: string, contents: string | Buffer }>> {
    let job = givenJob.clone()
    const jobTransformers = this.config.components.filter(c => c.type === 'job-transformer')

    job = await pReduce(
      jobTransformers,
      async (value, component) => {
        const result = await component.callback(value)
        // TODO: Validation
        return result || value
      },
      job,
    )

    const chunkGenerators = this.config.components.filter(c => c.type === 'chunk-generator')
    if (!chunkGenerators.length) {
      throw new Error('No chunk-generator components configured')
    }

    const generated = await pMap(job.chunks.values(), async chunk => {
      for (let i = 0, { length } = chunkGenerators; i < length; i++) {
        const generator = chunkGenerators[i]
        const result = await generator.callback(chunk, job, {
          getOutputPath: (output: { id: string, entry: ?string, format: string }) => getOutputPath(this.config, output),
        })
        if (result) {
          return result.map(item => ({ ...item, id: chunk.id, filePath: getOutputPath(this.config, chunk) }))
        }
      }
      throw new Error(
        `All generators refused to generate chunk of format '${chunk.format}' with label '${chunk.label}' and entry '${
          chunk.entry
        }'`,
      )
    })

    return flatten(generated)
  }
  async processChunk(chunk: Chunk, job: Job): Promise<void> {
    const { entry } = chunk
    if (!entry) {
      // TODO: Return silently instead?
      throw new Error('Cannot process chunk without entry')
    }
    if (job.locks.has(chunk.id)) return
    if (job.chunks.has(chunk.id)) return

    job.locks.add(chunk.id)
    try {
      job.chunks.set(chunk.id, chunk)

      await this.processFileTree(
        {
          format: chunk.format,
          filePath: entry,
        },
        false,
        job,
      )
    } catch (error) {
      job.chunks.delete(chunk.id)
      throw error
    } finally {
      job.locks.delete(chunk.id)
    }
  }
  // TODO: Use cached old files here if present on the job?
  async processFileTree(request: ImportResolved, forcedOverwrite: boolean, job: Job): Promise<void> {
    const lockKey = getFileImportHash(request.filePath, request.format)
    const oldFile = job.files.get(lockKey)
    if (job.locks.has(lockKey)) {
      return
    }
    if (oldFile && !forcedOverwrite) {
      return
    }
    job.locks.add(lockKey)

    try {
      const newFile = await this.queuedProcess(request)
      job.files.set(newFile.id, newFile)
      await Promise.all([
        pMap(newFile.imports, fileImport => this.processFileTree(fileImport, false, job)),
        pMap(newFile.chunks, fileChunk => this.processChunk(fileChunk, job)),
      ])
    } catch (error) {
      if (oldFile) {
        job.files.set(lockKey, oldFile)
      } else {
        job.files.delete(lockKey)
      }
      throw error
    } finally {
      job.locks.delete(lockKey)
    }
  }
  async resolve(request: ImportRequest): Promise<ComponentFileResolverResult> {
    return this.resolverWorker.send('resolve', request)
  }
  async queuedProcess(payload: ImportResolved): Promise<WorkerProcessResult> {
    const currentWorker = this.processorWorkers.find(worker => worker.isWorking === 0)
    if (currentWorker) {
      return currentWorker.send('process', payload, () => {
        const itemToProcess = this.queue.pop()
        if (itemToProcess) {
          currentWorker.send('process', itemToProcess.payload).then(itemToProcess.resolve, itemToProcess.reject)
        }
      })
    }
    const deferred = promiseDefer()
    this.queue.push({
      payload,
      resolve: deferred.resolve,
      reject: deferred.reject,
    })
    return deferred.promise
  }
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {
	// Unified Watch Object
	var watchFiles = {
		serverViews: ['app/views/**/*.*'],
		serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js', '!app/tests/'],
		clientViews: ['public/views/**/*.html'],
		clientJS: ['public/scripts/**/*.js'],
		clientCSS: ['public/stylesheets/*.css'],
		scss: ['public/stylesheets/*.scss'],
		mochaTests: ['app/tests/**/*.js']
	};

	// Project Configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		env: {
			test: {
				NODE_ENV: 'test'
			},
			dev: {
				NODE_ENV: 'development'
			},
			prod: {
				NODE_ENV: 'production'
			},
			secure: {
				NODE_ENV: 'secure'
			}
		},
		watch: {
			serverViews: {
				files: watchFiles.serverViews,
				options: {
					livereload: true
				}
			},
			serverJS: {
				files: watchFiles.serverJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientViews: {
				files: watchFiles.clientViews,
				options: {
					livereload: true
				}
			},
			clientJS: {
				files: watchFiles.clientJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientCSS: {
				files: watchFiles.clientCSS,
				tasks: ['csslint'],
				options: {
					livereload: true
				}
			},
      clientSCSS: {
        files: 'public/stylesheets/scss/*.scss',
        tasks: ['sass'],
        options: {
          livereload: true
        }
      }
		},
		jshint: {
			all: {
				src: watchFiles.clientJS.concat(watchFiles.serverJS),
				options: {
					jshintrc: true
				}
			}
		},
		csslint: {
			options: {
				csslintrc: '.csslintrc'
			},
			all: {
				src: watchFiles.clientCSS
			}
		},
		uglify: {
			production: {
				options: {
					mangle: false
				},
				files: {
					'public/dist/application.min.js': '<%= applicationJavaScriptFiles %>',
					'public/dist/vendor.min.js': '<%= vendorJavaScriptFiles %>'
				}
			}
		},
		cssmin: {
			combine: {
				files: {
					'public/dist/application.min.css': '<%= applicationCSSFiles %>'
				}
			}
		},

		//add vendor prefixed styles
		autoprefixer: {
			options: {
				browsers: ['last 2 versions', 'ie 8', 'ie 9']
			},
			dist: {
				files: [{
					expand: true,
					src: 'public/stylesheets/*.css'
				}]
			}
		},

		//compiles scss to css
    sass: {
      dist: {
      	options: {
      		compass: true
      	},
        files: {
          'public/stylesheets/main.css': 'public/stylesheets/scss/main.scss'
        }
      }
    },
		nodemon: {
			dev: {
				script: 'server.js',
				options: {
					nodeArgs: ['--debug'],
					ext: 'js,html',
					watch: watchFiles.serverViews.concat(watchFiles.serverJS)
				}
			}
		},
		'node-inspector': {
			custom: {
				options: {
					'web-port': 1337,
					'web-host': 'localhost',
					'debug-port': 5858,
					'save-live-edit': true,
					'no-preload': true,
					'stack-trace-limit': 50,
					'hidden': []
				}
			}
		},
		// ngAnnotate: {
		// 	production: {
		// 		files: {
		// 			'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
		// 		}
		// 	}
		// },
		concurrent: {
			default: ['nodemon', 'watch', 'sass'],
			debug: ['nodemon', 'watch', 'node-inspector'],
			options: {
				logConcurrentOutput: true,
				limit: 10
			}
		},
		mochaTest: {
			src: watchFiles.mochaTests,
			options: {
				reporter: 'spec',
				require: 'server.js'
			}
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js'
			}
		}
	});

	// Load NPM tasks
	require('load-grunt-tasks')(grunt);

	// Making grunt default to force in order not to break the project.
	grunt.option('force', true);

	// A Task for loading the configuration object
	grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
		var init = require('./config/init')();
		var config = require('./config/config');

		grunt.config.set('applicationJavaScriptFiles', config.assets.js);
		grunt.config.set('vendorJavaScriptFiles', config.assets.lib.js);
		grunt.config.set('applicationCSSFiles', config.assets.lib.css.concat(config.assets.css));
	});

	// Default task(s).
	grunt.registerTask('default', ['env:dev', 'concurrent:default']);

	// Debug task.
	// grunt.registerTask('debug', ['lint', 'concurrent:debug']);
	grunt.registerTask('debug', ['concurrent:debug']);

	// Secure task(s).
	grunt.registerTask('secure', ['env:secure', 'lint', 'concurrent:default']);

	// Lint task(s).
	grunt.registerTask('lint', ['jshint', 'csslint']);

	// Build task(s).
	// grunt.registerTask('build', ['lint', 'loadConfig', 'autoprefixer', 'ngAnnotate', 'uglify', 'cssmin']);
	grunt.registerTask('build', ['env:dev', 'loadConfig', 'autoprefixer', 'uglify', 'cssmin']);

	// Test task.
	grunt.registerTask('test', ['test:server', 'test:client']);
	grunt.registerTask('test:server', ['env:test', 'mochaTest']);
	grunt.registerTask('test:client', ['env:test', 'karma:unit']);

	// Run in production mode
	grunt.registerTask('prod', ['build', 'env:prod', 'concurrent:default']);

};
<commit_msg>update autoprefixer task options<commit_after>'use strict';

module.exports = function(grunt) {
	// Unified Watch Object
	var watchFiles = {
		serverViews: ['app/views/**/*.*'],
		serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js', '!app/tests/'],
		clientViews: ['public/views/**/*.html'],
		clientJS: ['public/scripts/**/*.js'],
		clientCSS: ['public/stylesheets/*.css'],
		scss: ['public/stylesheets/*.scss'],
		mochaTests: ['app/tests/**/*.js']
	};

	// Project Configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		env: {
			test: {
				NODE_ENV: 'test'
			},
			dev: {
				NODE_ENV: 'development'
			},
			prod: {
				NODE_ENV: 'production'
			},
			secure: {
				NODE_ENV: 'secure'
			}
		},
		watch: {
			serverViews: {
				files: watchFiles.serverViews,
				options: {
					livereload: true
				}
			},
			serverJS: {
				files: watchFiles.serverJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientViews: {
				files: watchFiles.clientViews,
				options: {
					livereload: true
				}
			},
			clientJS: {
				files: watchFiles.clientJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientCSS: {
				files: watchFiles.clientCSS,
				tasks: ['csslint'],
				options: {
					livereload: true
				}
			},
      clientSCSS: {
        files: 'public/stylesheets/scss/*.scss',
        tasks: ['sass'],
        options: {
          livereload: true
        }
      }
		},
		jshint: {
			all: {
				src: watchFiles.clientJS.concat(watchFiles.serverJS),
				options: {
					jshintrc: true
				}
			}
		},
		csslint: {
			options: {
				csslintrc: '.csslintrc'
			},
			all: {
				src: watchFiles.clientCSS
			}
		},
		uglify: {
			production: {
				options: {
					mangle: false
				},
				files: {
					'public/dist/application.min.js': '<%= applicationJavaScriptFiles %>',
					'public/dist/vendor.min.js': '<%= vendorJavaScriptFiles %>'
				}
			}
		},
		cssmin: {
			combine: {
				files: {
					'public/dist/application.min.css': '<%= applicationCSSFiles %>'
				}
			}
		},

		//add vendor prefixed styles
		autoprefixer: {
			options: {
				browsers: ['last 2 versions', 'ie 8', 'ie 9'],
				remove: false
			},
			dist: {
				files: [{
					expand: true,
					src: 'public/stylesheets/*.css'
				}]
			}
		},

		//compiles scss to css
    sass: {
      dist: {
      	options: {
      		compass: true
      	},
        files: {
          'public/stylesheets/main.css': 'public/stylesheets/scss/main.scss'
        }
      }
    },
		nodemon: {
			dev: {
				script: 'server.js',
				options: {
					nodeArgs: ['--debug'],
					ext: 'js,html',
					watch: watchFiles.serverViews.concat(watchFiles.serverJS)
				}
			}
		},
		'node-inspector': {
			custom: {
				options: {
					'web-port': 1337,
					'web-host': 'localhost',
					'debug-port': 5858,
					'save-live-edit': true,
					'no-preload': true,
					'stack-trace-limit': 50,
					'hidden': []
				}
			}
		},
		// ngAnnotate: {
		// 	production: {
		// 		files: {
		// 			'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
		// 		}
		// 	}
		// },
		concurrent: {
			default: ['nodemon', 'watch', 'sass'],
			debug: ['nodemon', 'watch', 'node-inspector'],
			options: {
				logConcurrentOutput: true,
				limit: 10
			}
		},
		mochaTest: {
			src: watchFiles.mochaTests,
			options: {
				reporter: 'spec',
				require: 'server.js'
			}
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js'
			}
		}
	});

	// Load NPM tasks
	require('load-grunt-tasks')(grunt);

	// Making grunt default to force in order not to break the project.
	grunt.option('force', true);

	// A Task for loading the configuration object
	grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
		var init = require('./config/init')();
		var config = require('./config/config');

		grunt.config.set('applicationJavaScriptFiles', config.assets.js);
		grunt.config.set('vendorJavaScriptFiles', config.assets.lib.js);
		grunt.config.set('applicationCSSFiles', config.assets.lib.css.concat(config.assets.css));
	});

	// Default task(s).
	grunt.registerTask('default', ['env:dev', 'concurrent:default']);

	// Debug task.
	// grunt.registerTask('debug', ['lint', 'concurrent:debug']);
	grunt.registerTask('debug', ['concurrent:debug']);

	// Secure task(s).
	grunt.registerTask('secure', ['env:secure', 'lint', 'concurrent:default']);

	// Lint task(s).
	grunt.registerTask('lint', ['jshint', 'csslint']);

	// Build task(s).
	// grunt.registerTask('build', ['lint', 'loadConfig', 'autoprefixer', 'ngAnnotate', 'uglify', 'cssmin']);
	grunt.registerTask('build', ['env:dev', 'loadConfig', 'uglify', 'autoprefixer', 'cssmin']);

	// Test task.
	grunt.registerTask('test', ['test:server', 'test:client']);
	grunt.registerTask('test:server', ['env:test', 'mochaTest']);
	grunt.registerTask('test:client', ['env:test', 'karma:unit']);

	// Run in production mode
	grunt.registerTask('prod', ['build', 'env:prod', 'concurrent:default']);

};
<|endoftext|>


<commit_before>/* @flow */

import React, { Component, PropTypes } from 'react';
import ReactNative from 'react-native';
import shallowCompare from 'react-addons-shallow-compare';
import AvatarRound from './AvatarRound';
import AppText from './AppText';
import Colors from '../../Colors';

const {
	View,
	ScrollView,
	StyleSheet,
	TouchableOpacity,
} = ReactNative;

const styles = StyleSheet.create({
	container: {
		width: 56,
		backgroundColor: Colors.black,
	},

	current: {
		backgroundColor: Colors.accent,
	},

	avatar: {
		backgroundColor: 'rgba(255, 255, 255, .16)',
		marginTop: 8,
		marginHorizontal: 6,
	},

	nick: {
		color: Colors.white,
		fontSize: 12,
		lineHeight: 18,
		textAlign: 'center',
		marginVertical: 4,
	},
});

type Props = {
	data: Array<{ user: string; session: string }>;
	user: string;
	switchUser: Function;
}

export default class UserSwitcher extends Component<void, Props, void> {
	static propTypes = {
		data: PropTypes.arrayOf(PropTypes.shape({
			user: PropTypes.string,
			session: PropTypes.string,
		})),
		user: PropTypes.string.isRequired,
		switchUser: PropTypes.func.isRequired,
	};

	shouldComponentUpdate(nextProps: Props, nextState: any): boolean {
		return shallowCompare(this, nextProps, nextState);
	}

	render() {
		const {
			data,
			user,
		} = this.props;

		return (
			<View style={styles.container}>
				<ScrollView>
					{data.map(it => (
						<TouchableOpacity key={it.user} onPress={() => this.props.switchUser(it)}>
							<View style={it.user === user ? styles.current : null}>
								<AvatarRound
									style={styles.avatar}
									user={it.user}
									size={44}
								/>
								<AppText numberOfLines={1} style={styles.nick}>{it.user}</AppText>
							</View>
						</TouchableOpacity>
					))}
				</ScrollView>
			</View>
		);
	}
}
<commit_msg>perf(ui): use a Listview for user switcher<commit_after>/* @flow */

import React, { Component, PropTypes } from 'react';
import ReactNative from 'react-native';
import shallowCompare from 'react-addons-shallow-compare';
import AvatarRound from './AvatarRound';
import AppText from './AppText';
import Colors from '../../Colors';

const {
	View,
	ListView,
	StyleSheet,
	TouchableOpacity,
} = ReactNative;

const styles = StyleSheet.create({
	container: {
		width: 56,
		backgroundColor: Colors.black,
	},

	current: {
		backgroundColor: Colors.accent,
	},

	avatar: {
		backgroundColor: 'rgba(255, 255, 255, .16)',
		marginTop: 8,
		marginHorizontal: 6,
	},

	nick: {
		color: Colors.white,
		fontSize: 12,
		lineHeight: 18,
		textAlign: 'center',
		marginVertical: 4,
	},
});

type Props = {
	data: Array<{ user: string; session: string }>;
	user: string;
	switchUser: Function;
}

type State = {
	dataSource: ListView.DataSource;
}

export default class UserSwitcher extends Component<void, Props, State> {
	static propTypes = {
		data: PropTypes.arrayOf(PropTypes.shape({
			user: PropTypes.string,
			session: PropTypes.string,
		})),
		user: PropTypes.string.isRequired,
		switchUser: PropTypes.func.isRequired,
	};

	state: State = {
		dataSource: new ListView.DataSource({
			rowHasChanged: (r1, r2) => r1 !== r2,
		}),
	};

	componentWillMount() {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(this.props.data),
		});
	}

	componentWillReceiveProps(nextProps: Props) {
		this.setState({
			dataSource: this.state.dataSource.cloneWithRows(nextProps.data),
		});
	}

	shouldComponentUpdate(nextProps: Props, nextState: any): boolean {
		return shallowCompare(this, nextProps, nextState);
	}

	_renderRow: Function = (item) => {
		const {
			user,
		} = this.props;

		return (
			<TouchableOpacity key={item.user} onPress={() => this.props.switchUser(item)}>
				<View style={item.user === user ? styles.current : null}>
					<AvatarRound
						style={styles.avatar}
						user={item.user}
						size={44}
					/>
					<AppText numberOfLines={1} style={styles.nick}>{item.user}</AppText>
				</View>
			</TouchableOpacity>
		);
	};

	render() {
		return (
			<View style={styles.container}>
				<ListView
					removeClippedSubviews
					dataSource={this.state.dataSource}
					renderRow={this._renderRow}
				/>
			</View>
		);
	}
}
<|endoftext|>