<commit_before>const mergeDirs = require('merge-dirs').default;
const helpers = require('../../lib/helpers');
const path = require('path');
const shell = require('shelljs');
const latestVersion = require('latest-version');

module.exports = latestVersion('@storybook/react-native').then(version => {
  // copy all files from the template directory to project directory
  mergeDirs(path.resolve(__dirname, 'template/'), '.', 'overwrite');

  const packageJson = helpers.getPackageJson();

  packageJson.dependencies = packageJson.dependencies || {};
  packageJson.devDependencies = packageJson.devDependencies || {};

  packageJson.devDependencies['@storybook/react-native'] = `^${version}`;

  if (!packageJson.dependencies['react-dom'] && !packageJson.devDependencies['react-dom']) {
    packageJson.devDependencies['react-dom'] = '^15.5.4';
  }

  packageJson.scripts = packageJson.scripts || {};
  packageJson.scripts['storybook'] = 'storybook start -p 7007';

  helpers.writePackageJson(packageJson);
});
<commit_msg>Remove unused variable in CRNA<commit_after>const mergeDirs = require('merge-dirs').default;
const helpers = require('../../lib/helpers');
const path = require('path');
const latestVersion = require('latest-version');

module.exports = latestVersion('@storybook/react-native').then(version => {
  // copy all files from the template directory to project directory
  mergeDirs(path.resolve(__dirname, 'template/'), '.', 'overwrite');

  const packageJson = helpers.getPackageJson();

  packageJson.dependencies = packageJson.dependencies || {};
  packageJson.devDependencies = packageJson.devDependencies || {};

  packageJson.devDependencies['@storybook/react-native'] = `^${version}`;

  if (!packageJson.dependencies['react-dom'] && !packageJson.devDependencies['react-dom']) {
    packageJson.devDependencies['react-dom'] = '^15.5.4';
  }

  packageJson.scripts = packageJson.scripts || {};
  packageJson.scripts['storybook'] = 'storybook start -p 7007';

  helpers.writePackageJson(packageJson);
});
<|endoftext|>


<commit_before>'use strict';

var $ = require('jquery'),
	StickyScrollBarComponent = require('../../../js/StickyScrollBarComponent');

