<commit_before>require(`v8-compile-cache`)

const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const FriendlyErrorsWebpackPlugin = require(`@pieh/friendly-errors-webpack-plugin`)
const PnpWebpackPlugin = require(`pnp-webpack-plugin`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const getPublicPath = require(`./get-public-path`)
const debug = require(`debug`)(`gatsby:webpack-config`)
const report = require(`gatsby-cli/lib/reporter`)
const { withBasePath, withTrailingSlash } = require(`./path`)

const apiRunnerNode = require(`./api-runner-node`)
const createUtils = require(`./webpack-utils`)
const hasLocalEslint = require(`./local-eslint-config-finder`)

// Four stages or modes:
//   1) develop: for `gatsby develop` command, hot reload and CSS injection into page
//   2) develop-html: same as develop without react-hmre in the babel config for html renderer
//   3) build-javascript: Build JS and CSS chunks for production
//   4) build-html: build all HTML files

module.exports = async (program, directory, suppliedStage) => {
  const directoryPath = withBasePath(directory)

  process.env.GATSBY_BUILD_STAGE = suppliedStage

  // We combine develop & develop-html stages for purposes of generating the
  // webpack config.
  const stage = suppliedStage
  const { rules, loaders, plugins } = await createUtils({ stage, program })

  const { assetPrefix, pathPrefix } = store.getState().config

  const publicPath = getPublicPath({ assetPrefix, pathPrefix, ...program })

  function processEnv(stage, defaultNodeEnv) {
    debug(`Building env for "${stage}"`)
    // node env should be DEVELOPMENT | PRODUCTION as these are commonly used in node land
    // this variable is used inside webpack
    const nodeEnv = process.env.NODE_ENV || `${defaultNodeEnv}`
    // config env is depednant on the env that it's run, this can be anything from staging-production
    // this allows you to set use different .env environments or conditions in gatsby files
    const configEnv = process.env.GATSBY_ACTIVE_ENV || nodeEnv
    const envFile = path.join(process.cwd(), `./.env.${configEnv}`)
    let parsed = {}
    try {
      parsed = dotenv.parse(fs.readFileSync(envFile, { encoding: `utf8` }))
    } catch (err) {
      if (err.code !== `ENOENT`) {
        report.error(
          `There was a problem processing the .env file (${envFile})`,
          err
        )
      }
    }

    const envObject = Object.keys(parsed).reduce((acc, key) => {
      acc[key] = JSON.stringify(parsed[key])
      return acc
    }, {})

    const gatsbyVarObject = Object.keys(process.env).reduce((acc, key) => {
      if (key.match(/^GATSBY_/)) {
        acc[key] = JSON.stringify(process.env[key])
      }
      return acc
    }, {})

    // Don't allow overwriting of NODE_ENV, PUBLIC_DIR as to not break gatsby things
    envObject.NODE_ENV = JSON.stringify(nodeEnv)
    envObject.PUBLIC_DIR = JSON.stringify(`${process.cwd()}/public`)
    envObject.BUILD_STAGE = JSON.stringify(stage)
    envObject.CYPRESS_SUPPORT = JSON.stringify(process.env.CYPRESS_SUPPORT)

    const mergedEnvVars = Object.assign(envObject, gatsbyVarObject)

    return Object.keys(mergedEnvVars).reduce(
      (acc, key) => {
        acc[`process.env.${key}`] = mergedEnvVars[key]
        return acc
      },
      {
        "process.env": JSON.stringify({}),
      }
    )
  }

  function getHmrPath() {
    // ref: https://github.com/gatsbyjs/gatsby/issues/8348
    let hmrBasePath = `/`
    const hmrSuffix = `__webpack_hmr&reload=true&overlay=false`

    if (process.env.GATSBY_WEBPACK_PUBLICPATH) {
      const pubPath = process.env.GATSBY_WEBPACK_PUBLICPATH
      if (pubPath.substr(-1) === `/`) {
        hmrBasePath = pubPath
      } else {
        hmrBasePath = withTrailingSlash(pubPath)
      }
    }

    return hmrBasePath + hmrSuffix
  }

  debug(`Loading webpack config for stage "${stage}"`)
  function getOutput() {
    switch (stage) {
      case `develop`:
        return {
          path: directory,
          filename: `[name].js`,
          // Add /* filename */ comments to generated require()s in the output.
          pathinfo: true,
          // Point sourcemap entries to original disk location (format as URL on Windows)
          publicPath: process.env.GATSBY_WEBPACK_PUBLICPATH || `/`,
          devtoolModuleFilenameTemplate: info =>
            path.resolve(info.absoluteResourcePath).replace(/\\/g, `/`),
          // Avoid React cross-origin errors
          // See https://reactjs.org/docs/cross-origin-errors.html
          crossOriginLoading: `anonymous`,
        }
      case `build-html`:
      case `develop-html`:
        // A temp file required by static-site-generator-plugin. See plugins() below.
        // Deleted by build-html.js, since it's not needed for production.
        return {
          path: directoryPath(`public`),
          filename: `render-page.js`,
          libraryTarget: `umd`,
          library: `lib`,
          umdNamedDefine: true,
          globalObject: `this`,
          publicPath: withTrailingSlash(publicPath),
        }
      case `build-javascript`:
        return {
          filename: `[name]-[contenthash].js`,
          chunkFilename: `[name]-[contenthash].js`,
          path: directoryPath(`public`),
          publicPath: withTrailingSlash(publicPath),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getEntry() {
    switch (stage) {
      case `develop`:
        return {
          commons: [
            `event-source-polyfill`,
            `${require.resolve(
              `webpack-hot-middleware/client`
            )}?path=${getHmrPath()}`,
            directoryPath(`.cache/app`),
          ],
        }
      case `develop-html`:
        return {
          main: directoryPath(`.cache/develop-static-entry`),
        }
      case `build-html`:
        return {
          main: directoryPath(`.cache/static-entry`),
        }
      case `build-javascript`:
        return {
          app: directoryPath(`.cache/production-app`),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getPlugins() {
    let configPlugins = [
      plugins.moment(),

      // Add a few global variables. Set NODE_ENV to production (enables
      // optimizations for React) and what the link prefix is (__PATH_PREFIX__).
      plugins.define({
        ...processEnv(stage, `development`),
        __BASE_PATH__: JSON.stringify(program.prefixPaths ? pathPrefix : ``),
        __PATH_PREFIX__: JSON.stringify(program.prefixPaths ? publicPath : ``),
        __ASSET_PREFIX__: JSON.stringify(
          program.prefixPaths ? assetPrefix : ``
        ),
      }),
    ]

    switch (stage) {
      case `develop`:
        configPlugins = configPlugins.concat([
          plugins.hotModuleReplacement(),
          plugins.noEmitOnErrors(),

          new FriendlyErrorsWebpackPlugin({
            clearConsole: false,
          }),
        ])
        break
      case `build-javascript`: {
        configPlugins = configPlugins.concat([
          plugins.extractText(),
          // Write out stats object mapping named dynamic imports (aka page
          // components) to all their async chunks.
          plugins.extractStats(),
        ])
        break
      }
    }

    return configPlugins
  }

  function getDevtool() {
    switch (stage) {
      case `develop`:
        return `cheap-module-source-map`
      // use a normal `source-map` for the html phases since
      // it gives better line and column numbers
      case `develop-html`:
      case `build-html`:
      case `build-javascript`:
        return `source-map`
      default:
        return false
    }
  }

  function getMode() {
    switch (stage) {
      case `build-javascript`:
        return `production`
      case `develop`:
      case `develop-html`:
      case `build-html`:
        return `development` // So we don't uglify the html bundle
      default:
        return `production`
    }
  }

  function getModule(config) {
    // Common config for every env.
    // prettier-ignore
    let configRules = [
      rules.mjs(),
      rules.js(),
      rules.yaml(),
      rules.fonts(),
      rules.images(),
      rules.media(),
      rules.miscAssets(),
    ]
    if (store.getState().themes.themes) {
      configRules = configRules.concat(
        store.getState().themes.themes.map(theme => {
          return {
            test: /\.jsx?$/,
            include: theme.themeDir,
            use: [loaders.js()],
          }
        })
      )
    }
    switch (stage) {
      case `develop`: {
        // get schema to pass to eslint config and program for directory
        const { schema, program } = store.getState()

        // if no local eslint config, then add gatsby config
        if (!hasLocalEslint(program.directory)) {
          configRules = configRules.concat([rules.eslint(schema)])
        }

        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        // RHL will patch React, replace React-DOM by React-🔥-DOM and work with fiber directly
        // It's necessary to remove the warning in console (https://github.com/gatsbyjs/gatsby/issues/11934)
        configRules.push({
          include: /node_modules/,
          test: /\.jsx?$/,
          use: {
            loader: require.resolve(`./webpack-hmr-hooks-patch`),
          },
        })

        break
      }
      case `build-html`:
      case `develop-html`:
        // We don't deal with CSS at all when building the HTML.
        // The 'null' loader is used to prevent 'module not found' errors.
        // On the other hand CSS modules loaders are necessary.

        // prettier-ignore
        configRules = configRules.concat([
          {
            oneOf: [
              rules.cssModules(),
              {
                ...rules.css(),
                use: [loaders.null()],
              },
            ],
          },
        ])
        break

      case `build-javascript`:
        // We don't deal with CSS at all when building JavaScript but we still
        // need to process the CSS so offline-plugin knows about the various
        // assets referenced in your CSS.
        //
        // It's also necessary to process CSS Modules so your JS knows the
        // classNames to use.
        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
    }

    return { rules: configRules }
  }

  function getResolve() {
    const { program } = store.getState()
    return {
      // Use the program's extension list (generated via the
      // 'resolvableExtensions' API hook).
      extensions: [...program.extensions],
      alias: {
        gatsby$: directoryPath(path.join(`.cache`, `gatsby-browser-entry.js`)),
        // Using directories for module resolution is mandatory because
        // relative path imports are used sometimes
        // See https://stackoverflow.com/a/49455609/6420957 for more details
        "@babel/runtime": path.dirname(
          require.resolve(`@babel/runtime/package.json`)
        ),
        "core-js": path.dirname(require.resolve(`core-js/package.json`)),
        "react-hot-loader": path.dirname(
          require.resolve(`react-hot-loader/package.json`)
        ),
        "react-lifecycles-compat": directoryPath(
          `.cache/react-lifecycles-compat.js`
        ),
        "create-react-context": directoryPath(`.cache/create-react-context.js`),
      },
      plugins: [
        // Those two folders are special and contain gatsby-generated files
        // whose dependencies should be resolved through the `gatsby` package
        PnpWebpackPlugin.bind(directoryPath(`.cache`), module),
        PnpWebpackPlugin.bind(directoryPath(`public`), module),
        // Transparently resolve packages via PnP when needed; noop otherwise
        PnpWebpackPlugin,
      ],
    }
  }

  function getResolveLoader() {
    const root = [path.resolve(directory, `node_modules`)]

    const userLoaderDirectoryPath = path.resolve(directory, `loaders`)

    try {
      if (fs.statSync(userLoaderDirectoryPath).isDirectory()) {
        root.push(userLoaderDirectoryPath)
      }
    } catch (err) {
      debug(`Error resolving user loaders directory`, err)
    }

    return {
      modules: [...root, path.join(__dirname, `../loaders`), `node_modules`],
      // Bare loaders should always be loaded via the user dependencies (loaders
      // configured via third-party like gatsby use require.resolve)
      plugins: [PnpWebpackPlugin.moduleLoader(`${directory}/`)],
    }
  }

  const config = {
    // Context is the base directory for resolving the entry option.
    context: directory,
    entry: getEntry(),
    output: getOutput(),

    module: getModule(),
    plugins: getPlugins(),

    // Certain "isomorphic" packages have different entry points for browser
    // and server (see
    // https://github.com/defunctzombie/package-browser-field-spec); setting
    // the target tells webpack which file to include, ie. browser vs main.
    target: stage === `build-html` || stage === `develop-html` ? `node` : `web`,

    devtool: getDevtool(),
    // Turn off performance hints as we (for now) don't want to show the normal
    // webpack output anywhere.
    performance: {
      hints: false,
    },
    mode: getMode(),

    resolveLoader: getResolveLoader(),
    resolve: getResolve(),

    node: {
      __filename: true,
    },
  }

  if (stage === `build-javascript`) {
    config.optimization = {
      runtimeChunk: {
        name: `webpack-runtime`,
      },
      splitChunks: {
        name: false,
        cacheGroups: {
          // Only create one CSS file to avoid
          // problems with code-split CSS loading in different orders
          // causing inconsistent/non-determanistic styling
          // See https://github.com/gatsbyjs/gatsby/issues/11072
          styles: {
            name: `styles`,
            // This should cover all our types of CSS.
            test: /\.(css|scss|sass|less|styl)$/,
            chunks: `all`,
            enforce: true,
          },
        },
      },
      minimizer: [
        // TODO: maybe this option should be noMinimize?
        !program.noUglify && plugins.minifyJs(),
        plugins.minifyCss(),
      ].filter(Boolean),
    }
  }

  if (stage === `build-html` || stage === `develop-html`) {
    // Packages we want to externalize to save some build time
    // https://github.com/gatsbyjs/gatsby/pull/14208#pullrequestreview-240178728
    const externalList = [
      `@reach/router/lib/history`,
      `@reach/router`,
      `common-tags`,
      /^core-js\//,
      `crypto`,
      `debug`,
      `fs`,
      `https`,
      `http`,
      `lodash`,
      `path`,
      `semver`,
      /^lodash\//,
      `zlib`,
    ]

    // Packages we want to externalize because meant to be user-provided
    const userExternalList = [
      `es6-promise`,
      `minimatch`,
      `pify`,
      `react-helmet`,
      `react`,
      /^react-dom\//,
    ]

    const checkItem = (item, request) => {
      if (typeof item === `string` && item === request) {
        return true
      } else if (item instanceof RegExp && item.test(request)) {
        return true
      }
      return false
    }

    const isExternal = request => {
      if (externalList.some(item => checkItem(item, request))) {
        return `umd ${require.resolve(request)}`
      }
      if (userExternalList.some(item => checkItem(item, request))) {
        return `umd ${request}`
      }
      return null
    }

    config.externals = [
      function(context, request, callback) {
        const external = isExternal(request)
        if (external !== null) {
          callback(null, external)
        } else {
          callback()
        }
      },
    ]
  }

  store.dispatch(actions.replaceWebpackConfig(config))
  const getConfig = () => store.getState().webpack

  await apiRunnerNode(`onCreateWebpackConfig`, {
    getConfig,
    stage,
    rules,
    loaders,
    plugins,
  })

  return getConfig()
}
<commit_msg>fix(gatsby): fix `gatsby develop` with Yarn PnP (#14261)<commit_after>require(`v8-compile-cache`)

const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const FriendlyErrorsWebpackPlugin = require(`@pieh/friendly-errors-webpack-plugin`)
const PnpWebpackPlugin = require(`pnp-webpack-plugin`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const getPublicPath = require(`./get-public-path`)
const debug = require(`debug`)(`gatsby:webpack-config`)
const report = require(`gatsby-cli/lib/reporter`)
const { withBasePath, withTrailingSlash } = require(`./path`)

const apiRunnerNode = require(`./api-runner-node`)
const createUtils = require(`./webpack-utils`)
const hasLocalEslint = require(`./local-eslint-config-finder`)

// Four stages or modes:
//   1) develop: for `gatsby develop` command, hot reload and CSS injection into page
//   2) develop-html: same as develop without react-hmre in the babel config for html renderer
//   3) build-javascript: Build JS and CSS chunks for production
//   4) build-html: build all HTML files

module.exports = async (program, directory, suppliedStage) => {
  const directoryPath = withBasePath(directory)

  process.env.GATSBY_BUILD_STAGE = suppliedStage

  // We combine develop & develop-html stages for purposes of generating the
  // webpack config.
  const stage = suppliedStage
  const { rules, loaders, plugins } = await createUtils({ stage, program })

  const { assetPrefix, pathPrefix } = store.getState().config

  const publicPath = getPublicPath({ assetPrefix, pathPrefix, ...program })

  function processEnv(stage, defaultNodeEnv) {
    debug(`Building env for "${stage}"`)
    // node env should be DEVELOPMENT | PRODUCTION as these are commonly used in node land
    // this variable is used inside webpack
    const nodeEnv = process.env.NODE_ENV || `${defaultNodeEnv}`
    // config env is depednant on the env that it's run, this can be anything from staging-production
    // this allows you to set use different .env environments or conditions in gatsby files
    const configEnv = process.env.GATSBY_ACTIVE_ENV || nodeEnv
    const envFile = path.join(process.cwd(), `./.env.${configEnv}`)
    let parsed = {}
    try {
      parsed = dotenv.parse(fs.readFileSync(envFile, { encoding: `utf8` }))
    } catch (err) {
      if (err.code !== `ENOENT`) {
        report.error(
          `There was a problem processing the .env file (${envFile})`,
          err
        )
      }
    }

    const envObject = Object.keys(parsed).reduce((acc, key) => {
      acc[key] = JSON.stringify(parsed[key])
      return acc
    }, {})

    const gatsbyVarObject = Object.keys(process.env).reduce((acc, key) => {
      if (key.match(/^GATSBY_/)) {
        acc[key] = JSON.stringify(process.env[key])
      }
      return acc
    }, {})

    // Don't allow overwriting of NODE_ENV, PUBLIC_DIR as to not break gatsby things
    envObject.NODE_ENV = JSON.stringify(nodeEnv)
    envObject.PUBLIC_DIR = JSON.stringify(`${process.cwd()}/public`)
    envObject.BUILD_STAGE = JSON.stringify(stage)
    envObject.CYPRESS_SUPPORT = JSON.stringify(process.env.CYPRESS_SUPPORT)

    const mergedEnvVars = Object.assign(envObject, gatsbyVarObject)

    return Object.keys(mergedEnvVars).reduce(
      (acc, key) => {
        acc[`process.env.${key}`] = mergedEnvVars[key]
        return acc
      },
      {
        "process.env": JSON.stringify({}),
      }
    )
  }

  function getHmrPath() {
    // ref: https://github.com/gatsbyjs/gatsby/issues/8348
    let hmrBasePath = `/`
    const hmrSuffix = `__webpack_hmr&reload=true&overlay=false`

    if (process.env.GATSBY_WEBPACK_PUBLICPATH) {
      const pubPath = process.env.GATSBY_WEBPACK_PUBLICPATH
      if (pubPath.substr(-1) === `/`) {
        hmrBasePath = pubPath
      } else {
        hmrBasePath = withTrailingSlash(pubPath)
      }
    }

    return hmrBasePath + hmrSuffix
  }

  debug(`Loading webpack config for stage "${stage}"`)
  function getOutput() {
    switch (stage) {
      case `develop`:
        return {
          path: directory,
          filename: `[name].js`,
          // Add /* filename */ comments to generated require()s in the output.
          pathinfo: true,
          // Point sourcemap entries to original disk location (format as URL on Windows)
          publicPath: process.env.GATSBY_WEBPACK_PUBLICPATH || `/`,
          devtoolModuleFilenameTemplate: info =>
            path.resolve(info.absoluteResourcePath).replace(/\\/g, `/`),
          // Avoid React cross-origin errors
          // See https://reactjs.org/docs/cross-origin-errors.html
          crossOriginLoading: `anonymous`,
        }
      case `build-html`:
      case `develop-html`:
        // A temp file required by static-site-generator-plugin. See plugins() below.
        // Deleted by build-html.js, since it's not needed for production.
        return {
          path: directoryPath(`public`),
          filename: `render-page.js`,
          libraryTarget: `umd`,
          library: `lib`,
          umdNamedDefine: true,
          globalObject: `this`,
          publicPath: withTrailingSlash(publicPath),
        }
      case `build-javascript`:
        return {
          filename: `[name]-[contenthash].js`,
          chunkFilename: `[name]-[contenthash].js`,
          path: directoryPath(`public`),
          publicPath: withTrailingSlash(publicPath),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getEntry() {
    switch (stage) {
      case `develop`:
        return {
          commons: [
            require.resolve(`event-source-polyfill`),
            `${require.resolve(
              `webpack-hot-middleware/client`
            )}?path=${getHmrPath()}`,
            directoryPath(`.cache/app`),
          ],
        }
      case `develop-html`:
        return {
          main: directoryPath(`.cache/develop-static-entry`),
        }
      case `build-html`:
        return {
          main: directoryPath(`.cache/static-entry`),
        }
      case `build-javascript`:
        return {
          app: directoryPath(`.cache/production-app`),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getPlugins() {
    let configPlugins = [
      plugins.moment(),

      // Add a few global variables. Set NODE_ENV to production (enables
      // optimizations for React) and what the link prefix is (__PATH_PREFIX__).
      plugins.define({
        ...processEnv(stage, `development`),
        __BASE_PATH__: JSON.stringify(program.prefixPaths ? pathPrefix : ``),
        __PATH_PREFIX__: JSON.stringify(program.prefixPaths ? publicPath : ``),
        __ASSET_PREFIX__: JSON.stringify(
          program.prefixPaths ? assetPrefix : ``
        ),
      }),
    ]

    switch (stage) {
      case `develop`:
        configPlugins = configPlugins.concat([
          plugins.hotModuleReplacement(),
          plugins.noEmitOnErrors(),

          new FriendlyErrorsWebpackPlugin({
            clearConsole: false,
          }),
        ])
        break
      case `build-javascript`: {
        configPlugins = configPlugins.concat([
          plugins.extractText(),
          // Write out stats object mapping named dynamic imports (aka page
          // components) to all their async chunks.
          plugins.extractStats(),
        ])
        break
      }
    }

    return configPlugins
  }

  function getDevtool() {
    switch (stage) {
      case `develop`:
        return `cheap-module-source-map`
      // use a normal `source-map` for the html phases since
      // it gives better line and column numbers
      case `develop-html`:
      case `build-html`:
      case `build-javascript`:
        return `source-map`
      default:
        return false
    }
  }

  function getMode() {
    switch (stage) {
      case `build-javascript`:
        return `production`
      case `develop`:
      case `develop-html`:
      case `build-html`:
        return `development` // So we don't uglify the html bundle
      default:
        return `production`
    }
  }

  function getModule(config) {
    // Common config for every env.
    // prettier-ignore
    let configRules = [
      rules.mjs(),
      rules.js(),
      rules.yaml(),
      rules.fonts(),
      rules.images(),
      rules.media(),
      rules.miscAssets(),
    ]
    if (store.getState().themes.themes) {
      configRules = configRules.concat(
        store.getState().themes.themes.map(theme => {
          return {
            test: /\.jsx?$/,
            include: theme.themeDir,
            use: [loaders.js()],
          }
        })
      )
    }
    switch (stage) {
      case `develop`: {
        // get schema to pass to eslint config and program for directory
        const { schema, program } = store.getState()

        // if no local eslint config, then add gatsby config
        if (!hasLocalEslint(program.directory)) {
          configRules = configRules.concat([rules.eslint(schema)])
        }

        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        // RHL will patch React, replace React-DOM by React-🔥-DOM and work with fiber directly
        // It's necessary to remove the warning in console (https://github.com/gatsbyjs/gatsby/issues/11934)
        configRules.push({
          include: /node_modules/,
          test: /\.jsx?$/,
          use: {
            loader: require.resolve(`./webpack-hmr-hooks-patch`),
          },
        })

        break
      }
      case `build-html`:
      case `develop-html`:
        // We don't deal with CSS at all when building the HTML.
        // The 'null' loader is used to prevent 'module not found' errors.
        // On the other hand CSS modules loaders are necessary.

        // prettier-ignore
        configRules = configRules.concat([
          {
            oneOf: [
              rules.cssModules(),
              {
                ...rules.css(),
                use: [loaders.null()],
              },
            ],
          },
        ])
        break

      case `build-javascript`:
        // We don't deal with CSS at all when building JavaScript but we still
        // need to process the CSS so offline-plugin knows about the various
        // assets referenced in your CSS.
        //
        // It's also necessary to process CSS Modules so your JS knows the
        // classNames to use.
        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
    }

    return { rules: configRules }
  }

  function getResolve() {
    const { program } = store.getState()
    return {
      // Use the program's extension list (generated via the
      // 'resolvableExtensions' API hook).
      extensions: [...program.extensions],
      alias: {
        gatsby$: directoryPath(path.join(`.cache`, `gatsby-browser-entry.js`)),
        // Using directories for module resolution is mandatory because
        // relative path imports are used sometimes
        // See https://stackoverflow.com/a/49455609/6420957 for more details
        "@babel/runtime": path.dirname(
          require.resolve(`@babel/runtime/package.json`)
        ),
        "core-js": path.dirname(require.resolve(`core-js/package.json`)),
        "react-hot-loader": path.dirname(
          require.resolve(`react-hot-loader/package.json`)
        ),
        "react-lifecycles-compat": directoryPath(
          `.cache/react-lifecycles-compat.js`
        ),
        "create-react-context": directoryPath(`.cache/create-react-context.js`),
      },
      plugins: [
        // Those two folders are special and contain gatsby-generated files
        // whose dependencies should be resolved through the `gatsby` package
        PnpWebpackPlugin.bind(directoryPath(`.cache`), module),
        PnpWebpackPlugin.bind(directoryPath(`public`), module),
        // Transparently resolve packages via PnP when needed; noop otherwise
        PnpWebpackPlugin,
      ],
    }
  }

  function getResolveLoader() {
    const root = [path.resolve(directory, `node_modules`)]

    const userLoaderDirectoryPath = path.resolve(directory, `loaders`)

    try {
      if (fs.statSync(userLoaderDirectoryPath).isDirectory()) {
        root.push(userLoaderDirectoryPath)
      }
    } catch (err) {
      debug(`Error resolving user loaders directory`, err)
    }

    return {
      modules: [...root, path.join(__dirname, `../loaders`), `node_modules`],
      // Bare loaders should always be loaded via the user dependencies (loaders
      // configured via third-party like gatsby use require.resolve)
      plugins: [PnpWebpackPlugin.moduleLoader(`${directory}/`)],
    }
  }

  const config = {
    // Context is the base directory for resolving the entry option.
    context: directory,
    entry: getEntry(),
    output: getOutput(),

    module: getModule(),
    plugins: getPlugins(),

    // Certain "isomorphic" packages have different entry points for browser
    // and server (see
    // https://github.com/defunctzombie/package-browser-field-spec); setting
    // the target tells webpack which file to include, ie. browser vs main.
    target: stage === `build-html` || stage === `develop-html` ? `node` : `web`,

    devtool: getDevtool(),
    // Turn off performance hints as we (for now) don't want to show the normal
    // webpack output anywhere.
    performance: {
      hints: false,
    },
    mode: getMode(),

    resolveLoader: getResolveLoader(),
    resolve: getResolve(),

    node: {
      __filename: true,
    },
  }

  if (stage === `build-javascript`) {
    config.optimization = {
      runtimeChunk: {
        name: `webpack-runtime`,
      },
      splitChunks: {
        name: false,
        cacheGroups: {
          // Only create one CSS file to avoid
          // problems with code-split CSS loading in different orders
          // causing inconsistent/non-determanistic styling
          // See https://github.com/gatsbyjs/gatsby/issues/11072
          styles: {
            name: `styles`,
            // This should cover all our types of CSS.
            test: /\.(css|scss|sass|less|styl)$/,
            chunks: `all`,
            enforce: true,
          },
        },
      },
      minimizer: [
        // TODO: maybe this option should be noMinimize?
        !program.noUglify && plugins.minifyJs(),
        plugins.minifyCss(),
      ].filter(Boolean),
    }
  }

  if (stage === `build-html` || stage === `develop-html`) {
    // Packages we want to externalize to save some build time
    // https://github.com/gatsbyjs/gatsby/pull/14208#pullrequestreview-240178728
    const externalList = [
      `@reach/router/lib/history`,
      `@reach/router`,
      `common-tags`,
      /^core-js\//,
      `crypto`,
      `debug`,
      `fs`,
      `https`,
      `http`,
      `lodash`,
      `path`,
      `semver`,
      /^lodash\//,
      `zlib`,
    ]

    // Packages we want to externalize because meant to be user-provided
    const userExternalList = [
      `es6-promise`,
      `minimatch`,
      `pify`,
      `react-helmet`,
      `react`,
      /^react-dom\//,
    ]

    const checkItem = (item, request) => {
      if (typeof item === `string` && item === request) {
        return true
      } else if (item instanceof RegExp && item.test(request)) {
        return true
      }
      return false
    }

    const isExternal = request => {
      if (externalList.some(item => checkItem(item, request))) {
        return `umd ${require.resolve(request)}`
      }
      if (userExternalList.some(item => checkItem(item, request))) {
        return `umd ${request}`
      }
      return null
    }

    config.externals = [
      function(context, request, callback) {
        const external = isExternal(request)
        if (external !== null) {
          callback(null, external)
        } else {
          callback()
        }
      },
    ]
  }

  store.dispatch(actions.replaceWebpackConfig(config))
  const getConfig = () => store.getState().webpack

  await apiRunnerNode(`onCreateWebpackConfig`, {
    getConfig,
    stage,
    rules,
    loaders,
    plugins,
  })

  return getConfig()
}
<|endoftext|>


<commit_before>var GrovePi = require('node-grovepi').GrovePi;
var Commands = GrovePi.commands;
var Board = GrovePi.board;
var GenericDigitalInputSensor = GrovePi.sensors.GenericDigitalInput;

var board;

// Connect the Grove Button to digital port D2

function start() {
    console.log('starting...');
    board = new Board({
        debug: true,
        onError: function(err) {
            console.log('Oops! Something error.');
            console.log(err);
        },
        onInit: function(res) {
            if(res) {
                console.log('GrovePi Version : ' + board.version());

                var button = new GenericDigitalInputSensor(2);

                button.on('change', function(res) {
                    console.log('Grove Button value= ' + res);
                });
                button.watch();
            }
        }
    });
    board.init();
}

function onExit(err) {
    console.log('ending');
    board.close();
    process.removeAllListeners();
    process.exit();
    if (typeof err != 'undefined')
        console.log(err);
}

//start the app
start();

// catches ctrl+c event
process.on('SIGINT', onExit);
<commit_msg>fix grove button<commit_after>var GrovePi = require('node-grovepi').GrovePi;
var Commands = GrovePi.commands;
var Board = GrovePi.board;
var GenericDigitalInputSensor = require('node-grovepi').sensors.genericDigitalInputSensor;

var board;

// Connect the Grove Button to digital port D2

function start() {
    console.log('starting...');
    board = new Board({
        debug: true,
        onError: function(err) {
            console.log('Oops! Something error.');
            console.log(err);
        },
        onInit: function(res) {
            if(res) {
                console.log('GrovePi Version : ' + board.version());

                var button = new GenericDigitalInputSensor(2);

                button.on('change', function(res) {
                    console.log('Grove Button value= ' + res);
                });
                button.watch();
            }
        }
    });
    board.init();
}

function onExit(err) {
    console.log('ending');
    board.close();
    process.removeAllListeners();
    process.exit();
    if (typeof err != 'undefined')
        console.log(err);
}

//start the app
start();

// catches ctrl+c event
process.on('SIGINT', onExit);
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const typescriptDocgen = require('react-docgen-typescript');

function parseLine(exports, line) {
  const exportedName = line.replace(/.+"\.\/(\w+)";$/, 'src/$1.tsx');
  if (exportedName && exports.indexOf(exportedName) === -1) {
    exports.push(exportedName);
  }

  return exports;
}

function findExports() {
  const src = path.join(process.cwd(), 'src');
  const main = path.join(src, 'index.ts');
  const contents = fs.readFileSync(main, 'UTF-8');
  return contents.split(/\r?\n/).reduce((list, line) => parseLine(list, line, src), []);
}

module.exports = function createDocgen() {
  const tsconfig = path.join(process.cwd(), 'tsconfig.json');
  const parser = typescriptDocgen.withCustomConfig(tsconfig).parse;
  return findExports().map((fileName) => {
    const parsed = parser(fileName);
    if (parsed.length > 1) {
      for (let i = 0; i < parsed.length; i += 1) {
        const docgen = parsed[i];
        if (docgen.displayName.indexOf('Consumer') === -1) {
          return docgen;
        }
      }
    }

    return parsed[0];
  });
};
<commit_msg>Fixed doc-generator to not attempt to parse types<commit_after>const fs = require('fs');
const path = require('path');
const typescriptDocgen = require('react-docgen-typescript');

function parseLine(exports, line) {
  if (line === 'export * from "./types";') {
    return exports;
  }

  const exportedName = line.replace(/.+"\.\/(\w+)";$/, 'src/$1.tsx');
  if (exportedName && exports.indexOf(exportedName) === -1) {
    exports.push(exportedName);
  }

  return exports;
}

function findExports() {
  const src = path.join(process.cwd(), 'src');
  const main = path.join(src, 'index.ts');
  const contents = fs.readFileSync(main, 'UTF-8');
  return contents.split(/\r?\n/).reduce((list, line) => parseLine(list, line, src), []);
}

module.exports = function createDocgen() {
  const tsconfig = path.join(process.cwd(), 'tsconfig.json');
  const parser = typescriptDocgen.withCustomConfig(tsconfig).parse;
  return findExports().map((fileName) => {
    const parsed = parser(fileName);
    if (parsed.length > 1) {
      for (let i = 0; i < parsed.length; i += 1) {
        const docgen = parsed[i];
        if (docgen.displayName.indexOf('Consumer') === -1) {
          return docgen;
        }
      }
    }

    return parsed[0];
  });
};
<|endoftext|>


<commit_before>var milkcocoa = new MilkCocoa('{your-app-id}.mlkcca.com');<commit_msg>app_id<commit_after>var milkcocoa = new MilkCocoa('uniicwq7emj.mlkcca.com');
<|endoftext|>


<commit_before>define(function() {
  require.config({
    enforceDefine : true,
    paths : {
      aura : 'components/aura/lib',
      backbone : 'components/backbone/backbone',
      bootstrap : 'components/bootstrap/docs/assets/js/bootstrap',
      bootstrap_datepicker : 'js/vendor/bootstrap/plugins/datepicker',
      bootstrap_lightbox : 'js/vendor/bootstrap/plugins/lightbox',
      bootstrap_tag : 'js/vendor/bootstrap/plugins/bootstrap-tag',
      eventemitter : 'components/eventemitter2/lib/eventemitter2',
      fuelux_datagrid : 'components/fuelux/dist/datagrid',
      jquery : 'components/jquery/jquery',
      jquery_migrate : 'components/jquery/jquery-migrate',
      json2 : 'components/json2/json2',
      'load-image' : 'js/vendor/bootstrap/plugins/load-image',
      moment : 'js/vendor/moment/moment',
      moment_pl : 'js/vendor/moment/moment-pl',
      text : 'components/requirejs-text/text',
      underscore : 'components/lodash/dist/lodash.underscore',

      extensions : 'js/extensions',

      legacy : 'js/widgets/legacy'
    },
    shim : {
      'aura/aura' : {
        deps : [ 'jquery', 'underscore', 'text', 'aura/ext/debug', 'aura/ext/mediator', 'aura/ext/widgets' ]
      },
      backbone : {
        deps : [ 'jquery', 'underscore' ],
        exports : 'Backbone'
      },
      bootstrap : {
        deps : [ 'jquery' ],
        exports : '$.fn.affix'
      },
      bootstrap_datepicker : {
        deps : [ 'bootstrap' ]
      },
      bootstrap_tag : {
        deps : [ 'bootstrap' ],
        exports : '$.fn.tag'
      },
      fuelux_datagrid : {
        deps : [ 'bootstrap' ]
      },
      jquery : {
        deps : [ 'json2' ]
      },
      jquery_migrate : {
        deps : [ 'jquery' ],
        exports : 'jQuery.migrateWarnings'
      },
      json2 : {
        exports : 'JSON'
      },
      underscore : {
        exports : '_'
      }
    }
  });
});
<commit_msg>Allowed loading text templates cross-domain.<commit_after>define(function() {
  require.config({
    enforceDefine : true,
    config: {
      text: {
          useXhr: function (url, protocol, hostname, port) {
            return true;
          }
      }
    },
    paths : {
      aura : 'components/aura/lib',
      backbone : 'components/backbone/backbone',
      bootstrap : 'components/bootstrap/docs/assets/js/bootstrap',
      bootstrap_datepicker : 'js/vendor/bootstrap/plugins/datepicker',
      bootstrap_lightbox : 'js/vendor/bootstrap/plugins/lightbox',
      bootstrap_tag : 'js/vendor/bootstrap/plugins/bootstrap-tag',
      eventemitter : 'components/eventemitter2/lib/eventemitter2',
      fuelux_datagrid : 'components/fuelux/dist/datagrid',
      jquery : 'components/jquery/jquery',
      jquery_migrate : 'components/jquery/jquery-migrate',
      json2 : 'components/json2/json2',
      'load-image' : 'js/vendor/bootstrap/plugins/load-image',
      moment : 'js/vendor/moment/moment',
      moment_pl : 'js/vendor/moment/moment-pl',
      text : 'components/requirejs-text/text',
      underscore : 'components/lodash/dist/lodash.underscore',

      extensions : 'js/extensions',

      legacy : 'js/widgets/legacy'
    },
    shim : {
      'aura/aura' : {
        deps : [ 'jquery', 'underscore', 'text', 'aura/ext/debug', 'aura/ext/mediator', 'aura/ext/widgets' ]
      },
      backbone : {
        deps : [ 'jquery', 'underscore' ],
        exports : 'Backbone'
      },
      bootstrap : {
        deps : [ 'jquery' ],
        exports : '$.fn.affix'
      },
      bootstrap_datepicker : {
        deps : [ 'bootstrap' ]
      },
      bootstrap_tag : {
        deps : [ 'bootstrap' ],
        exports : '$.fn.tag'
      },
      fuelux_datagrid : {
        deps : [ 'bootstrap' ]
      },
      jquery : {
        deps : [ 'json2' ]
      },
      jquery_migrate : {
        deps : [ 'jquery' ],
        exports : 'jQuery.migrateWarnings'
      },
      json2 : {
        exports : 'JSON'
      },
      underscore : {
        exports : '_'
      }
    }
  });
});
<|endoftext|>


<commit_before>(function() {
  'use strict';

  // Test file explorer.
  var explorer = window.Kloudless.explorer({
    app_id: window.app_id,
    multiselect: true,
    link: false,
    computer: true,
    services: ['all'],
    types: ['all'],
  });

  /* Uncomment the line below to test out event queueing
   * till the File Explorer is ready.
   */
  // explorer.choose();

  explorer.on('success', function(files) {
    console.log('Successfully chose files: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Files chosen:'));
    var data = document.createElement('pre');
    data.appendChild(document.createTextNode(
        JSON.stringify(files, null, 2)));
    result.appendChild(data);
    document.body.appendChild(result);
  });
  explorer.on('selected', function(files) {
    console.log('Selected files: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Files selected:'));
    var data = document.createElement('pre');
    data.appendChild(document.createTextNode(
        JSON.stringify(files, null, 2)));
    result.appendChild(data);
    document.body.appendChild(result);
  });
  explorer.on('startFileUpload', function(file) {
    console.log('File upload started:', file);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File upload started: ' + file.name));
    document.body.appendChild(result);
  });
  explorer.on('finishFileUpload', function(file) {
    console.log('File upload finished:', file);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File upload finished: ' + file.name));
    document.body.appendChild(result);
  });
  explorer.on('cancel', function() {
    console.log('File selection cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File selection cancelled!'));
    document.body.appendChild(result);
  });
  explorer.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in file selection!'));
    document.body.appendChild(result);
  });

  explorer.on('addAccount', function(account) {
    console.log('Succesfully added account: ', account);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Account added: ' +
        JSON.stringify(account)));
    document.body.appendChild(result);
  });

  explorer.on('deleteAccount', function(account) {
    console.log('Succesfully deleted account: ', account);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Deleted account: ' +
        JSON.stringify(account)));
    document.body.appendChild(result);
  });

  explorer.choosify(document.getElementById('file-test'));

  explorer.on('open', function() {
    console.log("File Explorer opened.");
  });

  explorer.on('close', function() {
    console.log("File Explorer closed.");
  });

  var cl = document.getElementById('close-test');
  cl.addEventListener('click', function() {
    explorer.close();
  });

  // Test second file explorer.
  var second = window.Kloudless.explorer({
    app_id: window.app_id,
    multiselect: true,
    link: false,
    computer: true,
    services: ['file_store'],
    types: ['folder']
  });

  second.on('success', function(files) {
    console.log('Successfully chose folder: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Folder selected: ' + JSON.stringify(files)));
    document.body.appendChild(result);
  });
  second.on('cancel', function() {
    console.log('Folder selection cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Folder selection cancelled!'));
    document.body.appendChild(result);
  });
  second.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in file selection!'));
    document.body.appendChild(result);
  });

  second.choosify(document.getElementById('folder-test'));

  // Test saver.
  var saver = window.Kloudless.explorer({
    app_id: window.app_id,
    flavor: 'saver',
    files: [{
      'url': 'https://dt8kf6553cww8.cloudfront.net/static/images/icons/blue_dropbox_glyph-vflJ8-C5d.png',
      'name': 'dropboxlogo.png'
    },{
      'url': 'http://upload.wikimedia.org/wikipedia/commons/7/75/Google_Drive_Logo.svg',
      'name': 'drivelogo.svg'
    }]
  });

  saver.on('success', function(files) {
    console.log('Successfully saved file: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Saved files: ' + JSON.stringify(files)));
    document.body.appendChild(result);
  });
  saver.on('cancel', function() {
    console.log('Save cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Save cancelled!'));
    document.body.appendChild(result);
  });
  saver.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in saving!'));
    document.body.appendChild(result);
  });

  saver.savify(document.getElementById('saver-test'));

})();
<commit_msg>Fixing second FE test server page."<commit_after>(function() {
  'use strict';

  // Test file explorer.
  var explorer = window.Kloudless.explorer({
    app_id: window.app_id,
    multiselect: true,
    link: false,
    computer: true,
    services: ['all'],
    types: ['all'],
  });

  /* Uncomment the line below to test out event queueing
   * till the File Explorer is ready.
   */
  // explorer.choose();

  explorer.on('success', function(files) {
    console.log('Successfully chose files: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Files chosen:'));
    var data = document.createElement('pre');
    data.appendChild(document.createTextNode(
        JSON.stringify(files, null, 2)));
    result.appendChild(data);
    document.body.appendChild(result);
  });
  explorer.on('selected', function(files) {
    console.log('Selected files: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Files selected:'));
    var data = document.createElement('pre');
    data.appendChild(document.createTextNode(
        JSON.stringify(files, null, 2)));
    result.appendChild(data);
    document.body.appendChild(result);
  });
  explorer.on('startFileUpload', function(file) {
    console.log('File upload started:', file);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File upload started: ' + file.name));
    document.body.appendChild(result);
  });
  explorer.on('finishFileUpload', function(file) {
    console.log('File upload finished:', file);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File upload finished: ' + file.name));
    document.body.appendChild(result);
  });
  explorer.on('cancel', function() {
    console.log('File selection cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('File selection cancelled!'));
    document.body.appendChild(result);
  });
  explorer.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in file selection!'));
    document.body.appendChild(result);
  });

  explorer.on('addAccount', function(account) {
    console.log('Succesfully added account: ', account);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Account added: ' +
        JSON.stringify(account)));
    document.body.appendChild(result);
  });

  explorer.on('deleteAccount', function(account) {
    console.log('Succesfully deleted account: ', account);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Deleted account: ' +
        JSON.stringify(account)));
    document.body.appendChild(result);
  });

  explorer.choosify(document.getElementById('file-test'));

  explorer.on('open', function() {
    console.log("File Explorer opened.");
  });

  explorer.on('close', function() {
    console.log("File Explorer closed.");
  });

  var cl = document.getElementById('close-test');
  cl.addEventListener('click', function() {
    explorer.close();
  });

  // Test second file explorer.
  var second = window.Kloudless.explorer({
    app_id: window.app_id,
    multiselect: true,
    link: false,
    computer: true,
    services: ['file_store'],
    types: ['folders']
  });

  second.on('success', function(files) {
    console.log('Successfully chose folder: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Folder selected: ' + JSON.stringify(files)));
    document.body.appendChild(result);
  });
  second.on('cancel', function() {
    console.log('Folder selection cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Folder selection cancelled!'));
    document.body.appendChild(result);
  });
  second.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in file selection!'));
    document.body.appendChild(result);
  });

  second.choosify(document.getElementById('folder-test'));

  // Test saver.
  var saver = window.Kloudless.explorer({
    app_id: window.app_id,
    flavor: 'saver',
    files: [{
      'url': 'https://dt8kf6553cww8.cloudfront.net/static/images/icons/blue_dropbox_glyph-vflJ8-C5d.png',
      'name': 'dropboxlogo.png'
    },{
      'url': 'http://upload.wikimedia.org/wikipedia/commons/7/75/Google_Drive_Logo.svg',
      'name': 'drivelogo.svg'
    }]
  });

  saver.on('success', function(files) {
    console.log('Successfully saved file: ', files);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Saved files: ' + JSON.stringify(files)));
    document.body.appendChild(result);
  });
  saver.on('cancel', function() {
    console.log('Save cancelled.');

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('Save cancelled!'));
    document.body.appendChild(result);
  });
  saver.on('error', function(error) {
    console.log('An error occurred: ', error);

    var result = document.createElement('p');
    result.appendChild(document.createTextNode('An error occurred in saving!'));
    document.body.appendChild(result);
  });

  saver.savify(document.getElementById('saver-test'));

})();
<|endoftext|>