describe('StickyScrollBarComponent', function () {
	beforeEach(function() {
		this.$window = $('

');
        this.$window.height(500);

        // need to append html to window?
		this.$html = $('');
		this.$body = $('').appendTo(this.$html);
		this.$container = $(
			'
' +
			'
' +
			'		Some content' +
            '
' +
			'
'
		).appendTo(this.$body);

		this.stickyScrollBarComponent = new StickyScrollBarComponent(this.$window, this.$html);
	});

	afterEach(function () {
        this.$html.remove(); // Detach test DOM from the real one - NEEDED?
    });

    describe('On init', function() {

		beforeEach(function() {
			this.stickyScrollBarComponent.init(this.$container);
		});

		it('should run some tests');

		// it('should throw an error if $container isn't passed to the component');
		// it('should throw an error if $window isn't passed to the component');
		// it('should throw an error if $html isn't passed to the component');

		// it('should append the sticky scroll bar to the container', function () {
		// 	expect(this.$container.find('.sticky-scrollbar')).to.have.length(1);
		// });

		// it('should not display the sticky scroll bar when the window height is larger than the container', function () {
		// 	this.$container.height(200);

		// 	expect(this.$container.find('.sticky-scrollbar').hasClass('u-display-none')).to.be.true;
		// });

		// it('should display the sticky scroll bar when the content is larger than the window height', function () {
		// 	this.$container.height(600);

		// 	expect(this.$container.find('.sticky-scrollbar').hasClass('u-display-none')).to.be.false;
		// });

	})

	// describe('When the window is scrolled', function() {

	// })

	// describe('When the window is resized', function() {

	// })

	// describe('When the sticky scroll bar is shown and the content is scrolled', function() {

	// })

	// describe('When the sticky scroll bar is shown and the sticky scroll bar is scrolled', function() {

	// })
});
<commit_msg>Removed old test file due to issue with test files beginning with 'S' not running...<commit_after><|endoftext|>


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

import {dev, user} from './log';
import {getContextMetadata} from '../src/iframe-attributes';
import {tryParseJson} from './json';
import {getMode} from './mode';
import {dict} from './utils/object';
import {parseUrl, assertHttpsUrl} from './url';
import {urls} from './config';
import {setStyle} from './style';
import {startsWith} from './string';

/** @type {!Object<string,number>} Number of 3p frames on the for that type. */
let count = {};

/** @type {string} */
let overrideBootstrapBaseUrl;

/** @const {string} */
const TAG = '3p-frame';

/**
 * Produces the attributes for the ad template.
 * @param {!Window} parentWindow
 * @param {!AmpElement} element
 * @param {string=} opt_type
 * @param {Object=} opt_context
 * @return {!JsonObject} Contains
 *     - type, width, height, src attributes of <amp-ad> tag. These have
 *       precedence over the data- attributes.
 *     - data-* attributes of the <amp-ad> tag with the "data-" removed.
 *     - A _context object for internal use.
 */
function getFrameAttributes(parentWindow, element, opt_type, opt_context) {
  const type = opt_type || element.getAttribute('type');
  user().assert(type, 'Attribute type required for <amp-ad>: %s', element);
  const sentinel = generateSentinel(parentWindow);
  let attributes = dict();
  // Do these first, as the other attributes have precedence.
  addDataAndJsonAttributes_(element, attributes);
  attributes = getContextMetadata(parentWindow, element, sentinel,
      attributes);
  attributes['type'] = type;
  Object.assign(attributes['_context'], opt_context);
  return attributes;
}

/**
 * Creates the iframe for the embed. Applies correct size and passes the embed
 * attributes to the frame via JSON inside the fragment.
 * @param {!Window} parentWindow
 * @param {!AmpElement} parentElement
 * @param {string=} opt_type
 * @param {Object=} opt_context
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {!Element} The iframe.
 */
export function getIframe(
  parentWindow, parentElement, opt_type, opt_context, opt_disallowCustom) {
  // Check that the parentElement is already in DOM. This code uses a new and
  // fast `isConnected` API and thus only used when it's available.
  dev().assert(
      parentElement['isConnected'] === undefined ||
      parentElement['isConnected'] === true,
      'Parent element must be in DOM');
  const attributes =
      getFrameAttributes(parentWindow, parentElement, opt_type, opt_context);
  const iframe = parentWindow.document.createElement('iframe');

  if (!count[attributes['type']]) {
    count[attributes['type']] = 0;
  }
  count[attributes['type']] += 1;

  const baseUrl = getBootstrapBaseUrl(
      parentWindow, undefined, opt_type, opt_disallowCustom);
  const host = parseUrl(baseUrl).hostname;
  // This name attribute may be overwritten if this frame is chosen to
  // be the master frame. That is ok, as we will read the name off
  // for our uses before that would occur.
  // @see https://github.com/ampproject/amphtml/blob/master/3p/integration.js
  const name = JSON.stringify(dict({
    'host': host,
    'type': attributes['type'],
    // https://github.com/ampproject/amphtml/pull/2955
    'count': count[attributes['type']],
    'attributes': attributes,
  }));

  iframe.src = baseUrl;
  iframe.ampLocation = parseUrl(baseUrl);
  iframe.name = name;
  // Add the check before assigning to prevent IE throw Invalid argument error
  if (attributes['width']) {
    iframe.width = attributes['width'];
  }
  if (attributes['height']) {
    iframe.height = attributes['height'];
  }
  iframe.setAttribute('scrolling', 'no');
  setStyle(iframe, 'border', 'none');
  /** @this {!Element} */
  iframe.onload = function() {
    // Chrome does not reflect the iframe readystate.
    this.readyState = 'complete';
  };
  iframe.setAttribute('data-amp-3p-sentinel',
      attributes['_context']['sentinel']);
  return iframe;
}

/**
 * Copies data- attributes from the element into the attributes object.
 * Removes the data- from the name and capitalizes after -. If there
 * is an attribute called json, parses the JSON and adds it to the
 * attributes.
 * @param {!Element} element
 * @param {!JsonObject} attributes The destination.
 * visibleForTesting
 */
export function addDataAndJsonAttributes_(element, attributes) {
  const dataset = element.dataset;
  for (const name in dataset) {
    // data-vars- is reserved for amp-analytics
    // see https://github.com/ampproject/amphtml/blob/master/extensions/amp-analytics/analytics-vars.md#variables-as-data-attribute
    if (!startsWith(name, 'vars')) {
      attributes[name] = dataset[name];
    }
  }
  const json = element.getAttribute('json');
  if (json) {
    const obj = tryParseJson(json);
    if (obj === undefined) {
      throw user().createError(
          'Error parsing JSON in json attribute in element %s',
          element);
    }
    for (const key in obj) {
      attributes[key] = obj[key];
    }
  }
}

/**
 * Preloads URLs related to the bootstrap iframe.
 * @param {!Window} win
 * @param {!./preconnect.Preconnect} preconnect
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 */
export function preloadBootstrap(
  win, preconnect, opt_type, opt_disallowCustom) {
  const url = getBootstrapBaseUrl(win, undefined, opt_type, opt_disallowCustom);
  preconnect.preload(url, 'document');

  // While the URL may point to a custom domain, this URL will always be
  // fetched by it.
  const scriptUrl = getMode().localDev
    ? getAdsLocalhost(win) + '/dist.3p/current/integration.js'
    : `${urls.thirdParty}/$internalRuntimeVersion$/f.js`;
  preconnect.preload(scriptUrl, 'script');
}

/**
 * Returns the base URL for 3p bootstrap iframes.
 * @param {!Window} parentWindow
 * @param {boolean=} opt_strictForUnitTest
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {string}
 * @visibleForTesting
 */
export function getBootstrapBaseUrl(
  parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) {
  // The value is cached in a global variable called `bootstrapBaseUrl`;
  const bootstrapBaseUrl = parentWindow.bootstrapBaseUrl;
  if (bootstrapBaseUrl) {
    return bootstrapBaseUrl;
  }
  return parentWindow.bootstrapBaseUrl = getCustomBootstrapBaseUrl(
      parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) ||
      getDefaultBootstrapBaseUrl(parentWindow);
}

export function setDefaultBootstrapBaseUrlForTesting(url) {
  overrideBootstrapBaseUrl = url;
}

export function resetBootstrapBaseUrlForTesting(win) {
  win.bootstrapBaseUrl = undefined;
  win.defaultBootstrapSubDomain = undefined;
}

/**
 * Returns the default base URL for 3p bootstrap iframes.
 * @param {!Window} parentWindow
 * @param {string=} opt_srcFileBasename
 * @return {string}
 */
export function getDefaultBootstrapBaseUrl(parentWindow, opt_srcFileBasename) {
  const srcFileBasename = opt_srcFileBasename || 'frame';
  if (getMode().localDev || getMode().test) {
    return overrideBootstrapBaseUrl || getAdsLocalhost(parentWindow)
          + '/dist.3p/'
          + (getMode().minified ? `$internalRuntimeVersion$/${srcFileBasename}`
            : `current/${srcFileBasename}.max`)
          + '.html';
  }
  // Ensure same sub-domain is used despite potentially different file.
  parentWindow.defaultBootstrapSubDomain =
      parentWindow.defaultBootstrapSubDomain || getSubDomain(parentWindow);
  return 'https://' + parentWindow.defaultBootstrapSubDomain +
      `.${urls.thirdPartyFrameHost}/$internalRuntimeVersion$/` +
      `${srcFileBasename}.html`;
}

function getAdsLocalhost(win) {
  if (urls.localDev) {
    return `//${urls.thirdPartyFrameHost}`;
  }
  return 'http://ads.localhost:'
      + (win.location.port || win.parent.location.port);
}

/**
 * Sub domain on which the 3p iframe will be hosted.
 * Because we only calculate the URL once per page, this function is only
 * called once and hence all frames on a page use the same URL.
 * @return {string}
 * @visibleForTesting
 */
export function getSubDomain(win) {
  return 'd-' + getRandom(win);
}

/**
 * Generates a random non-negative integer.
 * @param {!Window} win
 * @return {string}
 */
export function getRandom(win) {
  let rand;
  if (win.crypto && win.crypto.getRandomValues) {
    // By default use 2 32 bit integers.
    const uint32array = new Uint32Array(2);
    win.crypto.getRandomValues(uint32array);
    rand = String(uint32array[0]) + uint32array[1];
  } else {
    // Fall back to Math.random.
    rand = String(win.Math.random()).substr(2) + '0';
  }
  return rand;
}

/**
 * Returns the custom base URL for 3p bootstrap iframes if it exists.
 * Otherwise null.
 * @param {!Window} parentWindow
 * @param {boolean=} opt_strictForUnitTest
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {?string}
 */
function getCustomBootstrapBaseUrl(
  parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) {
  const meta = parentWindow.document
      .querySelector('meta[name="amp-3p-iframe-src"]');
  if (!meta) {
    return null;
  }
  if (opt_disallowCustom) {
    user().error(TAG, `3p iframe url disabled for ${opt_type || 'unknown'}`);
    return null;
  }
  const url = assertHttpsUrl(meta.getAttribute('content'), meta);
  user().assert(url.indexOf('?') == -1,
      '3p iframe url must not include query string %s in element %s.',
      url, meta);
  // This is not a security primitive, we just don't want this to happen in
  // practice. People could still redirect to the same origin, but they cannot
  // redirect to the proxy origin which is the important one.
  const parsed = parseUrl(url);
  user().assert((parsed.hostname == 'localhost' && !opt_strictForUnitTest) ||
      parsed.origin != parseUrl(parentWindow.location.href).origin,
  '3p iframe url must not be on the same origin as the current doc' +
      'ument %s (%s) in element %s. See https://github.com/ampproject/amphtml' +
      '/blob/master/spec/amp-iframe-origin-policy.md for details.', url,
  parsed.origin, meta);
  return url + '?$internalRuntimeVersion$';
}

/**
 * Returns a randomized sentinel value for 3p iframes.
 * The format is "%d-%d" with the first value being the depth of current
 * window in the window hierarchy and the second a random integer.
 * @param {!Window} parentWindow
 * @return {string}
 * @visibleForTesting
 */
export function generateSentinel(parentWindow) {
  let windowDepth = 0;
  for (let win = parentWindow; win && win != win.parent; win = win.parent) {
    windowDepth++;
  }
  return String(windowDepth) + '-' + getRandom(parentWindow);
}

/**
 * Resets the count of each 3p frame type
 * @visibleForTesting
 */
export function resetCountForTesting() {
  count = {};
}
<commit_msg>Fix 3P ad frame for local development (#12458)<commit_after>/**
 * Copyright 2015 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {dev, user} from './log';
import {getContextMetadata} from '../src/iframe-attributes';
import {tryParseJson} from './json';
import {getMode} from './mode';
import {dict} from './utils/object';
import {parseUrl, assertHttpsUrl} from './url';
import {urls} from './config';
import {setStyle} from './style';
import {startsWith} from './string';

/** @type {!Object<string,number>} Number of 3p frames on the for that type. */
let count = {};

/** @type {string} */
let overrideBootstrapBaseUrl;

/** @const {string} */
const TAG = '3p-frame';

/**
 * Produces the attributes for the ad template.
 * @param {!Window} parentWindow
 * @param {!AmpElement} element
 * @param {string=} opt_type
 * @param {Object=} opt_context
 * @return {!JsonObject} Contains
 *     - type, width, height, src attributes of <amp-ad> tag. These have
 *       precedence over the data- attributes.
 *     - data-* attributes of the <amp-ad> tag with the "data-" removed.
 *     - A _context object for internal use.
 */
function getFrameAttributes(parentWindow, element, opt_type, opt_context) {
  const type = opt_type || element.getAttribute('type');
  user().assert(type, 'Attribute type required for <amp-ad>: %s', element);
  const sentinel = generateSentinel(parentWindow);
  let attributes = dict();
  // Do these first, as the other attributes have precedence.
  addDataAndJsonAttributes_(element, attributes);
  attributes = getContextMetadata(parentWindow, element, sentinel,
      attributes);
  attributes['type'] = type;
  Object.assign(attributes['_context'], opt_context);
  return attributes;
}

/**
 * Creates the iframe for the embed. Applies correct size and passes the embed
 * attributes to the frame via JSON inside the fragment.
 * @param {!Window} parentWindow
 * @param {!AmpElement} parentElement
 * @param {string=} opt_type
 * @param {Object=} opt_context
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {!Element} The iframe.
 */
export function getIframe(
  parentWindow, parentElement, opt_type, opt_context, opt_disallowCustom) {
  // Check that the parentElement is already in DOM. This code uses a new and
  // fast `isConnected` API and thus only used when it's available.
  dev().assert(
      parentElement['isConnected'] === undefined ||
      parentElement['isConnected'] === true,
      'Parent element must be in DOM');
  const attributes =
      getFrameAttributes(parentWindow, parentElement, opt_type, opt_context);
  const iframe = parentWindow.document.createElement('iframe');

  if (!count[attributes['type']]) {
    count[attributes['type']] = 0;
  }
  count[attributes['type']] += 1;

  const baseUrl = getBootstrapBaseUrl(
      parentWindow, undefined, opt_type, opt_disallowCustom);
  const host = parseUrl(baseUrl).hostname;
  // This name attribute may be overwritten if this frame is chosen to
  // be the master frame. That is ok, as we will read the name off
  // for our uses before that would occur.
  // @see https://github.com/ampproject/amphtml/blob/master/3p/integration.js
  const name = JSON.stringify(dict({
    'host': host,
    'type': attributes['type'],
    // https://github.com/ampproject/amphtml/pull/2955
    'count': count[attributes['type']],
    'attributes': attributes,
  }));

  iframe.src = baseUrl;
  iframe.ampLocation = parseUrl(baseUrl);
  iframe.name = name;
  // Add the check before assigning to prevent IE throw Invalid argument error
  if (attributes['width']) {
    iframe.width = attributes['width'];
  }
  if (attributes['height']) {
    iframe.height = attributes['height'];
  }
  iframe.setAttribute('scrolling', 'no');
  setStyle(iframe, 'border', 'none');
  /** @this {!Element} */
  iframe.onload = function() {
    // Chrome does not reflect the iframe readystate.
    this.readyState = 'complete';
  };
  iframe.setAttribute('data-amp-3p-sentinel',
      attributes['_context']['sentinel']);
  return iframe;
}

/**
 * Copies data- attributes from the element into the attributes object.
 * Removes the data- from the name and capitalizes after -. If there
 * is an attribute called json, parses the JSON and adds it to the
 * attributes.
 * @param {!Element} element
 * @param {!JsonObject} attributes The destination.
 * visibleForTesting
 */
export function addDataAndJsonAttributes_(element, attributes) {
  const dataset = element.dataset;
  for (const name in dataset) {
    // data-vars- is reserved for amp-analytics
    // see https://github.com/ampproject/amphtml/blob/master/extensions/amp-analytics/analytics-vars.md#variables-as-data-attribute
    if (!startsWith(name, 'vars')) {
      attributes[name] = dataset[name];
    }
  }
  const json = element.getAttribute('json');
  if (json) {
    const obj = tryParseJson(json);
    if (obj === undefined) {
      throw user().createError(
          'Error parsing JSON in json attribute in element %s',
          element);
    }
    for (const key in obj) {
      attributes[key] = obj[key];
    }
  }
}

/**
 * Preloads URLs related to the bootstrap iframe.
 * @param {!Window} win
 * @param {!./preconnect.Preconnect} preconnect
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 */
export function preloadBootstrap(
  win, preconnect, opt_type, opt_disallowCustom) {
  const url = getBootstrapBaseUrl(win, undefined, opt_type, opt_disallowCustom);
  preconnect.preload(url, 'document');

  // While the URL may point to a custom domain, this URL will always be
  // fetched by it.
  const scriptUrl = getMode().localDev
    ? getAdsLocalhost(win) + '/dist.3p/current/integration.js'
    : `${urls.thirdParty}/$internalRuntimeVersion$/f.js`;
  preconnect.preload(scriptUrl, 'script');
}

/**
 * Returns the base URL for 3p bootstrap iframes.
 * @param {!Window} parentWindow
 * @param {boolean=} opt_strictForUnitTest
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {string}
 * @visibleForTesting
 */
export function getBootstrapBaseUrl(
  parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) {
  // The value is cached in a global variable called `bootstrapBaseUrl`;
  const bootstrapBaseUrl = parentWindow.bootstrapBaseUrl;
  if (bootstrapBaseUrl) {
    return bootstrapBaseUrl;
  }
  return parentWindow.bootstrapBaseUrl = getCustomBootstrapBaseUrl(
      parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) ||
      getDefaultBootstrapBaseUrl(parentWindow);
}

export function setDefaultBootstrapBaseUrlForTesting(url) {
  overrideBootstrapBaseUrl = url;
}

export function resetBootstrapBaseUrlForTesting(win) {
  win.bootstrapBaseUrl = undefined;
  win.defaultBootstrapSubDomain = undefined;
}

/**
 * Returns the default base URL for 3p bootstrap iframes.
 * @param {!Window} parentWindow
 * @param {string=} opt_srcFileBasename
 * @return {string}
 */
export function getDefaultBootstrapBaseUrl(parentWindow, opt_srcFileBasename) {
  const srcFileBasename = opt_srcFileBasename || 'frame';
  if (getMode().localDev || getMode().test) {
    return overrideBootstrapBaseUrl || getAdsLocalhost(parentWindow)
          + '/dist.3p/'
          + (getMode().minified ? `$internalRuntimeVersion$/${srcFileBasename}`
            : `current/${srcFileBasename}.max`)
          + '.html';
  }
  // Ensure same sub-domain is used despite potentially different file.
  parentWindow.defaultBootstrapSubDomain =
      parentWindow.defaultBootstrapSubDomain || getSubDomain(parentWindow);
  return 'https://' + parentWindow.defaultBootstrapSubDomain +
      `.${urls.thirdPartyFrameHost}/$internalRuntimeVersion$/` +
      `${srcFileBasename}.html`;
}

function getAdsLocalhost(win) {
  return 'http://ads.localhost:'
      + (win.location.port || win.parent.location.port);
}

/**
 * Sub domain on which the 3p iframe will be hosted.
 * Because we only calculate the URL once per page, this function is only
 * called once and hence all frames on a page use the same URL.
 * @return {string}
 * @visibleForTesting
 */
export function getSubDomain(win) {
  return 'd-' + getRandom(win);
}

/**
 * Generates a random non-negative integer.
 * @param {!Window} win
 * @return {string}
 */
export function getRandom(win) {
  let rand;
  if (win.crypto && win.crypto.getRandomValues) {
    // By default use 2 32 bit integers.
    const uint32array = new Uint32Array(2);
    win.crypto.getRandomValues(uint32array);
    rand = String(uint32array[0]) + uint32array[1];
  } else {
    // Fall back to Math.random.
    rand = String(win.Math.random()).substr(2) + '0';
  }
  return rand;
}

/**
 * Returns the custom base URL for 3p bootstrap iframes if it exists.
 * Otherwise null.
 * @param {!Window} parentWindow
 * @param {boolean=} opt_strictForUnitTest
 * @param {string=} opt_type
 * @param {boolean=} opt_disallowCustom whether 3p url should not use meta tag.
 * @return {?string}
 */
function getCustomBootstrapBaseUrl(
  parentWindow, opt_strictForUnitTest, opt_type, opt_disallowCustom) {
  const meta = parentWindow.document
      .querySelector('meta[name="amp-3p-iframe-src"]');
  if (!meta) {
    return null;
  }
  if (opt_disallowCustom) {
    user().error(TAG, `3p iframe url disabled for ${opt_type || 'unknown'}`);
    return null;
  }
  const url = assertHttpsUrl(meta.getAttribute('content'), meta);
  user().assert(url.indexOf('?') == -1,
      '3p iframe url must not include query string %s in element %s.',
      url, meta);
  // This is not a security primitive, we just don't want this to happen in
  // practice. People could still redirect to the same origin, but they cannot
  // redirect to the proxy origin which is the important one.
  const parsed = parseUrl(url);
  user().assert((parsed.hostname == 'localhost' && !opt_strictForUnitTest) ||
      parsed.origin != parseUrl(parentWindow.location.href).origin,
  '3p iframe url must not be on the same origin as the current doc' +
      'ument %s (%s) in element %s. See https://github.com/ampproject/amphtml' +
      '/blob/master/spec/amp-iframe-origin-policy.md for details.', url,
  parsed.origin, meta);
  return url + '?$internalRuntimeVersion$';
}

/**
 * Returns a randomized sentinel value for 3p iframes.
 * The format is "%d-%d" with the first value being the depth of current
 * window in the window hierarchy and the second a random integer.
 * @param {!Window} parentWindow
 * @return {string}
 * @visibleForTesting
 */
export function generateSentinel(parentWindow) {
  let windowDepth = 0;
  for (let win = parentWindow; win && win != win.parent; win = win.parent) {
    windowDepth++;
  }
  return String(windowDepth) + '-' + getRandom(parentWindow);
}

/**
 * Resets the count of each 3p frame type
 * @visibleForTesting
 */
export function resetCountForTesting() {
  count = {};
}
<|endoftext|>


<commit_before>/**
 * @flow
 */

import ProgressBar from 'progress';
import _ from 'lodash';
import bunyan from '@expo/bunyan';
import chalk from 'chalk';
import glob from 'glob';
import fs from 'fs';
import path from 'path';
import simpleSpinner from '@expo/simple-spinner';
import url from 'url';

import program, { Command } from 'commander';
import {
  Analytics,
  Binaries,
  Config,
  Doctor,
  Logger,
  PackagerLogsStream,
  NotificationCode,
  Project,
  ProjectUtils,
  User as UserManager,
} from 'xdl';

import { loginOrRegisterIfLoggedOut } from './accounts';
import log from './log';
import update from './update';
import urlOpts from './urlOpts';
import addCommonOptions from './commonOptions';
import packageJSON from '../package.json';

if (process.env.NODE_ENV === 'development') {
  require('source-map-support').install();
}

// The following prototyped functions are not used here, but within in each file found in `./commands`
// Extending commander to easily add more options to certain command line arguments
Command.prototype.urlOpts = function() {
  urlOpts.addOptions(this);
  return this;
};

Command.prototype.allowOffline = function() {
  this.option('--offline', 'Allows this command to run while offline');
  return this;
};

Command.prototype.allowNonInteractive = function() {
  this.option('--non-interactive', 'Fails if an interactive prompt would be required to continue.');
  return this;
};

// asyncAction is a wrapper for all commands/actions to be executed after commander is done
// parsing the command input
Command.prototype.asyncAction = function(asyncFn, skipUpdateCheck) {
  addCommonOptions(this);
  return this.action(async (...args) => {
    if (!skipUpdateCheck) {
      try {
        await checkForUpdateAsync();
      } catch (e) {}
    }

    try {
      let options = _.last(args);
      if (options.output === 'raw') {
        log.config.raw = true;
      }
      if (options.offline) {
        Config.offline = true;
      }
      await asyncFn(...args);
      // After a command, flush the analytics queue so the program will not have any active timers
      // This allows node js to exit immediately
      Analytics.flush();
    } catch (err) {
      // TODO: Find better ways to consolidate error messages
      if (err._isCommandError) {
        log.error(err.message);
      } else if (err._isApiError) {
        log.error(chalk.red(err.message));
      } else if (err.isXDLError) {
        log.error(err.message);
      } else {
        log.error(err.message);
        // TODO: Is there a better way to do this? EXPO_DEBUG needs to be set to view the stack trace
        if (process.env.EXPO_DEBUG) {
          log.error(chalk.gray(err.stack));
        } else {
          log.error(chalk.grey('Set EXPO_DEBUG=true in your env to view the stack trace.'));
        }
      }

      process.exit(1);
    }
  });
};

// asyncActionProjectDir captures the projectDirectory from the command line,
// setting it to cwd if it is not provided.
// Commands such as `start` and `publish` use this.
// It does several things:
// - Everything in asyncAction
// - Checks if the user is logged in or out
// - Checks for updates
// - Attaches the bundling logger
// - Checks if the project directory is valid or not
// - Runs AsyncAction with the projectDir as an argument
Command.prototype.asyncActionProjectDir = function(asyncFn, skipProjectValidation, skipAuthCheck) {
  return this.asyncAction(async (projectDir, ...args) => {
    try {
      await checkForUpdateAsync();
    } catch (e) {}

    const opts = args[0];
    if (!skipAuthCheck && !opts.nonInteractive && !opts.offline) {
      await loginOrRegisterIfLoggedOut();
    }

    if (!skipAuthCheck) {
      await UserManager.ensureLoggedInAsync();
    }

    if (!projectDir) {
      projectDir = process.cwd();
    } else {
      projectDir = path.resolve(process.cwd(), projectDir);
    }

    if (opts.config) {
      const pathToConfig = path.resolve(process.cwd(), opts.config);
      if (!fs.existsSync(pathToConfig)) {
        throw new Error(`File at provide config path does not exist: ${pathToConfig}`);
      }
      ProjectUtils.setCustomConfigPath(projectDir, pathToConfig);
    }

    const logLines = (msg, logFn) => {
      for (let line of msg.split('\n')) {
        logFn(line);
      }
    };

    const logStackTrace = (chunk, logFn, nestedLogFn) => {
      let traceInfo;
      try {
        traceInfo = JSON.parse(chunk.msg);
      } catch (e) {
        return logFn(chunk.msg);
      }

      let { message, stack } = traceInfo;
      log.addNewLineIfNone();
      logFn(chalk.bold(message));

      const isLibraryFrame = line => {
        return line.startsWith('node_modules');
      };

      let stackFrames = _.compact(stack.split('\n'));
      let lastAppCodeFrameIndex = _.findLastIndex(stackFrames, line => {
        return !isLibraryFrame(line);
      });
      let lastFrameIndexToLog = Math.min(
        stackFrames.length - 1,
        lastAppCodeFrameIndex + 2 // show max two more frames after last app code frame
      );
      let unloggedFrames = stackFrames.length - lastFrameIndexToLog;

      // If we're only going to exclude one frame, just log them all
      if (unloggedFrames === 1) {
        lastFrameIndexToLog = stackFrames.length - 1;
        unloggedFrames = 0;
      }

      for (let i = 0; i <= lastFrameIndexToLog; i++) {
        let line = stackFrames[i];
        if (!line) {
          continue;
        } else if (line.match(/react-native\/.*YellowBox.js/)) {
          continue;
        }

        if (line.startsWith('node_modules')) {
          nestedLogFn('- ' + line);
        } else {
          nestedLogFn('* ' + line);
        }
      }

      if (unloggedFrames > 0) {
        nestedLogFn(`- ... ${unloggedFrames} more stack frames from framework internals`);
      }

      log.printNewLineBeforeNextLog();
    };

    const logWithLevel = chunk => {
      if (!chunk.msg) {
        return;
      }
      if (chunk.level <= bunyan.INFO) {
        if (chunk.includesStack) {
          logStackTrace(chunk, log, log.nested);
        } else {
          logLines(chunk.msg, log);
        }
      } else if (chunk.level === bunyan.WARN) {
        if (chunk.includesStack) {
          logStackTrace(chunk, log.warn, log.nestedWarn);
        } else {
          logLines(chunk.msg, log.warn);
        }
      } else {
        if (chunk.includesStack) {
          logStackTrace(chunk, log.error, log.nestedError);
        } else {
          logLines(chunk.msg, log.error);
        }
      }
    };

    let bar;
    let packagerLogsStream = new PackagerLogsStream({
      projectRoot: projectDir,
      onStartBuildBundle: () => {
        bar = new ProgressBar('Building JavaScript bundle [:bar] :percent', {
          total: 100,
          clear: true,
          complete: '=',
          incomplete: ' ',
        });

        log.setBundleProgressBar(bar);
      },
      onProgressBuildBundle: percent => {
        if (!bar || bar.complete) return;
        let ticks = percent - bar.curr;
        ticks > 0 && bar.tick(ticks);
      },
      onFinishBuildBundle: (err, startTime: Date, endTime: Date) => {
        if (bar && !bar.complete) {
          bar.tick(100 - bar.curr);
        }

        if (bar) {
          log.setBundleProgressBar(null);
          bar = null;

          if (err) {
            log(chalk.red('Failed building JavaScript bundle.'));
          } else {
            log(chalk.green(`Finished building JavaScript bundle in ${endTime - startTime}ms.`));
          }
        }
      },
      updateLogs: updater => {
        let newLogChunks = updater([]);
        newLogChunks.forEach(newLogChunk => {
          logWithLevel(newLogChunk);
        });
      },
    });

    // needed for validation logging to function
    ProjectUtils.attachLoggerStream(projectDir, {
      stream: {
        write: chunk => {
          if (chunk.tag === 'device') {
            logWithLevel(chunk);
          }
        },
      },
      type: 'raw',
    });

    // The existing CLI modules only pass one argument to this function, so skipProjectValidation
    // will be undefined in most cases. we can explicitly pass a truthy value here to avoid
    // validation (eg for init)
    //
    // If the packager/manifest server is running and healthy, there is no need
    // to rerun Doctor because the directory was already checked previously
    // This is relevant for command such as `send`
    if (!skipProjectValidation && (await Project.currentStatus(projectDir)) !== 'running') {
      log('Making sure project is set up correctly...');
      simpleSpinner.start();
      // validate that this is a good projectDir before we try anything else

      let status = await Doctor.validateLowLatencyAsync(projectDir);
      if (status === Doctor.FATAL) {
        throw new Error(`There is an error with your project. See above logs for information.`);
      }
      simpleSpinner.stop();
      log('Your project looks good!');
    }

    // the existing CLI modules only pass one argument to this function, so skipProjectValidation
    // will be undefined in most cases. we can explicitly pass a truthy value here to avoid validation (eg for init)

    return asyncFn(projectDir, ...args);
  }, true);
};

function runAsync(programName) {
  try {
    // Setup analytics
    Analytics.setSegmentNodeKey('vGu92cdmVaggGA26s3lBX6Y5fILm8SQ7');
    Analytics.setVersionName(packageJSON.version);
    _registerLogs();

    if (process.env.SERVER_URL) {
      let serverUrl = process.env.SERVER_URL;
      if (!serverUrl.startsWith('http')) {
        serverUrl = `http://${serverUrl}`;
      }
      let parsedUrl = url.parse(serverUrl);
      Config.api.host = parsedUrl.hostname;
      Config.api.port = parsedUrl.port;
    }

    Config.developerTool = packageJSON.name;

    // Setup our commander instance
    program.name = programName;
    program
      .version(packageJSON.version)
      .option('-o, --output [format]', 'Output format. pretty (default), raw');

    // Load each module found in ./commands by 'registering' it with our commander instance
    const files = _.uniqBy(
      [
        ...(programName === 'exp'
          ? glob.sync('exp_commands/*.js', { cwd: __dirname })
          : glob.sync('expo_commands/*.js', { cwd: __dirname })),
        ...glob.sync('commands/*.js', { cwd: __dirname }),
      ],
      path.basename
    );
    _.sortBy(files, path.basename).forEach(file => {
      const commandModule = require(`./${file}`);
      if (typeof commandModule === 'function') {
        commandModule(program);
      } else if (typeof commandModule.default === 'function') {
        commandModule.default(program);
      } else {
        log.error(`'${file}.js' is not a properly formatted command.`);
      }
    });

    if (process.env.EXPO_DEBUG) {
      glob
        .sync('debug_commands/*.js', {
          cwd: __dirname,
        })
        .forEach(file => {
          require(`./${file}`)(program);
        });
    }

    // Commander will now parse argv/argc
    program.parse(process.argv);

    // Display a message if the user does not input a valid command
    let subCommand = process.argv[2];
    if (subCommand) {
      let commands = [];
      program.commands.forEach(command => {
        commands.push(command['_name']);
        let alias = command['_alias'];
        if (alias) {
          commands.push(alias);
        }
      });
      if (!_.includes(commands, subCommand)) {
        console.log(
          `"${subCommand}" is not an ${programName} command. See "${programName} --help" for the full list of commands.`
        );
      }
    } else {
      program.help();
    }
  } catch (e) {
    console.error(e);
    throw e;
  }
}

async function checkForUpdateAsync() {
  let { state, current, latest } = await update.checkForUpdateAsync();
  let message;
  switch (state) {
    case 'up-to-date':
      break;

    case 'out-of-date':
      message = `There is a new version of ${packageJSON.name} available (${latest}).
You are currently using ${packageJSON.name} ${current}
Run \`npm install -g ${packageJSON.name}\` to get the latest version`;
      log.error(chalk.green(message));
      break;

    case 'ahead-of-published':
      // if the user is ahead of npm, we're going to assume they know what they're doing
      break;
  }
}

function _registerLogs() {
  let stream = {
    stream: {
      write: chunk => {
        if (chunk.code) {
          switch (chunk.code) {
            case NotificationCode.START_LOADING:
              simpleSpinner.start();
              return;
            case NotificationCode.STOP_LOADING:
              simpleSpinner.stop();
              return;
            case NotificationCode.DOWNLOAD_CLI_PROGRESS:
              return;
          }
        }

        if (chunk.level === bunyan.INFO) {
          log(chunk.msg);
        } else if (chunk.level === bunyan.WARN) {
          log.warn(chunk.msg);
        } else if (chunk.level >= bunyan.ERROR) {
          log.error(chunk.msg);
        }
      },
    },
    type: 'raw',
  };

  Logger.notifications.addStream(stream);
  Logger.global.addStream(stream);
}

async function writePathAsync() {
  let subCommand = process.argv[2];
  if (subCommand === 'prepare-detached-build') {
    // This is being run from Android Studio or Xcode. Don't want to write PATH in this case.
    return;
  }

  await Binaries.writePathToUserSettingsAsync();
}

// This is the entry point of the CLI
export function run(programName) {
  (async function() {
    await Promise.all([writePathAsync(), runAsync(programName)]);
  })().catch(e => {
    console.error('Uncaught Error', e);
    process.exit(1);
  });
}
<commit_msg>Remove superfluous call for checkForUpdateAsync<commit_after>/**
 * @flow
 */

import ProgressBar from 'progress';
import _ from 'lodash';
import bunyan from '@expo/bunyan';
import chalk from 'chalk';
import glob from 'glob';
import fs from 'fs';
import path from 'path';
import simpleSpinner from '@expo/simple-spinner';
import url from 'url';

import program, { Command } from 'commander';
import {
  Analytics,
  Binaries,
  Config,
  Doctor,
  Logger,
  PackagerLogsStream,
  NotificationCode,
  Project,
  ProjectUtils,
  User as UserManager,
} from 'xdl';

import { loginOrRegisterIfLoggedOut } from './accounts';
import log from './log';
import update from './update';
import urlOpts from './urlOpts';
import addCommonOptions from './commonOptions';
import packageJSON from '../package.json';

if (process.env.NODE_ENV === 'development') {
  require('source-map-support').install();
}

// The following prototyped functions are not used here, but within in each file found in `./commands`
// Extending commander to easily add more options to certain command line arguments
Command.prototype.urlOpts = function() {
  urlOpts.addOptions(this);
  return this;
};

Command.prototype.allowOffline = function() {
  this.option('--offline', 'Allows this command to run while offline');
  return this;
};

Command.prototype.allowNonInteractive = function() {
  this.option('--non-interactive', 'Fails if an interactive prompt would be required to continue.');
  return this;
};

// asyncAction is a wrapper for all commands/actions to be executed after commander is done
// parsing the command input
Command.prototype.asyncAction = function(asyncFn, skipUpdateCheck) {
  addCommonOptions(this);
  return this.action(async (...args) => {
    if (!skipUpdateCheck) {
      try {
        await checkForUpdateAsync();
      } catch (e) {}
    }

    try {
      let options = _.last(args);
      if (options.output === 'raw') {
        log.config.raw = true;
      }
      if (options.offline) {
        Config.offline = true;
      }
      await asyncFn(...args);
      // After a command, flush the analytics queue so the program will not have any active timers
      // This allows node js to exit immediately
      Analytics.flush();
    } catch (err) {
      // TODO: Find better ways to consolidate error messages
      if (err._isCommandError) {
        log.error(err.message);
      } else if (err._isApiError) {
        log.error(chalk.red(err.message));
      } else if (err.isXDLError) {
        log.error(err.message);
      } else {
        log.error(err.message);
        // TODO: Is there a better way to do this? EXPO_DEBUG needs to be set to view the stack trace
        if (process.env.EXPO_DEBUG) {
          log.error(chalk.gray(err.stack));
        } else {
          log.error(chalk.grey('Set EXPO_DEBUG=true in your env to view the stack trace.'));
        }
      }

      process.exit(1);
    }
  });
};

// asyncActionProjectDir captures the projectDirectory from the command line,
// setting it to cwd if it is not provided.
// Commands such as `start` and `publish` use this.
// It does several things:
// - Everything in asyncAction
// - Checks if the user is logged in or out
// - Checks for updates
// - Attaches the bundling logger
// - Checks if the project directory is valid or not
// - Runs AsyncAction with the projectDir as an argument
Command.prototype.asyncActionProjectDir = function(asyncFn, skipProjectValidation, skipAuthCheck) {
  return this.asyncAction(async (projectDir, ...args) => {
    const opts = args[0];
    if (!skipAuthCheck && !opts.nonInteractive && !opts.offline) {
      await loginOrRegisterIfLoggedOut();
    }

    if (!skipAuthCheck) {
      await UserManager.ensureLoggedInAsync();
    }

    if (!projectDir) {
      projectDir = process.cwd();
    } else {
      projectDir = path.resolve(process.cwd(), projectDir);
    }

    if (opts.config) {
      const pathToConfig = path.resolve(process.cwd(), opts.config);
      if (!fs.existsSync(pathToConfig)) {
        throw new Error(`File at provide config path does not exist: ${pathToConfig}`);
      }
      ProjectUtils.setCustomConfigPath(projectDir, pathToConfig);
    }

    const logLines = (msg, logFn) => {
      for (let line of msg.split('\n')) {
        logFn(line);
      }
    };

    const logStackTrace = (chunk, logFn, nestedLogFn) => {
      let traceInfo;
      try {
        traceInfo = JSON.parse(chunk.msg);
      } catch (e) {
        return logFn(chunk.msg);
      }

      let { message, stack } = traceInfo;
      log.addNewLineIfNone();
      logFn(chalk.bold(message));

      const isLibraryFrame = line => {
        return line.startsWith('node_modules');
      };

      let stackFrames = _.compact(stack.split('\n'));
      let lastAppCodeFrameIndex = _.findLastIndex(stackFrames, line => {
        return !isLibraryFrame(line);
      });
      let lastFrameIndexToLog = Math.min(
        stackFrames.length - 1,
        lastAppCodeFrameIndex + 2 // show max two more frames after last app code frame
      );
      let unloggedFrames = stackFrames.length - lastFrameIndexToLog;

      // If we're only going to exclude one frame, just log them all
      if (unloggedFrames === 1) {
        lastFrameIndexToLog = stackFrames.length - 1;
        unloggedFrames = 0;
      }

      for (let i = 0; i <= lastFrameIndexToLog; i++) {
        let line = stackFrames[i];
        if (!line) {
          continue;
        } else if (line.match(/react-native\/.*YellowBox.js/)) {
          continue;
        }

        if (line.startsWith('node_modules')) {
          nestedLogFn('- ' + line);
        } else {
          nestedLogFn('* ' + line);
        }
      }

      if (unloggedFrames > 0) {
        nestedLogFn(`- ... ${unloggedFrames} more stack frames from framework internals`);
      }

      log.printNewLineBeforeNextLog();
    };

    const logWithLevel = chunk => {
      if (!chunk.msg) {
        return;
      }
      if (chunk.level <= bunyan.INFO) {
        if (chunk.includesStack) {
          logStackTrace(chunk, log, log.nested);
        } else {
          logLines(chunk.msg, log);
        }
      } else if (chunk.level === bunyan.WARN) {
        if (chunk.includesStack) {
          logStackTrace(chunk, log.warn, log.nestedWarn);
        } else {
          logLines(chunk.msg, log.warn);
        }
      } else {
        if (chunk.includesStack) {
          logStackTrace(chunk, log.error, log.nestedError);
        } else {
          logLines(chunk.msg, log.error);
        }
      }
    };

    let bar;
    let packagerLogsStream = new PackagerLogsStream({
      projectRoot: projectDir,
      onStartBuildBundle: () => {
        bar = new ProgressBar('Building JavaScript bundle [:bar] :percent', {
          total: 100,
          clear: true,
          complete: '=',
          incomplete: ' ',
        });

        log.setBundleProgressBar(bar);
      },
      onProgressBuildBundle: percent => {
        if (!bar || bar.complete) return;
        let ticks = percent - bar.curr;
        ticks > 0 && bar.tick(ticks);
      },
      onFinishBuildBundle: (err, startTime: Date, endTime: Date) => {
        if (bar && !bar.complete) {
          bar.tick(100 - bar.curr);
        }

        if (bar) {
          log.setBundleProgressBar(null);
          bar = null;

          if (err) {
            log(chalk.red('Failed building JavaScript bundle.'));
          } else {
            log(chalk.green(`Finished building JavaScript bundle in ${endTime - startTime}ms.`));
          }
        }
      },
      updateLogs: updater => {
        let newLogChunks = updater([]);
        newLogChunks.forEach(newLogChunk => {
          logWithLevel(newLogChunk);
        });
      },
    });

    // needed for validation logging to function
    ProjectUtils.attachLoggerStream(projectDir, {
      stream: {
        write: chunk => {
          if (chunk.tag === 'device') {
            logWithLevel(chunk);
          }
        },
      },
      type: 'raw',
    });

    // The existing CLI modules only pass one argument to this function, so skipProjectValidation
    // will be undefined in most cases. we can explicitly pass a truthy value here to avoid
    // validation (eg for init)
    //
    // If the packager/manifest server is running and healthy, there is no need
    // to rerun Doctor because the directory was already checked previously
    // This is relevant for command such as `send`
    if (!skipProjectValidation && (await Project.currentStatus(projectDir)) !== 'running') {
      log('Making sure project is set up correctly...');
      simpleSpinner.start();
      // validate that this is a good projectDir before we try anything else

      let status = await Doctor.validateLowLatencyAsync(projectDir);
      if (status === Doctor.FATAL) {
        throw new Error(`There is an error with your project. See above logs for information.`);
      }
      simpleSpinner.stop();
      log('Your project looks good!');
    }

    // the existing CLI modules only pass one argument to this function, so skipProjectValidation
    // will be undefined in most cases. we can explicitly pass a truthy value here to avoid validation (eg for init)

    return asyncFn(projectDir, ...args);
  });
};

function runAsync(programName) {
  try {
    // Setup analytics
    Analytics.setSegmentNodeKey('vGu92cdmVaggGA26s3lBX6Y5fILm8SQ7');
    Analytics.setVersionName(packageJSON.version);
    _registerLogs();

    if (process.env.SERVER_URL) {
      let serverUrl = process.env.SERVER_URL;
      if (!serverUrl.startsWith('http')) {
        serverUrl = `http://${serverUrl}`;
      }
      let parsedUrl = url.parse(serverUrl);
      Config.api.host = parsedUrl.hostname;
      Config.api.port = parsedUrl.port;
    }

    Config.developerTool = packageJSON.name;

    // Setup our commander instance
    program.name = programName;
    program
      .version(packageJSON.version)
      .option('-o, --output [format]', 'Output format. pretty (default), raw');

    // Load each module found in ./commands by 'registering' it with our commander instance
    const files = _.uniqBy(
      [
        ...(programName === 'exp'
          ? glob.sync('exp_commands/*.js', { cwd: __dirname })
          : glob.sync('expo_commands/*.js', { cwd: __dirname })),
        ...glob.sync('commands/*.js', { cwd: __dirname }),
      ],
      path.basename
    );
    _.sortBy(files, path.basename).forEach(file => {
      const commandModule = require(`./${file}`);
      if (typeof commandModule === 'function') {
        commandModule(program);
      } else if (typeof commandModule.default === 'function') {
        commandModule.default(program);
      } else {
        log.error(`'${file}.js' is not a properly formatted command.`);
      }
    });

    if (process.env.EXPO_DEBUG) {
      glob
        .sync('debug_commands/*.js', {
          cwd: __dirname,
        })
        .forEach(file => {
          require(`./${file}`)(program);
        });
    }

    // Commander will now parse argv/argc
    program.parse(process.argv);

    // Display a message if the user does not input a valid command
    let subCommand = process.argv[2];
    if (subCommand) {
      let commands = [];
      program.commands.forEach(command => {
        commands.push(command['_name']);
        let alias = command['_alias'];
        if (alias) {
          commands.push(alias);
        }
      });
      if (!_.includes(commands, subCommand)) {
        console.log(
          `"${subCommand}" is not an ${programName} command. See "${programName} --help" for the full list of commands.`
        );
      }
    } else {
      program.help();
    }
  } catch (e) {
    console.error(e);
    throw e;
  }
}

async function checkForUpdateAsync() {
  let { state, current, latest } = await update.checkForUpdateAsync();
  let message;
  switch (state) {
    case 'up-to-date':
      break;

    case 'out-of-date':
      message = `There is a new version of ${packageJSON.name} available (${latest}).
You are currently using ${packageJSON.name} ${current}
Run \`npm install -g ${packageJSON.name}\` to get the latest version`;
      log.error(chalk.green(message));
      break;

    case 'ahead-of-published':
      // if the user is ahead of npm, we're going to assume they know what they're doing
      break;
  }
}

function _registerLogs() {
  let stream = {
    stream: {
      write: chunk => {
        if (chunk.code) {
          switch (chunk.code) {
            case NotificationCode.START_LOADING:
              simpleSpinner.start();
              return;
            case NotificationCode.STOP_LOADING:
              simpleSpinner.stop();
              return;
            case NotificationCode.DOWNLOAD_CLI_PROGRESS:
              return;
          }
        }

        if (chunk.level === bunyan.INFO) {
          log(chunk.msg);
        } else if (chunk.level === bunyan.WARN) {
          log.warn(chunk.msg);
        } else if (chunk.level >= bunyan.ERROR) {
          log.error(chunk.msg);
        }
      },
    },
    type: 'raw',
  };

  Logger.notifications.addStream(stream);
  Logger.global.addStream(stream);
}

async function writePathAsync() {
  let subCommand = process.argv[2];
  if (subCommand === 'prepare-detached-build') {
    // This is being run from Android Studio or Xcode. Don't want to write PATH in this case.
    return;
  }

  await Binaries.writePathToUserSettingsAsync();
}

// This is the entry point of the CLI
export function run(programName) {
  (async function() {
    await Promise.all([writePathAsync(), runAsync(programName)]);
  })().catch(e => {
    console.error('Uncaught Error', e);
    process.exit(1);
  });
}
<|endoftext|>


<commit_before>(function() {
	"use strict";
	function initPage() {
		var form = $(".edit_generic_work");

		// The required fields should not keep the form from submitting.
		// Turn off the browser's required field processing, but keep the indication that the field is required, so that it can be styled.
		var required_fields = form.find("[required=required]");
		required_fields.prop("required", false);

		// Turn off the Sufia submit prevention
		// Do this in a timeout so that the sufia code will run first.
		setTimeout(function() {
			form.off("submit");
		}, 10);

		// Override the sufia code that disables the "save" button. We always want to be able to save.
		form.on('blur change keyup', 'input, select, textarea', function(){
			// Do this in a timeout so that the sufia code will run first.
			setTimeout(function() {
				setRequired();
			}, 10);
		});

		// Override the "Add files" requirement so that it looks at previously uploaded files, too.
		var requiredFiles = $("#required-files");
		var requiredMetaData = $("#required-metadata");
		var fileUploadSection = $("#fileupload");
		function setRequired() {
			var save = $("#with_files_submit_exit,#with_files_submit_continue,#with_files_submit");

			// Be sure the agreement is set.
			var agreement = $("#agreement:checked");
			if (agreement.length > 0)
				save.prop("disabled", false);
			else
				save.prop("disabled", true);

			// Be sure there is at least one file uploaded.
			// If the fileUploadSection isn't there at all, then we aren't on the edit page, so don't do anything.
			if (fileUploadSection.length === 0)
				return;
			var fileList = fileUploadSection.find("tr");
			if (fileList.length > 0) {
				requiredFiles.removeClass("incomplete");
				requiredFiles.addClass("complete");
			} else {
				requiredFiles.removeClass("complete");
				requiredFiles.addClass("incomplete");
			}

			// Be sure all the metadata is filled in.
			var allFilledIn = true;
			$.each(required_fields, function(index, value) {
				var el = $(value);
				var val = el.val();
				if (val.length === 0) {
					allFilledIn = false;
					el.addClass("invalid-input");
				} else {
					el.removeClass("invalid-input");
				}
			});
			// Also be sure that the first advisor fields are filled in. We have to do this on the fly since the user can delete the first one.
			var inputs = $("#contributor_contributor_first_name_0,#contributor_contributor_last_name_0,#contributor_contributor_department_0,#contributor_contributor_institution_0");
			inputs.each(function() {
				var el = $(this);
				if (el.val().length === 0) {
					allFilledIn = false;
					el.addClass("invalid-input");
				} else {
					el.removeClass("invalid-input");
				}
			});
			if (allFilledIn) {
				requiredMetaData.removeClass("incomplete");
				requiredMetaData.addClass("complete");
			} else {
				requiredMetaData.removeClass("complete");
				requiredMetaData.addClass("incomplete");
			}

		}
		// Do this in a timeout so that the sufia code will run first.
		setTimeout(function() {
			setRequired();
		}, 10);

		// Also recheck the file requirement when the file delete button is pressed.
		fileUploadSection.on("click", ".delete", function() {
			// Do this in a timeout so that the delete action will run first. The item fades out with a css transform, so the timeout needs to be longer than the transform.
			setTimeout(function() {
				setRequired();
			}, 2000);
		});

		// Also if the computing id changes, recheck.
		$("body").on("computing_id:change", setRequired);
	}

	$(window).bind('page:change', function() {
		initPage();
	});
})();
<commit_msg>Fix detecting whether a file has been uploaded.<commit_after>(function() {
	"use strict";
	function initPage() {
		var form = $(".edit_generic_work");

		// The required fields should not keep the form from submitting.
		// Turn off the browser's required field processing, but keep the indication that the field is required, so that it can be styled.
		var required_fields = form.find("[required=required]");
		required_fields.prop("required", false);

		// Turn off the Sufia submit prevention
		// Do this in a timeout so that the sufia code will run first.
		setTimeout(function() {
			form.off("submit");
		}, 10);

		// Override the sufia code that disables the "save" button. We always want to be able to save.
		form.on('blur change keyup', 'input, select, textarea', function(){
			// Do this in a timeout so that the sufia code will run first.
			setTimeout(function() {
				setRequired();
			}, 10);
		});

		// Override the "Add files" requirement so that it looks at previously uploaded files, too.
		var requiredFiles = $("#required-files");
		var requiredMetaData = $("#required-metadata");
		var fileUploadSection = $("#fileupload");
		function setRequired() {
			var save = $("#with_files_submit_exit,#with_files_submit_continue,#with_files_submit");

			// Be sure the agreement is set.
			var agreement = $("#agreement:checked");
			if (agreement.length > 0)
				save.prop("disabled", false);
			else
				save.prop("disabled", true);

			// Be sure there is at least one file uploaded.
			// If the fileUploadSection isn't there at all, then we aren't on the edit page, so don't do anything.
			if (fileUploadSection.length === 0)
				return;
			var fileList = fileUploadSection.find('tr input[name="previously_uploaded_files_label[]"],tr input[name="newly_uploaded_files_label[]"]');
			if (fileList.length > 0) {
				requiredFiles.removeClass("incomplete");
				requiredFiles.addClass("complete");
			} else {
				requiredFiles.removeClass("complete");
				requiredFiles.addClass("incomplete");
			}

			// Be sure all the metadata is filled in.
			var allFilledIn = true;
			$.each(required_fields, function(index, value) {
				var el = $(value);
				var val = el.val();
				if (val.length === 0) {
					allFilledIn = false;
					el.addClass("invalid-input");
				} else {
					el.removeClass("invalid-input");
				}
			});
			// Also be sure that the first advisor fields are filled in. We have to do this on the fly since the user can delete the first one.
			var inputs = $("#contributor_contributor_first_name_0,#contributor_contributor_last_name_0,#contributor_contributor_department_0,#contributor_contributor_institution_0");
			inputs.each(function() {
				var el = $(this);
				if (el.val().length === 0) {
					allFilledIn = false;
					el.addClass("invalid-input");
				} else {
					el.removeClass("invalid-input");
				}
			});
			if (allFilledIn) {
				requiredMetaData.removeClass("incomplete");
				requiredMetaData.addClass("complete");
			} else {
				requiredMetaData.removeClass("complete");
				requiredMetaData.addClass("incomplete");
			}

		}
		// Do this in a timeout so that the sufia code will run first.
		setTimeout(function() {
			setRequired();
		}, 10);

		// Also recheck the file requirement when the file delete button is pressed.
		fileUploadSection.on("click", ".delete", function() {
			// Do this in a timeout so that the delete action will run first. The item fades out with a css transform, so the timeout needs to be longer than the transform.
			setTimeout(function() {
				setRequired();
			}, 2000);
		});

		// Also if the computing id changes, recheck.
		$("body").on("computing_id:change", setRequired);
	}

	$(window).bind('page:change', function() {
		initPage();
	});
})();
<|endoftext|>


<commit_before>var createCamera = require('../camera')
var bunny = require('bunny')
var perspective = require('gl-mat4/perspective')
var createMesh = require('gl-simplicial-complex')

var canvas = document.createElement('canvas')
document.body.appendChild(canvas)
window.addEventListener('resize', require('canvas-fit')(canvas))

var gl = canvas.getContext('webgl')

var camera = createCamera(canvas, {
  eye:    [50,0,0],
  center: [0,0,0],
  zoomMax: 500
})

var mesh = createMesh(gl, {
  cells:      bunny.cells,
  positions:  bunny.positions,
  colormap:   'jet'
})

function render() {
  requestAnimationFrame(render)
  if(camera.tick()) {
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
    gl.enable(gl.DEPTH_TEST)
    mesh.draw({
      projection: perspective([], Math.PI/4, canvas.width/canvas.height, 0.01, 1000),
      view: camera.matrix
    })
  }
}
render()<commit_msg>set viewport<commit_after>var createCamera = require('../camera')
var bunny = require('bunny')
var perspective = require('gl-mat4/perspective')
var createMesh = require('gl-simplicial-complex')

var canvas = document.createElement('canvas')
document.body.appendChild(canvas)
window.addEventListener('resize', require('canvas-fit')(canvas))

var gl = canvas.getContext('webgl')

var camera = createCamera(canvas, {
  eye:    [50,0,0],
  center: [0,0,0],
  zoomMax: 500
})

var mesh = createMesh(gl, {
  cells:      bunny.cells,
  positions:  bunny.positions,
  colormap:   'jet'
})

function render() {
  requestAnimationFrame(render)
  if(camera.tick()) {
    gl.viewport(0, 0, canvas.width, canvas.height)
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
    gl.enable(gl.DEPTH_TEST)
    mesh.draw({
      projection: perspective([], Math.PI/4, canvas.width/canvas.height, 0.01, 1000),
      view: camera.matrix
    })
  }
}
render()<|endoftext|>


<commit_before>test( "Popcorn Image Plugin", function() {

  var popped = Popcorn( "#video" ),
      expects = 9,
      count = 0,
      setupId,
      imagediv = document.getElementById( "imagediv" ),
      sources = [
        "https://www.drumbeat.org/media//images/drumbeat-logo-splash.png",
        "http://www.petmountain.com/category/mini/organic-dog-supplies/520/organic-dog-supplies.jpg",
        "http://www.botskool.com/sites/default/files/images/javascript.png"
      ];

  expect( expects );

  function plus() {
    if ( ++count === expects ) {
      start();
    }
  }

  stop();

  ok( "image" in popped, "image is a method of the popped instance" );
  plus();

  equals( imagediv.innerHTML, "", "initially, there is nothing inside the imagediv" );
  plus();

  popped.image({
    start: 1,
    end: 3,
    href: "http://www.drumbeat.org/",
    src: sources[ 0 ],
    text: "DRUMBEAT",
    target: "imagediv"
  })
  .image({
    start: 4,
    end: 6,
    src: sources[ 1 ],
    target: "imagediv"
  })
  .image({
    start: 5,
    end: 6,
    src: sources[ 2 ],
    target: "imagediv"
  });

  setupId = popped.getLastTrackEventId();

  popped.cue( 2, function() {
    ok( imagediv.children[ 0 ].style.display !== "none", "inline", "Div contents are displayed" );
    plus();
    equals( imagediv.querySelector("img").nodeName, "IMG", "An image exists" );
    plus();
  });

  popped.cue( 3, function() {
    equals( imagediv.children[ 0 ].style.display, "none", "Div contents are hidden again" );
    plus();
  });

  popped.cue( 5, function() {
    [].forEach.call( document.querySelectorAll( "#imagediv a img" ), function( img, idx ) {
      ok( img.src === sources[ idx ], "Image " + idx + " is in the right order" );
      plus();
    });
  });

  popped.cue( 7, function() {
    popped.pause().removeTrackEvent( setupId );
    ok( !imagediv.children[ 2 ], "removed image was properly destroyed" );
    plus();
  });

  popped.volume( 0 ).play();
});

asyncTest( "Zerostart doesn't rehide", 0, function() {
  var popped = Popcorn( "#video" ),
      zerostart = document.getElementById( "zerostart" ),
      expects = 9;

  popped.on( "canplayall", function() {
    popped.currentTime(0);

    popped.image({
      start: 0,
      end: 3,
      src: "https://www.drumbeat.org/media/images/drumbeat-logo-splash.png",
      target: "zerostart"
    });

    popped.cue( 1, function() {
      ok( zerostart.children[ 0 ].style.display !== "none", "display area displayed at start: 0 without re-hiding" );
      start();
    });

    popped.play();
  });
});
<commit_msg>Fixes issues per review<commit_after>test( "Popcorn Image Plugin", function() {

  var popped = Popcorn( "#video" ),
      expects = 9,
      count = 0,
      setupId,
      imagediv = document.getElementById( "imagediv" ),
      sources = [
        "https://www.drumbeat.org/media//images/drumbeat-logo-splash.png",
        "http://www.petmountain.com/category/mini/organic-dog-supplies/520/organic-dog-supplies.jpg",
        "http://www.botskool.com/sites/default/files/images/javascript.png"
      ];

  expect( expects );

  function plus() {
    if ( ++count === expects ) {
      start();
    }
  }

  stop();

  ok( "image" in popped, "image is a method of the popped instance" );
  plus();

  equals( imagediv.innerHTML, "", "initially, there is nothing inside the imagediv" );
  plus();

  popped.image({
    start: 1,
    end: 3,
    href: "http://www.drumbeat.org/",
    src: sources[ 0 ],
    text: "DRUMBEAT",
    target: "imagediv"
  })
  .image({
    start: 4,
    end: 6,
    src: sources[ 1 ],
    target: "imagediv"
  })
  .image({
    start: 5,
    end: 6,
    src: sources[ 2 ],
    target: "imagediv"
  });

  setupId = popped.getLastTrackEventId();

  popped.cue( 2, function() {
    ok( imagediv.children[ 0 ].style.display !== "none", "inline", "Div contents are displayed" );
    plus();
    equals( imagediv.querySelector("img").nodeName, "IMG", "An image exists" );
    plus();
  });

  popped.cue( 3, function() {
    equals( imagediv.children[ 0 ].style.display, "none", "Div contents are hidden again" );
    plus();
  });

  popped.cue( 5, function() {
    [].forEach.call( document.querySelectorAll( "#imagediv a img" ), function( img, idx ) {
      ok( img.src === sources[ idx ], "Image " + idx + " is in the right order" );
      plus();
    });
  });

  popped.cue( 7, function() {
    popped.pause().removeTrackEvent( setupId );
    ok( !imagediv.children[ 2 ], "removed image was properly destroyed" );
    plus();
  });

  popped.volume( 0 ).play();
});

asyncTest( "Zerostart doesn't rehide", 1, function() {
  var popped = Popcorn( "#video" ),
      zerostart = document.getElementById( "zerostart" );

  popped.on( "canplayall", function() {
    popped.currentTime(0);

    popped.image({
      start: 0,
      end: 3,
      src: "https://www.drumbeat.org/media/images/drumbeat-logo-splash.png",
      target: "zerostart"
    });

    popped.cue( 1, function() {
      ok( zerostart.children[ 0 ].style.display !== "none", "display area displayed at start: 0 without re-hiding" );
      start();
    });

    popped.play();
  });
});
<|endoftext|>


<commit_before>// utility for enc

var consts = require('./consts'),
  c = consts.shorthand,
  time = require('./compile/time'),
  vlfield = require('./field'),
  util = require('./util'),
  schema = require('./schema/schema'),
  encTypes = schema.encTypes;

var vlenc = module.exports = {};

vlenc.countRetinal = function(enc) {
  var count = 0;
  if (enc.color) count++;
  if (enc.alpha) count++;
  if (enc.size) count++;
  if (enc.shape) count++;
  return count;
};

vlenc.has = function(enc, encType) {
  var fieldDef = enc && enc[encType];
  return fieldDef && fieldDef.name;
};

vlenc.isAggregate = function(enc) {
  for (var k in enc) {
    if (vlenc.has(k) && enc[k].aggr) {
      return true;
    }
  }
  return false;
};

vlenc.forEach = function(enc, f) {
  var i = 0;
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      f(k, enc[k], i++);
    }
  });
};