<commit_before>"use strict";

var db = require('../models');

module.exports = function(app, options) {
  app.post('/authorized', function(req, res) {
    if (req.get('Content-Type').indexOf('application/x-www-form-urlencoded') !== 0) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    var accessToken = req.body.token;

    if (!accessToken) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    var serviceProviderId = req.body.service_provider_id;

    if (!serviceProviderId) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    var query = {
      token: accessToken,
      service_provider_id: serviceProviderId
    };

    db.ServiceAccessToken
      .find({ where: query })
      .then(function(accessToken) {
        if (accessToken) {
          res.json({
            client_id: accessToken.client_id,
            user_id:   accessToken.user_id
          });
        }
        else {
          res.send(401, { error: 'unauthorized' });
        }
      },
      function(error) {
        res.send(500);
      });
  });
};
<commit_msg>Client currently provides service provider name<commit_after>"use strict";

var db = require('../models');

module.exports = function(app, options) {
  app.post('/authorized', function(req, res) {
    if (req.get('Content-Type').indexOf('application/x-www-form-urlencoded') !== 0) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    var accessToken = req.body.token;

    if (!accessToken) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    var serviceProviderId = req.body.service_provider_id;

    if (!serviceProviderId) {
      res.json(400, { error: 'invalid_request' });
      return;
    }

    // TODO: do this in a single query?

    db.ServiceProvider
      .find({ where: { name: serviceProviderId } })
      .complete(function(err, serviceProvider) {
        if (err) {
          res.send(500);
          return;
        }

        if (!serviceProvider) {
          res.send(401, { error: 'unauthorized' });
          return;
        }

        var query = {
          token: accessToken,
          service_provider_id: serviceProvider.id
        };

        db.ServiceAccessToken
          .find({ where: query })
          .complete(function(err, accessToken) {
            if (err) {
              res.send(500);
              return;
            }

            if (!accessToken) {
              res.send(401, { error: 'unauthorized' });
              return;
            }

            res.json({
              client_id: accessToken.client_id,
              user_id:   accessToken.user_id
            });
          });
      });
  });
};
<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

import Sample from './Sample';

export default class Stats {
   hour = new Sample('hour');
   minute = new Sample('minute');
   day = new Sample('day');
   session = new Sample('session');
   startTime = new Date().getTime();
   options = {
      slowLimit: 1000
   };

   constructor(logger, options) {
      this.logger = logger;
      this.previous = {hour: this.hour, minute: this.minute, day: this.day};
      if (options) {
         Object.assign(this.options, options);
         this.startTime = options.startTime || this.startTime;
         if (options.monitorInterval) {
            this.intervalId = setInterval(async => {
               this.logger.debug('monitor', this.minute.publish());
            }, options.monitorInterval);
         }
      }
      this.minuteIntervalId = setInterval(async => {
         this.logger.info('minute', this.previous.minute.publish(), this.minute.publish());
         this.previous.minute = this.minute;
         this.minute = new Sample('minute');
      }, Millis.fromMinutes(1));
      this.hourIntervalId = setInterval(async => {
         this.log('hour', this.previous.hour);
         this.previous.hour = this.hour;
         this.hour = new Sample('hour');
      }, Millis.fromHours(1));
      this.dayIntervalId = setInterval(async => {
         this.log('day', this.previous.day);
         this.previous.day = this.day;
         this.day = new Sample('day');
      }, Millis.fromDays(1));
   }