vlenc.map = function(enc, f) {
  var arr = [];
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      arr.push(f(k, enc[k], enc));
    }
  });
  return arr;
};

vlenc.reduce = function(enc, f, init) {
  var r = init, i = 0, k;
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      r = f(r, k, enc[k], enc);
    }
  });
  return r;
};

vlenc.shorthand = function(enc) {
  return vlenc.map(enc, function(et, field) {
    return et + c.assign + vlfield.shorthand(field);
  }).join(c.delim);
};

vlenc.parseShorthand = function(shorthand, convertType) {
  var enc = shorthand.split(c.delim);
  return enc.reduce(function(m, e) {
    var split = e.split(c.assign),
        enctype = split[0].trim(),
        field = split[1];

    m[enctype] = vlfield.parseShorthand(field, convertType);
    return m;
  }, {});
};<commit_msg>fix vlenc.isAggregate<commit_after>// utility for enc

var consts = require('./consts'),
  c = consts.shorthand,
  time = require('./compile/time'),
  vlfield = require('./field'),
  util = require('./util'),
  schema = require('./schema/schema'),
  encTypes = schema.encTypes;

var vlenc = module.exports = {};

vlenc.countRetinal = function(enc) {
  var count = 0;
  if (enc.color) count++;
  if (enc.alpha) count++;
  if (enc.size) count++;
  if (enc.shape) count++;
  return count;
};