   log(period, sample) {
      this.logger.info('log', period, {
         previous: sample.publish(),
         session: this.session.publish(),
         day: this.day.publish(),
         hour: this.hour.publish()
      });
   }

   publish(period) {
      if (period) {
         return {
            period: period,
            startTime: Dates.formatShortISO(this[period].startTime),
            current: this[period].publish(),
            previous: this.previous[period].publish(),
            session: this.session.publish(),
            day: this.day.publish(),
            previousPeriods: {
               day:this.previous.day.publish(),
               hour: this.previous.hour.publish(),
               minute: this.previous.minute.publish()
            }
         };
      } else {
         return {
            startTime: Dates.formatShortISO(this.startTime),
            session: this.session.publish(),
            day: this.day.publish(),
            hour: this.hour.publish(),
            minute: this.minute.publish(),
            previous: {
               day: this.previous.day.publish(),
               hour: this.previous.hour.publish(),
               minute: this.previous.minute.publish(),
            }
         };
      }
   }

   end() {
      if (this.monitorIntervalId) {
         clearInterval(this.monitorIntervalId);
      }
      clearInterval(this.minuteIntervalId);
      clearInterval(this.hourIntervalId);
      clearInterval(this.dayIntervalId);
   }

   incr(key) {
      this.hour.incr(key);
      this.minute.incr(key);
      this.day.incr(key);
      this.session.incr(key);
   }

   max(key, value) {
      this.hour.max(key);
      this.minute.max(key);
      this.day.max(key);
      this.session.max(key, value);
   }

   peak(key, value) {
      this.hour.peak(key);
      this.minute.peak(key);
      this.day.peak(key);
      this.session.peak(key, value);
   }

   time(key, options) {
      if (options) {
         if (Numbers.isInteger(options)) {
            options = Object.assign({startTime: options}, this.options);
         } else {
            options = Object.assign({startTime: this.startTime}, this.options, options);
         }
      } else {
         options = this.options;
      }
      this.hour.time(key, options);
      this.minute.time(key, options);
      this.day.time(key, options);
      this.session.time(key, options);
   }
}
<commit_msg>stats<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

import Sample from './Sample';

export default class Stats {
   hour = new Sample('hour');
   minute = new Sample('minute');
   day = new Sample('day');
   session = new Sample('session');
   startTime = new Date().getTime();
   options = {
      slowLimit: 1000
   };

   constructor(logger, options) {
      this.logger = logger;
      this.previous = {hour: this.hour, minute: this.minute, day: this.day};
      if (options) {
         Object.assign(this.options, options);
         this.startTime = options.startTime || this.startTime;
         if (options.monitorInterval) {
            this.intervalId = setInterval(async => {
               this.logger.debug('monitor', this.minute.publish());
            }, options.monitorInterval);
         }
      }
      this.minuteIntervalId = setInterval(async => {
         this.logger.info('minute', this.previous.minute.publish(), this.minute.publish());
         this.previous.minute = this.minute;
         this.minute = new Sample('minute');
      }, Millis.fromMinutes(1));
      this.hourIntervalId = setInterval(async => {
         this.log('hour', this.previous.hour);
         this.previous.hour = this.hour;
         this.hour = new Sample('hour');
      }, Millis.fromHours(1));
      this.dayIntervalId = setInterval(async => {
         this.log('day', this.previous.day);
         this.previous.day = this.day;
         this.day = new Sample('day');
      }, Millis.fromDays(1));
   }

   log(period, sample) {
      this.logger.info('log', period, {
         previous: sample.publish(),
         session: this.session.publish(),
         day: this.day.publish(),
         hour: this.hour.publish()
      });
   }

   publish(period) {
      if (period) {
         return {
            period: period,
            startTime: Dates.formatShortISO(this[period].startTime),
            currentTime: Dates.formatShortISO(new Date()),
            current: this[period].publish(),
            previous: this.previous[period].publish(),
            session: this.session.publish(),
            day: this.day.publish(),
            previousPeriods: {
               day:this.previous.day.publish(),
               hour: this.previous.hour.publish(),
               minute: this.previous.minute.publish()
            }
         };
      } else {
         return {
            startTime: Dates.formatShortISO(this.startTime),
            currentTime: Dates.formatShortISO(new Date()),
            session: this.session.publish(),
            day: this.day.publish(),
            hour: this.hour.publish(),
            minute: this.minute.publish(),
            previous: {
               day: this.previous.day.publish(),
               hour: this.previous.hour.publish(),
               minute: this.previous.minute.publish(),
            }
         };
      }
   }