vlenc.has = function(enc, encType) {
  var fieldDef = enc && enc[encType];
  return fieldDef && fieldDef.name;
};

vlenc.isAggregate = function(enc) {
  for (var k in enc) {
    if (vlenc.has(enc, k) && enc[k].aggr) {
      return true;
    }
  }
  return false;
};

vlenc.forEach = function(enc, f) {
  var i = 0;
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      f(k, enc[k], i++);
    }
  });
};

vlenc.map = function(enc, f) {
  var arr = [];
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      arr.push(f(k, enc[k], enc));
    }
  });
  return arr;
};

vlenc.reduce = function(enc, f, init) {
  var r = init, i = 0, k;
  encTypes.forEach(function(k) {
    if (vlenc.has(enc, k)) {
      r = f(r, k, enc[k], enc);
    }
  });
  return r;
};

vlenc.shorthand = function(enc) {
  return vlenc.map(enc, function(et, field) {
    return et + c.assign + vlfield.shorthand(field);
  }).join(c.delim);
};

vlenc.parseShorthand = function(shorthand, convertType) {
  var enc = shorthand.split(c.delim);
  return enc.reduce(function(m, e) {
    var split = e.split(c.assign),
        enctype = split[0].trim(),
        field = split[1];

    m[enctype] = vlfield.parseShorthand(field, convertType);
    return m;
  }, {});
};<|endoftext|>