   end() {
      if (this.monitorIntervalId) {
         clearInterval(this.monitorIntervalId);
      }
      clearInterval(this.minuteIntervalId);
      clearInterval(this.hourIntervalId);
      clearInterval(this.dayIntervalId);
   }

   incr(key) {
      this.hour.incr(key);
      this.minute.incr(key);
      this.day.incr(key);
      this.session.incr(key);
   }

   max(key, value) {
      this.hour.max(key);
      this.minute.max(key);
      this.day.max(key);
      this.session.max(key, value);
   }

   peak(key, value) {
      this.hour.peak(key);
      this.minute.peak(key);
      this.day.peak(key);
      this.session.peak(key, value);
   }

   time(key, options) {
      if (options) {
         if (Numbers.isInteger(options)) {
            options = Object.assign({startTime: options}, this.options);
         } else {
            options = Object.assign({startTime: this.startTime}, this.options, options);
         }
      } else {
         options = this.options;
      }
      this.hour.time(key, options);
      this.minute.time(key, options);
      this.day.time(key, options);
      this.session.time(key, options);
   }
}
<|endoftext|>


<commit_before>'use strict';
define(['ChoPidoTurnos', 'services/appointmentsService'], function(ChoPidoTurnos) {
  ChoPidoTurnos
    .controller('AppointmentSearchCtrl',
    ['$scope', '$stateParams', 'AppointmentsService', function($scope, $stateParams, appointmentService) {
      var _this = this;

      var _institution = $stateParams.institution || '';
      var _speciality = $stateParams.speciality || '';
      var _neighborhood = $stateParams.neighborhood || '';

      var groupBy = function(xs, f) {
        return xs.reduce(function(rv, x) {
          (rv[f(x)] = rv[f(x)] || []).push(x);
          return rv;
        }, {});
      };

      $scope.searchDateWeek = new Date();
      $scope.pageNumber = 0;
      console.log($scope);

      $scope.dayOfWeek = function(date) {
        switch (date.getDay()) {
          case 1: return 'Lunes';
          case 2: return 'Martes';
          case 3: return 'Miércoles';
          case 4: return 'Jueves';
          case 5: return 'Viernes';
          case 6: return 'Sabado';
          case 7: return 'Domingo';
          default: return '-';
        }
      };

      $scope.weekOfYear = function (d) {
       /* For a given date, get the ISO week number
        *
        * Based on information at:
        *
        *    http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
        *
        * Algorithm is to find nearest thursday, it's year
        * is the year of the week number. Then get weeks
        * between that date and the first day of that year.
        *
        * Note that dates in one year can be weeks of previous
        * or next year, overlap is up to 3 days.
        *
        * e.g. 2014/12/29 is Monday in week  1 of 2015
        *      2012/1/1   is Sunday in week 52 of 2011
        */
        // Copy date so don't modify original
        d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
        // Set to nearest Thursday: current date + 4 - current day number
        // Make Sunday's day number 7
        d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
        // Get first day of year
        var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
        // Calculate full weeks to nearest Thursday
        var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
        // Return array of year and week number
        return weekNo;
      };

      $scope.month = function (date) {
        return date.getMonth();
      };

      var searchAppointments = function () {
        var weekOfYear = $scope.weekOfYear($scope.searchDateWeek);
        var year = $scope.searchDateWeek.getFullYear();

        appointmentService
          .searchAppointments(_institution, _speciality, _neighborhood, weekOfYear, year, $scope.pageNumber)
          .then(function (data) {
            var page = data.data;
            var currentWeek = $scope.weekOfYear(new Date());
            var currentYear = new Date().getFullYear();

            $scope.page = page;

            $scope.appointmentsSearched = true;
            $scope.appointments = page.results;
            $scope.emptyAppointments = page.results.length === 0;
            $scope.hasPreviousPage = (weekOfYear > currentWeek && year >= currentYear) || page.page > 0;

            if (!$scope.emptyAppointments) {
              $scope.appointmentGroups = groupBy($scope.appointments, function (app) {
                var date = new Date(app.date);
                return new Date(date.getFullYear(), date.getMonth(), date.getDate());
              });

              $scope.appointmentDays = Object
                .keys($scope.appointmentGroups)
                .map(function (d) {
                  return new Date(d);
                })
                .sort();
            }
          });
      };

      searchAppointments();

      $scope.bookAppointment = function(appointment) {
        console.log(appointment);
      };

      $scope.prevPage = function () {
        if ($scope.pageNumber === 0) {
          $scope.searchDateWeek.setDate($scope.searchDateWeek.getDate() - 7);
          $scope.pageNumber = 0;
        } else {
          $scope.pageNumber--;
        }

        searchAppointments();
      };

      $scope.nextPage = function () {
        var endOfWeek = Math.floor($scope.page.total / $scope.page.pageSize) <= $scope.page.page;

        if (endOfWeek) {
          $scope.searchDateWeek.setDate($scope.searchDateWeek.getDate() + 7);
          $scope.pageNumber = 0;
        } else {
          $scope.pageNumber++;
        }

        searchAppointments();
      };
  }]);
});
<commit_msg>Fixes appointmentService injection typo<commit_after>'use strict';
define(['ChoPidoTurnos', 'services/appointmentsService'], function(ChoPidoTurnos) {
  ChoPidoTurnos
    .controller('AppointmentSearchCtrl',
    ['$scope', '$stateParams', 'appointmentsService', function($scope, $stateParams, appointmentService) {
      var _this = this;

      var _institution = $stateParams.institution || '';
      var _speciality = $stateParams.speciality || '';
      var _neighborhood = $stateParams.neighborhood || '';

      var groupBy = function(xs, f) {
        return xs.reduce(function(rv, x) {
          (rv[f(x)] = rv[f(x)] || []).push(x);
          return rv;
        }, {});
      };

      $scope.searchDateWeek = new Date();
      $scope.pageNumber = 0;
      console.log($scope);

      $scope.dayOfWeek = function(date) {
        switch (date.getDay()) {
          case 1: return 'Lunes';
          case 2: return 'Martes';
          case 3: return 'Miércoles';
          case 4: return 'Jueves';
          case 5: return 'Viernes';
          case 6: return 'Sabado';
          case 7: return 'Domingo';
          default: return '-';
        }
      };

      $scope.weekOfYear = function (d) {
       /* For a given date, get the ISO week number
        *
        * Based on information at:
        *
        *    http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
        *
        * Algorithm is to find nearest thursday, it's year
        * is the year of the week number. Then get weeks
        * between that date and the first day of that year.
        *
        * Note that dates in one year can be weeks of previous
        * or next year, overlap is up to 3 days.
        *
        * e.g. 2014/12/29 is Monday in week  1 of 2015
        *      2012/1/1   is Sunday in week 52 of 2011
        */
        // Copy date so don't modify original
        d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
        // Set to nearest Thursday: current date + 4 - current day number
        // Make Sunday's day number 7
        d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
        // Get first day of year
        var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
        // Calculate full weeks to nearest Thursday
        var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
        // Return array of year and week number
        return weekNo;
      };

      $scope.month = function (date) {
        return date.getMonth();
      };

      var searchAppointments = function () {
        var weekOfYear = $scope.weekOfYear($scope.searchDateWeek);
        var year = $scope.searchDateWeek.getFullYear();

        appointmentService
          .searchAppointments(_institution, _speciality, _neighborhood, weekOfYear, year, $scope.pageNumber)
          .then(function (data) {
            var page = data.data;
            var currentWeek = $scope.weekOfYear(new Date());
            var currentYear = new Date().getFullYear();

            $scope.page = page;

            $scope.appointmentsSearched = true;
            $scope.appointments = page.results;
            $scope.emptyAppointments = page.results.length === 0;
            $scope.hasPreviousPage = (weekOfYear > currentWeek && year >= currentYear) || page.page > 0;

            if (!$scope.emptyAppointments) {
              $scope.appointmentGroups = groupBy($scope.appointments, function (app) {
                var date = new Date(app.date);
                return new Date(date.getFullYear(), date.getMonth(), date.getDate());
              });

              $scope.appointmentDays = Object
                .keys($scope.appointmentGroups)
                .map(function (d) {
                  return new Date(d);
                })
                .sort();
            }
          });
      };

      searchAppointments();

      $scope.bookAppointment = function(appointment) {
        console.log(appointment);
      };

      $scope.prevPage = function () {
        if ($scope.pageNumber === 0) {
          $scope.searchDateWeek.setDate($scope.searchDateWeek.getDate() - 7);
          $scope.pageNumber = 0;
        } else {
          $scope.pageNumber--;
        }

        searchAppointments();
      };

      $scope.nextPage = function () {
        var endOfWeek = Math.floor($scope.page.total / $scope.page.pageSize) <= $scope.page.page;

        if (endOfWeek) {
          $scope.searchDateWeek.setDate($scope.searchDateWeek.getDate() + 7);
          $scope.pageNumber = 0;
        } else {
          $scope.pageNumber++;
        }

        searchAppointments();
      };
  }]);
});
<|endoftext|>


<commit_before>/**
 * @returns {Boolean} true if the specified value is not null and not undefined.
 */
function isValue (x) {
  return x !== null && x !== undefined
}

/**
 * @returns {Number} returns remainder of floored division, i.e., floor(a / n). Useful for consistent modulo
 *          of negative numbers. See http://en.wikipedia.org/wiki/Modulo_operation.
 */
function floorMod (a, n) {
  return a - n * Math.floor(a / n)
}

/**
 * @returns {Number} the value x clamped to the range [low, high].
 */
function clamp (x, min, max) {
  return Math.max(min, Math.min(x, max))
}

/**
 * @returns {Boolean} if the given point is inside the given bounding box e.g. [-180, -90, 180, 90].
 * This solution also takes in consideration a case in which the UI sends a box which crosses longitude 180/-180
 * (maps views on low zoom level where you can see the whole world, allow infinite cyclic horizontal scrolling,
 * so it is possible for example that a box's bottomLeft.lng=170 while topRight.lng=-170(=190) and by that including a range of 20 degrees
 */
function isInside (lon, lat, bounds) {
  let isLonInRange = (bounds[2] < bounds[0]
    ? lon >= bounds[0] || lon <= bounds[2]
    : lon >= bounds[0] && lon <= bounds[2])

  return lat >= bounds[1] && lat <= bounds[3] && isLonInRange
}

export class Grid {
  // Options are similar to those defining the forecast model + a data json array for grid point values
  // (bounds e.g. [-180, -90, 180, 90], e.g. origin: [-180, 90], e.g. size: [720, 361], e.g. resolution: [0.5, 0.5])
  constructor (options) {
    Object.assign(this, options)

    // Depending on the model longitude/latitude increases/decreases according to grid scanning
    this.lonDirection = (this.origin[0] === this.bounds[0] ? 1 : -1)
    this.latDirection = (this.origin[1] === this.bounds[1] ? 1 : -1)
    // Check for wrapped grids
    this.isContinuous = Math.floor(this.size[0] * this.resolution[0]) >= 360
  }

  getValue (i, j) {
    if (!this.data) return 0

    let index = i + j * this.size[0]
    if (index < this.data.length) {
      return this.data[index]
    } else {
      return undefined
    }
  }

  // bilinear interpolation
  bilinearInterpolate (x, y, g00, g10, g01, g11) {
    let rx = (1 - x)
    let ry = (1 - y)
    let a = rx * ry
    let b = x * ry
    let c = rx * y
    let d = x * y
    return g00 * a + g10 * b + g01 * c + g11 * d
  }

  /**
   * Get interpolated grid value from Lon/Lat position
   * @param lon {Float} Longitude
   * @param lat {Float} Latitude
   * @returns {Object}
   */
  interpolate (lon, lat) {
    if (!this.data) return undefined
    // Check for points outside bbox
    if (!isInside(lon, lat, this.bounds)) return undefined

    let i = this.lonDirection * floorMod(lon - this.origin[0], 360) / this.resolution[0]     // calculate longitude index in wrapped range [0, 360)
    let fi = Math.floor(i)
    let ci = fi + 1
    // In this case virtually duplicate first column as last column to simplify interpolation logic
    if (this.isContinuous && ci >= this.size[0]) {
      ci = 0
    }
    ci = clamp(ci, 0, this.size[0] - 1)

    let j = this.latDirection * (lat - this.origin[1]) / this.resolution[1]                  // calculate latitude index in direction +90 to -90
    let fj = Math.floor(j)
    let cj = clamp(fj + 1, 0, this.size[1] - 1)

    let g00 = this.getValue(fi, fj)
    let g10 = this.getValue(ci, fj)
    let g01 = this.getValue(fi, cj)
    let g11 = this.getValue(ci, cj)

    // All four points found, so interpolate the value
    if (isValue(g00) && isValue(g10) && isValue(g01) && isValue(g11)) {
      return this.bilinearInterpolate(i - fi, j - fj, g00, g10, g01, g11)
    } else {
      return undefined
    }
  }

  /**
   * Get a resampled version of the grid based on interpolated values
   * @param origin {Array} Origin in longitude/latitude of the new data
   * @param resolution {Array} Resolution in longitude/latitude of the new data
   * @param size {Array} Grid size in longitude/latitude of the new data
   * @returns {Array}
   */
  resample (origin, resolution, size) {
    let data = []
    for (let j = 0; j < size[1]; j++) {
      for (let i = 0; i < size[0]; i++) {
        // Offset by pixel center
        let lon = origin[0] + this.lonDirection * (i * resolution[0])
        let lat = origin[1] + this.latDirection * (j * resolution[1])
        let value = this.interpolate(lon, lat)
        data.push(value)
      }
    }
    return data
  }
}
<commit_msg>Fixed standard<commit_after>/**
 * @returns {Boolean} true if the specified value is not null and not undefined.
 */
function isValue (x) {
  return x !== null && x !== undefined
}

/**
 * @returns {Number} returns remainder of floored division, i.e., floor(a / n). Useful for consistent modulo
 *          of negative numbers. See http://en.wikipedia.org/wiki/Modulo_operation.
 */
function floorMod (a, n) {
  return a - n * Math.floor(a / n)
}

/**
 * @returns {Number} the value x clamped to the range [low, high].
 */
function clamp (x, min, max) {
  return Math.max(min, Math.min(x, max))
}

/**
 * @returns {Boolean} if the given point is inside the given bounding box e.g. [-180, -90, 180, 90].
 * This solution also takes in consideration a case in which the UI sends a box which crosses longitude 180/-180
 * (maps views on low zoom level where you can see the whole world, allow infinite cyclic horizontal scrolling,
 * so it is possible for example that a box's bottomLeft.lng=170 while topRight.lng=-170(=190) and by that including a range of 20 degrees
 */
function isInside (lon, lat, bounds) {
  let isLonInRange = (bounds[2] < bounds[0]
    ? lon >= bounds[0] || lon <= bounds[2]
    : lon >= bounds[0] && lon <= bounds[2])

  return lat >= bounds[1] && lat <= bounds[3] && isLonInRange
}

export class Grid {
  // Options are similar to those defining the forecast model + a data json array for grid point values
  // (bounds e.g. [-180, -90, 180, 90], e.g. origin: [-180, 90], e.g. size: [720, 361], e.g. resolution: [0.5, 0.5])
  constructor (options) {
    Object.assign(this, options)

    // Depending on the model longitude/latitude increases/decreases according to grid scanning
    this.lonDirection = (this.origin[0] === this.bounds[0] ? 1 : -1)
    this.latDirection = (this.origin[1] === this.bounds[1] ? 1 : -1)
    // Check for wrapped grids
    this.isContinuous = Math.floor(this.size[0] * this.resolution[0]) >= 360
  }

  getValue (i, j) {
    if (!this.data) return 0

    let index = i + j * this.size[0]
    if (index < this.data.length) {
      return this.data[index]
    } else {
      return undefined
    }
  }

  // bilinear interpolation
  bilinearInterpolate (x, y, g00, g10, g01, g11) {
    let rx = (1 - x)
    let ry = (1 - y)
    let a = rx * ry
    let b = x * ry
    let c = rx * y
    let d = x * y
    return g00 * a + g10 * b + g01 * c + g11 * d
  }

  /**
   * Get interpolated grid value from Lon/Lat position
   * @param lon {Float} Longitude
   * @param lat {Float} Latitude
   * @returns {Object}
   */
  interpolate (lon, lat) {
    if (!this.data) return undefined
    // Check for points outside bbox
    if (!isInside(lon, lat, this.bounds)) return undefined

    let i = this.lonDirection * floorMod(lon - this.origin[0], 360) / this.resolution[0]     // calculate longitude index in wrapped range [0, 360)
    let fi = Math.floor(i)
    let ci = fi + 1
    // In this case virtually duplicate first column as last column to simplify interpolation logic
    if (this.isContinuous && ci >= this.size[0]) {
      ci = 0
    }
    ci = clamp(ci, 0, this.size[0] - 1)

    let j = this.latDirection * (lat - this.origin[1]) / this.resolution[1]                  // calculate latitude index in direction +90 to -90
    let fj = Math.floor(j)
    let cj = clamp(fj + 1, 0, this.size[1] - 1)

    let g00 = this.getValue(fi, fj)
    let g10 = this.getValue(ci, fj)
    let g01 = this.getValue(fi, cj)
    let g11 = this.getValue(ci, cj)

    // All four points found, so interpolate the value
    if (isValue(g00) && isValue(g10) && isValue(g01) && isValue(g11)) {
      return this.bilinearInterpolate(i - fi, j - fj, g00, g10, g01, g11)
    } else {
      return undefined
    }
  }

  /**
   * Get a resampled version of the grid based on interpolated values
   * @param origin {Array} Origin in longitude/latitude of the new data
   * @param resolution {Array} Resolution in longitude/latitude of the new data
   * @param size {Array} Grid size in longitude/latitude of the new data
   * @returns {Array}
   */
  resample (origin, resolution, size) {
    let data = []
    for (let j = 0; j < size[1]; j++) {
      for (let i = 0; i < size[0]; i++) {
        // Offset by pixel center
        let lon = origin[0] + this.lonDirection * (i * resolution[0])
        let lat = origin[1] + this.latDirection * (j * resolution[1])
        let value = this.interpolate(lon, lat)
        data.push(value)
      }
    }
    return data
  }
}
<|endoftext|>


<commit_before>var PromisePipe = require('../src/PromisePipe')();
var PromisePipeServer = require('../src/PromisePipe')();
var PromisePipeWorker = require('../src/PromisePipe')();
PromisePipeServer.setEnv('server');
PromisePipeWorker.setEnv('worker');

var EventEmitter = require('events').EventEmitter;

var sinon = require('sinon');
var Promise = require('es6-promise').Promise;
var expect = require('chai').expect;

describe('PromisePipe when comes to chains from other env', function(){
	var context = {};
	var context1 = {};
	var context2 = {};
	var data1 = 1;
	var data2 = 2;
	var fn1 = sinon.stub();
	var fn2 = sinon.stub();
	var fn3 = sinon.stub();
	var fn4 = sinon.stub();
	var fn5 = sinon.stub();

	fn1.withArgs(data1).returns(data1);
	fn2.withArgs(data1).returns(data1);
	fn3.withArgs(data1).returns(data1);
	fn4.withArgs(data1).returns(data1);
	fn5.withArgs(data1).returns(data1);

	var serverSocketMock = new EventEmitter();
	var clientSocketMock = new EventEmitter();
	var workerSocketMock = new EventEmitter();

	function sendToClient(message){
		clientSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToServer(message){
		serverSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToWorker(message){
		workerSocketMock.emit('message', JSON.stringify(message));
	}

	PromisePipe.envTransition('client', 'server', function(message){
		sendToServer(message);
		return PromisePipe.promiseMessage(message);
	});

	PromisePipeServer.envTransition('server', 'worker', function(message){
		sendToWorker(message);
		return PromisePipeServer.promiseMessage(message);
	});

	clientSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipe.execTransitionMessage(message);
	});

	serverSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipeServer.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToClient(message);
		});
	});

	workerSocketMock.on('message', function(message){
		message = JSON.parse(message);

		PromisePipeWorker.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToServer(message);
		});
	});

	fn2._env = 'server';
	fn3._env = 'worker';
	fn4._env = 'server';

	var finish = sinon.spy();

	var pipe = PromisePipe()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeServer = PromisePipeServer()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeWorker = PromisePipeWorker()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	before(function(done){
		pipe(data1, context).then(finish);
		done()
	})
	it('should not fail', function(){
			sinon.assert.calledOnce(fn1);
			sinon.assert.calledOnce(fn2);
			sinon.assert.calledOnce(fn3);
			sinon.assert.calledOnce(fn4);
			sinon.assert.calledOnce(fn5);
			sinon.assert.calledWithExactly(finish, data1);
	})

	describe("server should also work fine", function(){
		before(function(done){
			pipeServer(data1, context1).then(finish);
			done()
		})
		it('should not fail', function(){
				sinon.assert.calledTwice(fn1);
				sinon.assert.calledTwice(fn2);
				sinon.assert.calledTwice(fn3);
				sinon.assert.calledTwice(fn4);
				sinon.assert.calledTwice(fn5);
				sinon.assert.calledWithExactly(finish, data1);
		})
	})

	xdescribe("should work if pseudo nested", function(){
		before(function(done){
			fn2._env = 'server';
			fn3._env = 'worker';
			fn4._env = 'worker';
			pipe(data1, context2).then(finish);
			done()
		})
		it('should not fail', function(){
				sinon.assert.calledThrice(fn1);
				sinon.assert.calledThrice(fn2);
				sinon.assert.calledThrice(fn3);
				sinon.assert.calledThrice(fn4);
				sinon.assert.calledThrice(fn5);
				sinon.assert.calledThrice(finish);
				sinon.assert.calledWithExactly(finish, data1);
		})
	})

})
<commit_msg>mute test to fix<commit_after>var PromisePipe = require('../src/PromisePipe')();
var PromisePipeServer = require('../src/PromisePipe')();
var PromisePipeWorker = require('../src/PromisePipe')();
PromisePipeServer.setEnv('server');
PromisePipeWorker.setEnv('worker');