<commit_before><commit_msg>Update namespace<commit_after><|endoftext|>


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

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name dists
* @memberof ns
* @readonly
* @type {Namespace}
* @see {@link module:@stdlib/stats/base/dists}
*/
setReadOnly( ns, 'dists', require( '@stdlib/stats/base/dists' ) );

/**
* @name dmax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmax}
*/
setReadOnly( ns, 'dmax', require( '@stdlib/stats/base/dmax' ) );

/**
* @name dmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmean}
*/
setReadOnly( ns, 'dmean', require( '@stdlib/stats/base/dmean' ) );

/**
* @name dmin
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmin}
*/
setReadOnly( ns, 'dmin', require( '@stdlib/stats/base/dmin' ) );

/**
* @name dnanmax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dnanmax}
*/
setReadOnly( ns, 'dnanmax', require( '@stdlib/stats/base/dnanmax' ) );

/**
* @name dnanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dnanmean}
*/
setReadOnly( ns, 'dnanmean', require( '@stdlib/stats/base/dnanmean' ) );

/**
* @name mean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/mean}
*/
setReadOnly( ns, 'mean', require( '@stdlib/stats/base/mean' ) );

/**
* @name nanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/nanmean}
*/
setReadOnly( ns, 'nanmean', require( '@stdlib/stats/base/nanmean' ) );

/**
* @name smax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smax}
*/
setReadOnly( ns, 'smax', require( '@stdlib/stats/base/smax' ) );

/**
* @name smean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smean}
*/
setReadOnly( ns, 'smean', require( '@stdlib/stats/base/smean' ) );

/**
* @name smin
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smin}
*/
setReadOnly( ns, 'smin', require( '@stdlib/stats/base/smin' ) );

/**
* @name snanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/snanmean}
*/
setReadOnly( ns, 'snanmean', require( '@stdlib/stats/base/snanmean' ) );

// EXPORTS //

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

'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name dists
* @memberof ns
* @readonly
* @type {Namespace}
* @see {@link module:@stdlib/stats/base/dists}
*/
setReadOnly( ns, 'dists', require( '@stdlib/stats/base/dists' ) );

/**
* @name dmax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmax}
*/
setReadOnly( ns, 'dmax', require( '@stdlib/stats/base/dmax' ) );

/**
* @name dmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmean}
*/
setReadOnly( ns, 'dmean', require( '@stdlib/stats/base/dmean' ) );

/**
* @name dmin
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dmin}
*/
setReadOnly( ns, 'dmin', require( '@stdlib/stats/base/dmin' ) );

/**
* @name dnanmax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dnanmax}
*/
setReadOnly( ns, 'dnanmax', require( '@stdlib/stats/base/dnanmax' ) );

/**
* @name dnanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dnanmean}
*/
setReadOnly( ns, 'dnanmean', require( '@stdlib/stats/base/dnanmean' ) );

/**
* @name dnanmin
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/dnanmin}
*/
setReadOnly( ns, 'dnanmin', require( '@stdlib/stats/base/dnanmin' ) );

/**
* @name mean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/mean}
*/
setReadOnly( ns, 'mean', require( '@stdlib/stats/base/mean' ) );

/**
* @name nanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/nanmean}
*/
setReadOnly( ns, 'nanmean', require( '@stdlib/stats/base/nanmean' ) );

/**
* @name smax
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smax}
*/
setReadOnly( ns, 'smax', require( '@stdlib/stats/base/smax' ) );

/**
* @name smean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smean}
*/
setReadOnly( ns, 'smean', require( '@stdlib/stats/base/smean' ) );

/**
* @name smin
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/smin}
*/
setReadOnly( ns, 'smin', require( '@stdlib/stats/base/smin' ) );

/**
* @name snanmean
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/stats/base/snanmean}
*/
setReadOnly( ns, 'snanmean', require( '@stdlib/stats/base/snanmean' ) );

// EXPORTS //

module.exports = ns;
<|endoftext|>