var EventEmitter = require('events').EventEmitter;

var sinon = require('sinon');
var Promise = require('es6-promise').Promise;
var expect = require('chai').expect;

describe('PromisePipe when comes to chains from other env', function(){
	var context = {};
	var context1 = {};
	var context2 = {};
	var data1 = 1;
	var data2 = 2;
	var fn1 = sinon.stub();
	var fn2 = sinon.stub();
	var fn3 = sinon.stub();
	var fn4 = sinon.stub();
	var fn5 = sinon.stub();

	fn1.withArgs(data1).returns(data1);
	fn2.withArgs(data1).returns(data1);
	fn3.withArgs(data1).returns(data1);
	fn4.withArgs(data1).returns(data1);
	fn5.withArgs(data1).returns(data1);

	var serverSocketMock = new EventEmitter();
	var clientSocketMock = new EventEmitter();
	var workerSocketMock = new EventEmitter();

	function sendToClient(message){
		clientSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToServer(message){
		serverSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToWorker(message){
		workerSocketMock.emit('message', JSON.stringify(message));
	}

	PromisePipe.envTransition('client', 'server', function(message){
		sendToServer(message);
		return PromisePipe.promiseMessage(message);
	});

	PromisePipeServer.envTransition('server', 'worker', function(message){
		sendToWorker(message);
		return PromisePipeServer.promiseMessage(message);
	});

	clientSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipe.execTransitionMessage(message);
	});

	serverSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipeServer.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToClient(message);
		});
	});

	workerSocketMock.on('message', function(message){
		message = JSON.parse(message);

		PromisePipeWorker.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToServer(message);
		});
	});

	fn2._env = 'server';
	fn3._env = 'worker';
	fn4._env = 'server';

	var finish = sinon.spy();

	var pipe = PromisePipe()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeServer = PromisePipeServer()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeWorker = PromisePipeWorker()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	before(function(done){
		pipe(data1, context).then(finish);
		done()
	})
	it('should not fail', function(){
			sinon.assert.calledOnce(fn1);
			sinon.assert.calledOnce(fn2);
			sinon.assert.calledOnce(fn3);
			sinon.assert.calledOnce(fn4);
			sinon.assert.calledOnce(fn5);
			sinon.assert.calledWithExactly(finish, data1);
	})

	describe("server should also work fine", function(){
		before(function(done){
			pipeServer(data1, context1).then(finish);
			done()
		})
		it('should not fail', function(){
				sinon.assert.calledTwice(fn1);
				sinon.assert.calledTwice(fn2);
				sinon.assert.calledTwice(fn3);
				sinon.assert.calledTwice(fn4);
				sinon.assert.calledTwice(fn5);
				sinon.assert.calledWithExactly(finish, data1);
		})
	})
})

xdescribe('PromisePipe when comes to chains from other env', function(){
	var context = {};
	var context1 = {};
	var context2 = {};
	var data1 = 1;
	var data2 = 2;
	var fn1 = sinon.stub();
	var fn2 = sinon.stub();
	var fn3 = sinon.stub();
	var fn4 = sinon.stub();
	var fn5 = sinon.stub();

	fn1.withArgs(data1).returns(data1);
	fn2.withArgs(data1).returns(data1);
	fn3.withArgs(data1).returns(data1);
	fn4.withArgs(data1).returns(data1);
	fn5.withArgs(data1).returns(data1);

	var serverSocketMock = new EventEmitter();
	var clientSocketMock = new EventEmitter();
	var workerSocketMock = new EventEmitter();

	function sendToClient(message){
		clientSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToServer(message){
		serverSocketMock.emit('message', JSON.stringify(message));
	}

	function sendToWorker(message){
		workerSocketMock.emit('message', JSON.stringify(message));
	}

	PromisePipe.envTransition('client', 'server', function(message){
		sendToServer(message);
		return PromisePipe.promiseMessage(message);
	});

	PromisePipeServer.envTransition('server', 'worker', function(message){
		sendToWorker(message);
		return PromisePipeServer.promiseMessage(message);
	});

	clientSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipe.execTransitionMessage(message);
	});

	serverSocketMock.on('message', function(message){
		message = JSON.parse(message);
		PromisePipeServer.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToClient(message);
		});
	});

	workerSocketMock.on('message', function(message){
		message = JSON.parse(message);

		PromisePipeWorker.execTransitionMessage(message).then(function(data){
			message.data = data;
			sendToServer(message);
		});
	});

	fn2._env = 'server';
	fn3._env = 'worker';
	fn4._env = 'worker';
	fn5._env = 'worker';

	var finish = sinon.spy();

	var pipe = PromisePipe()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeServer = PromisePipeServer()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	var pipeWorker = PromisePipeWorker()
			.then(fn1)
			.then(fn2)
			.then(fn3)
			.then(fn4)
			.then(fn5);

	describe("should work if pseudo nested", function(){
		before(function(done){
			pipe(data1, context2).then(finish);
			done()
		})
		it('should not fail', function(){
				sinon.assert.calledOnce(fn1);
				sinon.assert.calledOnce(fn2);
				sinon.assert.calledOnce(fn3);
				sinon.assert.calledOnce(fn4);
				sinon.assert.calledOnce(fn5);
				sinon.assert.calledOnce(finish);
				sinon.assert.calledWithExactly(finish, data1);
		})
	})

})
<|endoftext|>


<commit_before>var schema = require('../schema')

var NumberSchema = module.exports = function(minimum, exclusiveMinimum, maximum, exclusiveMaximum) {
  this.minimum = minimum
  this.exclusiveMinimum = exclusiveMinimum
  this.maximum = maximum
  this.exclusiveMaximum = exclusiveMaximum

  return schema.call(this)
}

NumberSchema.prototype = {
  validate : function(instance) {
    if (!(Object(instance) instanceof Number)) return false

    if (this.minimum !== undefined) {
      if (instance < this.minimum || (this.exclusiveMinimum && instance == this.minimum)) return false
    }

    if (this.maximum !== undefined) {
      if (instance > this.maximum || (this.exclusiveMaximum && instance == this.maximum)) return false
    }

    return true
  },

  min : function(minimum) {
    return new NumberSchema(minimum, false, this.maximum, this.exclusiveMaximum)
  },

  above : function(minimum) {
    return new NumberSchema(minimum, true, this.maximum, this.exclusiveMaximum)
  },

  max : function(maximum) {
    return new NumberSchema(this.minimum, this.exclusiveMinimum, maximum, false)
  },

  below : function(maximum) {
    return new NumberSchema(this.minimum, this.exclusiveMinimum, maximum, true)
  },

  toJSON : function() {
    var schema = {}

    if (this.minimum !== undefined) {
      schema.minimum = this.minimum
      schema.exclusiveMinimum = (this.exclusiveMinimum === true)
    }

    if (this.maximum !== undefined) {
      schema.maximum = this.maximum
      schema.exclusiveMaximum = (this.exclusiveMaximum === true)
    }

    return schema
  }
}

Number.schema = new NumberSchema()
Number.min    = Number.schema.min
Number.above  = Number.schema.above
Number.max    = Number.schema.max
Number.below  = Number.schema.below
<commit_msg>Fix toJSON in Number extension.<commit_after>var schema = require('../schema')

var NumberSchema = module.exports = function(minimum, exclusiveMinimum, maximum, exclusiveMaximum) {
  this.minimum = minimum
  this.exclusiveMinimum = exclusiveMinimum
  this.maximum = maximum
  this.exclusiveMaximum = exclusiveMaximum

  return schema.call(this)
}

NumberSchema.prototype = {
  validate : function(instance) {
    if (!(Object(instance) instanceof Number)) return false

    if (this.minimum !== undefined) {
      if (instance < this.minimum || (this.exclusiveMinimum && instance == this.minimum)) return false
    }

    if (this.maximum !== undefined) {
      if (instance > this.maximum || (this.exclusiveMaximum && instance == this.maximum)) return false
    }

    return true
  },

  min : function(minimum) {
    return new NumberSchema(minimum, false, this.maximum, this.exclusiveMaximum)
  },

  above : function(minimum) {
    return new NumberSchema(minimum, true, this.maximum, this.exclusiveMaximum)
  },

  max : function(maximum) {
    return new NumberSchema(this.minimum, this.exclusiveMinimum, maximum, false)
  },

  below : function(maximum) {
    return new NumberSchema(this.minimum, this.exclusiveMinimum, maximum, true)
  },

  toJSON : function() {
    var schema = { type : 'number', required : true }

    if (this.minimum !== undefined) {
      schema.minimum = this.minimum
      schema.exclusiveMinimum = (this.exclusiveMinimum === true)
    }

    if (this.maximum !== undefined) {
      schema.maximum = this.maximum
      schema.exclusiveMaximum = (this.exclusiveMaximum === true)
    }

    return schema
  }
}

Number.schema = new NumberSchema()
Number.min    = Number.schema.min
Number.above  = Number.schema.above
Number.max    = Number.schema.max
Number.below  = Number.schema.below
<|endoftext|>


<commit_before>import { computed } from '@ember/object';

export default function(...args) {
  let func = args.pop();
  return computed(...args, {
    get(key) {
      return this[`_${key}`] || func.call(this, key);
    },
    set(key, value) {
      return this[`_${key}`] = value;
    }
  })
}
<commit_msg>fixed byDefault macro - it didn't work for falsy values<commit_after>import { computed } from '@ember/object';

export default function(...args) {
  let func = args.pop();
  return computed(...args, {
    get(key) {
      if (this[`_${key}IsSet`]) {
        return this[`_${key}`];
      } else {
        return func.call(this, key)
      }
    },
    set(key, value) {
      this[`_${key}IsSet`] = true;
      return this[`_${key}`] = value;
    }
  })
}
<|endoftext|>