<commit_before>/**
 * 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.
 */

goog.provide('org.apache.flex.jquery.RadioButton');

goog.require('org.apache.flex.core.UIBase');

/**
 * @constructor
 * @extends {org.apache.flex.core.UIBase}
 */
org.apache.flex.jquery.RadioButton = function() {

  org.apache.flex.jquery.RadioButton.base(this, 'constructor');

  org.apache.flex.core.UIBase.call(this);
  org.apache.flex.jquery.RadioButton.radioCounter++;
};
goog.inherits(org.apache.flex.jquery.RadioButton,
    org.apache.flex.core.UIBase);

/**
 * @expose
 * @type {?string}
 * The name of the radioGroup.
 */
org.apache.flex.jquery.RadioButton.prototype.radioGroupName = null;

/**
 * @expose
 * Used to provide ids to the radio buttons.
 */
org.apache.flex.jquery.RadioButton.radioCounter = 0;

/**
 * @expose
 * Used to manage groups on the radio buttons.
 */
org.apache.flex.jquery.RadioButton.groups = { };

/**
 * Flag to make sure the event handler is set only once.
 */
org.apache.flex.jquery.RadioButton.groupHandlerSet = false;

/**
 * @override
 */
org.apache.flex.jquery.RadioButton.prototype.createElement =
    function() {

  var input = document.createElement('input');
  input.type = 'radio';
  input.name = 'radio';
  input.id = 'radio' +
      org.apache.flex.jquery.RadioButton.radioCounter;

  var label = document.createElement('label');
  label.htmlFor = input.id;

  this.element = input;
  this.labelFor = label;

  this.positioner = this.element;
  this.flexjs_wrapper = this;
  return this.element;
};

/**
 * @param {Object} doc the document for this item.
 * @param {string} id the id in the document for this item.
 */
org.apache.flex.jquery.RadioButton.prototype.setDocument =
    function(doc, id) {
  if (!org.apache.flex.jquery.RadioButton.groupHandlerSet)
  {
    org.apache.flex.jquery.RadioButton.groupHandlerSet =
        true;
    doc.addEventListener('initComplete',
        goog.bind(this.initHandler, this));
  }
};

/**
 * @param {Event} event The event.
 */
org.apache.flex.jquery.RadioButton.prototype.initHandler =
    function(event) {
  var divtags = org.apache.flex.jquery.RadioButton.groups;
  for (var name in divtags)
  {
    var div = divtags[name];
    $(div).buttonset();
  }
};

/**
 * @expose
 * @return {?string} The groupName getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_groupName =
    function() {
  return this.radioGroupName;
};

/**
 * @expose
 * @param {string} value The groupName setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_groupName =
    function(value) {

  /*
 * NOTE: Ideally when a RadioButton was created it would be added to an
 * existing set of RadioButtons. This is especially true for RadioButtons
 * added dynamically. However, due to a bug in jQuery
 * (see http://bugs.jqueryui.com/ticket/8975), it is currently not possible
 * to add or remove RadioButtons programmatically. For this version the
 * groups are maintained here in RadioButton and once the application has
 * finished initializing, the groups are given their buttonset().
 */

  this.radioGroupName = value;

  this.element.name = value;

  var div;

  if (org.apache.flex.jquery.RadioButton.groups[value]) {
    div = org.apache.flex.jquery.RadioButton.groups[value];
    div.appendChild(this.element);
    div.appendChild(this.labelFor);
  }
  else {
    div = document.createElement('div');
    div.id = value;
    div.appendChild(this.element);
    div.appendChild(this.labelFor);

    org.apache.flex.jquery.
        RadioButton.groups[String(value)] = div;
  }

  this.positioner = div;
};

/**
 * @expose
 * @return {string} The text getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_text =
    function() {
  return this.labelFor.innerHTML;
};

/**
 * @expose
 * @param {string} value The text setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_text =
    function(value) {
  this.labelFor.innerHTML = value;
};

/**
 * @expose
 * @return {boolean} The selected getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_selected =
    function() {
  return this.element.checked;
};

/**
 * @expose
 * @param {boolean} value The selected setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_selected =
    function(value) {
  this.element.checked = value;
};
<commit_msg>Fixed issue of misplacement and missing label with JavaScript jQuery RadioButton by simplifying the code.<commit_after>/**
 * 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.
 */

goog.provide('org.apache.flex.jquery.RadioButton');

goog.require('org.apache.flex.core.UIBase');

/**
 * @constructor
 * @extends {org.apache.flex.core.UIBase}
 */
org.apache.flex.jquery.RadioButton = function() {

  org.apache.flex.jquery.RadioButton.base(this, 'constructor');

  org.apache.flex.core.UIBase.call(this);
  org.apache.flex.jquery.RadioButton.radioCounter++;
};
goog.inherits(org.apache.flex.jquery.RadioButton,
    org.apache.flex.core.UIBase);

/**
 * @expose
 * @type {?string}
 * The name of the radioGroup.
 */
org.apache.flex.jquery.RadioButton.prototype.radioGroupName = null;

/**
 * @expose
 * Used to provide ids to the radio buttons.
 */
org.apache.flex.jquery.RadioButton.radioCounter = 0;

/**
 * @expose
 * Used to manage groups on the radio buttons.
 */
org.apache.flex.jquery.RadioButton.groups = { };

/**
 * Flag to make sure the event handler is set only once.
 */
org.apache.flex.jquery.RadioButton.groupHandlerSet = false;

/**
 * @override
 */
org.apache.flex.jquery.RadioButton.prototype.createElement =
    function() {

  this.input = document.createElement('input');
  this.input.type = 'radio';
  this.input.name = 'radio';
  this.input.id = 'radio' + org.apache.flex.jquery.RadioButton.radioCounter;

  this.labelFor = document.createElement('label');
  this.labelFor.htmlFor = this.input.id;

  this.element = document.createElement('div');
  this.element.appendChild(this.input);
  this.element.appendChild(this.labelFor);
  this.positioner = this.element;
  this.flexjs_wrapper = this;
  this.input.flexjs_wrapper = this;
  this.labelFor.fljs_wrapper = this;

  return this.element;
};

/**
 * @expose
 * @return {?string} The groupName getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_groupName =
    function() {
  return this.radioGroupName;
};

/**
 * @expose
 * @param {string} value The groupName setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_groupName =
    function(value) {

  this.radioGroupName = value;
  this.input.name = value;
};

/**
 * @expose
 * @return {string} The text getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_text =
    function() {
  return this.labelFor.innerHTML;
};

/**
 * @expose
 * @param {string} value The text setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_text =
    function(value) {
  this.labelFor.innerHTML = value;
};

/**
 * @expose
 * @return {boolean} The selected getter.
 */
org.apache.flex.jquery.RadioButton.prototype.get_selected =
    function() {
  return this.input.checked;
};

/**
 * @expose
 * @param {boolean} value The selected setter.
 */
org.apache.flex.jquery.RadioButton.prototype.set_selected =
    function(value) {
  this.input.checked = value;
};
<|endoftext|>


<commit_before>/* @flow */

import { ZalgoPromise } from 'zalgo-promise/src';
import { values, uniqueID } from 'belter/src';
import { type OrderCreateRequest, type FundingEligibilityType,
    type OrderGetResponse, type OrderCaptureResponse, type OrderAuthorizeResponse } from '@paypal/sdk-client/src';
import { FUNDING, PLATFORM, INTENT, COMMIT, VAULT,
    ENV, COUNTRY, LANG, COUNTRY_LANGS, type LocaleType, CARD, COMPONENTS } from '@paypal/sdk-constants/src';
import { type CrossDomainWindowType } from 'cross-domain-utils/src';
import { LOGO_COLOR } from '@paypal/sdk-logos/src';
import { SUPPORTED_FUNDING_SOURCES } from '@paypal/funding-components/src';
import type { ComponentFunctionType } from 'jsx-pragmatic/src';

import { BUTTON_LABEL, BUTTON_COLOR, BUTTON_LAYOUT, BUTTON_SHAPE, BUTTON_SIZE } from '../../constants';
import { getFundingConfig, isFundingEligible } from '../../funding';

import { BUTTON_SIZE_STYLE } from './config';

export type CreateOrderData = {|

|} | {};

export type CreateOrderActions = {|
    order : {
        create : (OrderCreateRequest) => ZalgoPromise<string>
    }
|};

export type CreateOrder = (CreateOrderData, CreateOrderActions) => ZalgoPromise<string> | string;

export type OnApproveData = {|
    orderID : string,
    payerID : string,
    paymentID? : string
|};

export type CreateBillingAgreement = () => ZalgoPromise<string> | string;

export type CreateSubscriptionRequest = {||};
export type SubscriptionResponse = {||} | {};
export type CreateSubscriptionData = {|
|} | {};

export type CreateSubscriptionActions = {|
    subscription : {
        create : (CreateSubscriptionRequest) => ZalgoPromise<string>,
        revise : (CreateSubscriptionRequest) => ZalgoPromise<string>
    }
|};

export type CreateSubscription = (CreateSubscriptionData, CreateSubscriptionActions) => ZalgoPromise<string> | string;

export type OnApproveActions = {|
    redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>,
    order : {
        capture : () => ZalgoPromise<OrderCaptureResponse>,
        get : () => ZalgoPromise<OrderGetResponse>,
        authorize : () => ZalgoPromise<OrderAuthorizeResponse>
    },
    subscription : {
        get : () => ZalgoPromise<SubscriptionResponse>,
        activate : () => ZalgoPromise<SubscriptionResponse>
    }
|};

export type OnApprove = (data : OnApproveData, actions : OnApproveActions) => ZalgoPromise<void> | void;

type OnShippingChangeAddress = {|
    city : string,
    state : string,
    country_code : string,
    postal_code : string
|};

type OnShippingChangeMethod = {|
    label : string,
    type : string,
    amount : {
        currency_code : string,
        value : string
    }
|};

export type OnShippingChangeData = {|
    orderID : string,
    payerID : string,
    paymentID? : string,
    shipping_address : OnShippingChangeAddress,
    selected_shipping_method : OnShippingChangeMethod
|};

export type OnShippingChangeActions = {|
    order : {
        patch : () => ZalgoPromise<OrderGetResponse>
    }
|};

export type OnShippingChange = (data : OnShippingChangeData, actions : OnShippingChangeActions) => ZalgoPromise<void> | void;

export type OnCancelData = {|
    orderID : string,
    paymentID? : string
|};

export type OnCancelActions = {|
    redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>
|};

export type OnCancel = (OnCancelData, OnCancelActions) => ZalgoPromise<void> | void;

export type OnClickData = {|
    fundingSource : $Values<typeof FUNDING>,
    card? : $Values<typeof CARD>
|};

export type OnClickActions = {|
    resolve : () => ZalgoPromise<void>,
    reject : () => ZalgoPromise<void>
|};

export type OnClick = (OnClickData, OnClickActions) => void;

export type ButtonStyle = {|
    label : ?$Values<typeof BUTTON_LABEL>,
    color : $Values<typeof BUTTON_COLOR>,
    shape : $Values<typeof BUTTON_SHAPE>,
    tagline : boolean,
    layout : $Values<typeof BUTTON_LAYOUT>,
    period? : number,
    height? : number
|};

export type ButtonStyleInputs = {|
    label? : $PropertyType<ButtonStyle, 'label'> | void,
    color? : $PropertyType<ButtonStyle, 'color'> | void,
    shape? : $PropertyType<ButtonStyle, 'shape'> | void,
    tagline? : $PropertyType<ButtonStyle, 'tagline'> | void,
    layout? : $PropertyType<ButtonStyle, 'layout'> | void,
    period? : $PropertyType<ButtonStyle, 'period'> | void,
    height? : $PropertyType<ButtonStyle, 'height'> | void
|};

type PersonalizationComponentProps = {|
   logoColor : $Values<typeof LOGO_COLOR>,
   period : ?number
|};

export type Personalization = {|
    buttonText? : {|
        text : string,
        Component : ?ComponentFunctionType<PersonalizationComponentProps>,
        tracking : {|
            impression : string,
            click : string
        |}
    |},
    tagline? : {|
        text : string,
        Component : ?ComponentFunctionType<PersonalizationComponentProps>,
        tracking : {|
            impression : string,
            click : string
        |}
    |}
|};

export type RenderButtonProps = {|
    style : ButtonStyle,
    locale : LocaleType,
    commit : boolean,
    fundingSource : ?$Values<typeof FUNDING>,
    env : $Values<typeof ENV>,
    stage? : string,
    stageUrl? : string,
    platform : $Values<typeof PLATFORM>,
    fundingEligibility : FundingEligibilityType,
    remembered : $ReadOnlyArray<$Values<typeof FUNDING>>,
    clientID : string,
    sessionID : string,
    buttonSessionID : string,
    nonce : string,
    components : $ReadOnlyArray<$Values<typeof COMPONENTS>>,
    onShippingChange : ?OnShippingChange,
    personalization : ?Personalization,
    clientAccessToken : ?string,
    content : { [string] : string }
|};

export type PrerenderDetails = {|
    win : ?CrossDomainWindowType,
    fundingSource : $Values<typeof FUNDING>,
    card : ?$Values<typeof CARD>
|};

export type GetPrerenderDetails = () => PrerenderDetails | void;

export type ButtonProps = {|
    fundingSource : ?$Values<typeof FUNDING>,
    intent : $Values<typeof INTENT>,
    createOrder : CreateOrder,
    createBillingAgreement : CreateBillingAgreement,
    createSubscription : CreateSubscription,
    oncancel : OnCancel,
    onApprove : OnApprove,
    onClick : OnClick,
    getPrerenderDetails : GetPrerenderDetails,
    style : ButtonStyle,
    locale : LocaleType,
    commit : boolean,
    env : $Values<typeof ENV>,
    stage? : string,
    stageUrl? : string,
    platform : $Values<typeof PLATFORM>,
    fundingEligibility : FundingEligibilityType,
    remembered : $ReadOnlyArray<$Values<typeof FUNDING>>,
    remember : ($ReadOnlyArray<$Values<typeof FUNDING>>) => void,
    clientID : string,
    sessionID : string,
    buttonSessionID : string,
    onShippingChange : ?OnShippingChange,
    clientAccessToken : ?string,
    nonce : string
|};

export type ButtonPropsInputs = {|
    clientID : string,
    fundingSource? : $Values<typeof FUNDING>,
    style? : ButtonStyleInputs | void,
    locale? : $PropertyType<ButtonProps, 'locale'> | void,
    commit? : $PropertyType<ButtonProps, 'commit'> | void,
    env? : $PropertyType<ButtonProps, 'env'> | void,
    meta? : $PropertyType<ButtonProps, 'meta'> | void,
    stage? : $PropertyType<ButtonProps, 'stage'> | void,
    stageUrl? : $PropertyType<ButtonProps, 'stageUrl'> | void,
    platform? : $PropertyType<ButtonProps, 'platform'> | void,
    fundingEligibility? : $PropertyType<ButtonProps, 'fundingEligibility'> | void,
    remembered? : $PropertyType<ButtonProps, 'remembered'> | void,
    remember? : $PropertyType<ButtonProps, 'remember'> | void,
    sessionID? : $PropertyType<ButtonProps, 'sessionID'> | void,
    buttonSessionID? : $PropertyType<ButtonProps, 'buttonSessionID'> | void,
    nonce? : string,
    components : $ReadOnlyArray<$Values<typeof COMPONENTS>>,
    onShippingChange : ?Function,
    personalization? : Personalization,
    clientAccessToken? : string,
    csp? : {
        nonce? : string
    },
    content? : { [string] : string }
|};

export const DEFAULT_STYLE = {
    LAYOUT: BUTTON_LAYOUT.VERTICAL,
    COLOR:  BUTTON_COLOR.GOLD,
    SHAPE:  BUTTON_SHAPE.RECT
};

export const DEFAULT_PROPS = {
    LOCALE:   {
        country: COUNTRY.US,
        lang:    LANG.EN
    },
    COMMIT:   COMMIT.TRUE,
    VAULT:    VAULT.FALSE,
    INTENT:   INTENT.CAPTURE,
    ENV:      ENV.PRODUCTION,
    PLATFORM: PLATFORM.DESKTOP
};

// $FlowFixMe
export function normalizeButtonStyle(props : ?ButtonPropsInputs, style : ButtonStyleInputs) : ButtonStyle {

    if (!style) {
        throw new Error(`Expected props.style to be set`);
    }

    const { fundingSource } = props;

    const FUNDING_CONFIG = getFundingConfig();
    const fundingConfig = FUNDING_CONFIG[fundingSource || FUNDING.PAYPAL];

    if (!fundingConfig) {
        throw new Error(`Expected ${ fundingSource || FUNDING.PAYPAL } to be eligible`);
    }

    const {
        label,
        layout = fundingSource ? BUTTON_LAYOUT.HORIZONTAL : fundingConfig.layouts[0],
        color = fundingConfig.colors[0],
        shape = fundingConfig.shapes[0],
        tagline = (layout === BUTTON_LAYOUT.HORIZONTAL && !fundingSource),
        height,
        period
    } = style;

    if (values(BUTTON_LAYOUT).indexOf(layout) === -1) {
        throw new Error(`Invalid layout: ${ layout }`);
    }

    if (label && values(BUTTON_LABEL).indexOf(label) === -1) {
        throw new Error(`Invalid label: ${ label }`);
    }

    if (color && fundingConfig.colors.indexOf(color) === -1) {
        throw new Error(`Unexpected style.color for ${ FUNDING.PAYPAL } button: ${ color }, expected ${ fundingConfig.colors.join(', ') }`);
    }

    if (shape && fundingConfig.shapes.indexOf(shape) === -1) {
        throw new Error(`Unexpected style.shape for ${ FUNDING.PAYPAL } button: ${ shape }, expected ${ fundingConfig.shapes.join(', ') }`);
    }

    if (height !== undefined) {
        if (typeof height !== 'number') {
            throw new TypeError(`Expected style.height to be a number, got: ${ height }`);
        }

        const [ minHeight, maxHeight ] = [ BUTTON_SIZE_STYLE[BUTTON_SIZE.SMALL].minHeight, BUTTON_SIZE_STYLE[BUTTON_SIZE.HUGE].maxHeight ];

        if (height < minHeight || height > maxHeight) {
            throw new Error(`Expected style.height to be between ${ minHeight }px and ${ maxHeight }px - got ${ height }px`);
        }
    }

    if (layout === BUTTON_LAYOUT.VERTICAL) {
        if (tagline) {
            throw new Error(`style.tagline is not allowed for ${ BUTTON_LAYOUT.VERTICAL } layout`);
        }
    }

    return { label, layout, color, shape, tagline, height, period };
}

const COUNTRIES = values(COUNTRY);
const FUNDING_SOURCES = values(FUNDING);
const ENVS = values(ENV);
const PLATFORMS = values(PLATFORM);

export function normalizeButtonProps(props : ?ButtonPropsInputs) : RenderButtonProps {

    if (!props) {
        throw new Error(`Expected props`);
    }

    let {
        clientID,
        fundingSource,
        // $FlowFixMe
        style = {},
        remembered = [],
        locale = DEFAULT_PROPS.LOCALE,
        env = DEFAULT_PROPS.ENV,
        platform = DEFAULT_PROPS.PLATFORM,
        commit = DEFAULT_PROPS.COMMIT,
        fundingEligibility,
        sessionID = uniqueID(),
        buttonSessionID = uniqueID(),
        csp = {},
        components = [ COMPONENTS.BUTTONS ],
        nonce = '',
        onShippingChange,
        personalization,
        clientAccessToken,
        content = {}
    } = props;

    const { country, lang } = locale;

    if (!country || COUNTRIES.indexOf(country) === -1) {
        throw new Error(`Expected valid country, got ${ country || 'undefined' }`);
    }

    if (!lang || COUNTRY_LANGS[country].indexOf(lang) === -1) {
        throw new Error(`Expected valid lang, got ${ lang || 'undefined' }`);
    }

    if (remembered.some(source => FUNDING_SOURCES.indexOf(source) === -1)) {
        throw new Error(`Expected valid funding sources, got ${ JSON.stringify(remembered) }`);
    }

    if (ENVS.indexOf(env) === -1) {
        throw new Error(`Expected valid env, got ${ env || 'undefined' }`);
    }

    if (!fundingEligibility) {
        throw new Error(`Expected fundingEligibility`);
    }

    if (PLATFORMS.indexOf(platform) === -1) {
        throw new Error(`Expected valid platform, got ${ platform || 'undefined' }`);
    }

    if (csp && csp.nonce) {
        nonce = csp.nonce;
    }

    if (fundingSource) {
        if (SUPPORTED_FUNDING_SOURCES.indexOf(fundingSource) === -1) {
            throw new Error(`Invalid funding source: ${ fundingSource }`);
        }

        if (!isFundingEligible(fundingSource, { platform, fundingEligibility, components, onShippingChange })) {
            throw new Error(`Funding Source not eligible: ${ fundingSource }`);
        }
    }

    style = normalizeButtonStyle(props, style);

    return { clientID, fundingSource, style, locale, remembered, env, fundingEligibility, platform, clientAccessToken,
        buttonSessionID, commit, sessionID, nonce, components, onShippingChange, personalization, content };
}
<commit_msg>Default to paypal for style prop normalization<commit_after>/* @flow */

import { ZalgoPromise } from 'zalgo-promise/src';
import { values, uniqueID } from 'belter/src';
import { type OrderCreateRequest, type FundingEligibilityType,
    type OrderGetResponse, type OrderCaptureResponse, type OrderAuthorizeResponse } from '@paypal/sdk-client/src';
import { FUNDING, PLATFORM, INTENT, COMMIT, VAULT,
    ENV, COUNTRY, LANG, COUNTRY_LANGS, type LocaleType, CARD, COMPONENTS } from '@paypal/sdk-constants/src';
import { type CrossDomainWindowType } from 'cross-domain-utils/src';
import { LOGO_COLOR } from '@paypal/sdk-logos/src';
import { SUPPORTED_FUNDING_SOURCES } from '@paypal/funding-components/src';
import type { ComponentFunctionType } from 'jsx-pragmatic/src';

import { BUTTON_LABEL, BUTTON_COLOR, BUTTON_LAYOUT, BUTTON_SHAPE, BUTTON_SIZE } from '../../constants';
import { getFundingConfig, isFundingEligible } from '../../funding';

import { BUTTON_SIZE_STYLE } from './config';

export type CreateOrderData = {|

|} | {};

export type CreateOrderActions = {|
    order : {
        create : (OrderCreateRequest) => ZalgoPromise<string>
    }
|};

export type CreateOrder = (CreateOrderData, CreateOrderActions) => ZalgoPromise<string> | string;

export type OnApproveData = {|
    orderID : string,
    payerID : string,
    paymentID? : string
|};

export type CreateBillingAgreement = () => ZalgoPromise<string> | string;

export type CreateSubscriptionRequest = {||};
export type SubscriptionResponse = {||} | {};
export type CreateSubscriptionData = {|
|} | {};

export type CreateSubscriptionActions = {|
    subscription : {
        create : (CreateSubscriptionRequest) => ZalgoPromise<string>,
        revise : (CreateSubscriptionRequest) => ZalgoPromise<string>
    }
|};

export type CreateSubscription = (CreateSubscriptionData, CreateSubscriptionActions) => ZalgoPromise<string> | string;

export type OnApproveActions = {|
    redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>,
    order : {
        capture : () => ZalgoPromise<OrderCaptureResponse>,
        get : () => ZalgoPromise<OrderGetResponse>,
        authorize : () => ZalgoPromise<OrderAuthorizeResponse>
    },
    subscription : {
        get : () => ZalgoPromise<SubscriptionResponse>,
        activate : () => ZalgoPromise<SubscriptionResponse>
    }
|};

export type OnApprove = (data : OnApproveData, actions : OnApproveActions) => ZalgoPromise<void> | void;

type OnShippingChangeAddress = {|
    city : string,
    state : string,
    country_code : string,
    postal_code : string
|};

type OnShippingChangeMethod = {|
    label : string,
    type : string,
    amount : {
        currency_code : string,
        value : string
    }
|};

export type OnShippingChangeData = {|
    orderID : string,
    payerID : string,
    paymentID? : string,
    shipping_address : OnShippingChangeAddress,
    selected_shipping_method : OnShippingChangeMethod
|};

export type OnShippingChangeActions = {|
    order : {
        patch : () => ZalgoPromise<OrderGetResponse>
    }
|};

export type OnShippingChange = (data : OnShippingChangeData, actions : OnShippingChangeActions) => ZalgoPromise<void> | void;

export type OnCancelData = {|
    orderID : string,
    paymentID? : string
|};

export type OnCancelActions = {|
    redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>
|};

export type OnCancel = (OnCancelData, OnCancelActions) => ZalgoPromise<void> | void;

export type OnClickData = {|
    fundingSource : $Values<typeof FUNDING>,
    card? : $Values<typeof CARD>
|};

export type OnClickActions = {|
    resolve : () => ZalgoPromise<void>,
    reject : () => ZalgoPromise<void>
|};

export type OnClick = (OnClickData, OnClickActions) => void;

export type ButtonStyle = {|
    label : ?$Values<typeof BUTTON_LABEL>,
    color : $Values<typeof BUTTON_COLOR>,
    shape : $Values<typeof BUTTON_SHAPE>,
    tagline : boolean,
    layout : $Values<typeof BUTTON_LAYOUT>,
    period? : number,
    height? : number
|};

export type ButtonStyleInputs = {|
    label? : $PropertyType<ButtonStyle, 'label'> | void,
    color? : $PropertyType<ButtonStyle, 'color'> | void,
    shape? : $PropertyType<ButtonStyle, 'shape'> | void,
    tagline? : $PropertyType<ButtonStyle, 'tagline'> | void,
    layout? : $PropertyType<ButtonStyle, 'layout'> | void,
    period? : $PropertyType<ButtonStyle, 'period'> | void,
    height? : $PropertyType<ButtonStyle, 'height'> | void
|};

type PersonalizationComponentProps = {|
   logoColor : $Values<typeof LOGO_COLOR>,
   period : ?number
|};

export type Personalization = {|
    buttonText? : {|
        text : string,
        Component : ?ComponentFunctionType<PersonalizationComponentProps>,
        tracking : {|
            impression : string,
            click : string
        |}
    |},
    tagline? : {|
        text : string,
        Component : ?ComponentFunctionType<PersonalizationComponentProps>,
        tracking : {|
            impression : string,
            click : string
        |}
    |}
|};

export type RenderButtonProps = {|
    style : ButtonStyle,
    locale : LocaleType,
    commit : boolean,
    fundingSource : ?$Values<typeof FUNDING>,
    env : $Values<typeof ENV>,
    stage? : string,
    stageUrl? : string,
    platform : $Values<typeof PLATFORM>,
    fundingEligibility : FundingEligibilityType,
    remembered : $ReadOnlyArray<$Values<typeof FUNDING>>,
    clientID : string,
    sessionID : string,
    buttonSessionID : string,
    nonce : string,
    components : $ReadOnlyArray<$Values<typeof COMPONENTS>>,
    onShippingChange : ?OnShippingChange,
    personalization : ?Personalization,
    clientAccessToken : ?string,
    content : { [string] : string }
|};

export type PrerenderDetails = {|
    win : ?CrossDomainWindowType,
    fundingSource : $Values<typeof FUNDING>,
    card : ?$Values<typeof CARD>
|};

export type GetPrerenderDetails = () => PrerenderDetails | void;

export type ButtonProps = {|
    fundingSource : ?$Values<typeof FUNDING>,
    intent : $Values<typeof INTENT>,
    createOrder : CreateOrder,
    createBillingAgreement : CreateBillingAgreement,
    createSubscription : CreateSubscription,
    oncancel : OnCancel,
    onApprove : OnApprove,
    onClick : OnClick,
    getPrerenderDetails : GetPrerenderDetails,
    style : ButtonStyle,
    locale : LocaleType,
    commit : boolean,
    env : $Values<typeof ENV>,
    stage? : string,
    stageUrl? : string,
    platform : $Values<typeof PLATFORM>,
    fundingEligibility : FundingEligibilityType,
    remembered : $ReadOnlyArray<$Values<typeof FUNDING>>,
    remember : ($ReadOnlyArray<$Values<typeof FUNDING>>) => void,
    clientID : string,
    sessionID : string,
    buttonSessionID : string,
    onShippingChange : ?OnShippingChange,
    clientAccessToken : ?string,
    nonce : string
|};

export type ButtonPropsInputs = {|
    clientID : string,
    fundingSource? : $Values<typeof FUNDING>,
    style? : ButtonStyleInputs | void,
    locale? : $PropertyType<ButtonProps, 'locale'> | void,
    commit? : $PropertyType<ButtonProps, 'commit'> | void,
    env? : $PropertyType<ButtonProps, 'env'> | void,
    meta? : $PropertyType<ButtonProps, 'meta'> | void,
    stage? : $PropertyType<ButtonProps, 'stage'> | void,
    stageUrl? : $PropertyType<ButtonProps, 'stageUrl'> | void,
    platform? : $PropertyType<ButtonProps, 'platform'> | void,
    fundingEligibility? : $PropertyType<ButtonProps, 'fundingEligibility'> | void,
    remembered? : $PropertyType<ButtonProps, 'remembered'> | void,
    remember? : $PropertyType<ButtonProps, 'remember'> | void,
    sessionID? : $PropertyType<ButtonProps, 'sessionID'> | void,
    buttonSessionID? : $PropertyType<ButtonProps, 'buttonSessionID'> | void,
    nonce? : string,
    components : $ReadOnlyArray<$Values<typeof COMPONENTS>>,
    onShippingChange : ?Function,
    personalization? : Personalization,
    clientAccessToken? : string,
    csp? : {
        nonce? : string
    },
    content? : { [string] : string }
|};

export const DEFAULT_STYLE = {
    LAYOUT: BUTTON_LAYOUT.VERTICAL,
    COLOR:  BUTTON_COLOR.GOLD,
    SHAPE:  BUTTON_SHAPE.RECT
};

export const DEFAULT_PROPS = {
    LOCALE:   {
        country: COUNTRY.US,
        lang:    LANG.EN
    },
    COMMIT:   COMMIT.TRUE,
    VAULT:    VAULT.FALSE,
    INTENT:   INTENT.CAPTURE,
    ENV:      ENV.PRODUCTION,
    PLATFORM: PLATFORM.DESKTOP
};

// $FlowFixMe
export function normalizeButtonStyle(props : ?ButtonPropsInputs, style : ButtonStyleInputs) : ButtonStyle {

    if (!style) {
        throw new Error(`Expected props.style to be set`);
    }

    const { fundingSource } = props;

    const FUNDING_CONFIG = getFundingConfig();
    const fundingConfig = FUNDING_CONFIG[fundingSource || FUNDING.PAYPAL] || FUNDING_CONFIG[FUNDING.PAYPAL];

    if (!fundingConfig) {
        throw new Error(`Expected ${ fundingSource || FUNDING.PAYPAL } to be eligible`);
    }

    const {
        label,
        layout = fundingSource ? BUTTON_LAYOUT.HORIZONTAL : fundingConfig.layouts[0],
        color = fundingConfig.colors[0],
        shape = fundingConfig.shapes[0],
        tagline = (layout === BUTTON_LAYOUT.HORIZONTAL && !fundingSource),
        height,
        period
    } = style;

    if (values(BUTTON_LAYOUT).indexOf(layout) === -1) {
        throw new Error(`Invalid layout: ${ layout }`);
    }

    if (label && values(BUTTON_LABEL).indexOf(label) === -1) {
        throw new Error(`Invalid label: ${ label }`);
    }

    if (color && fundingConfig.colors.indexOf(color) === -1) {
        throw new Error(`Unexpected style.color for ${ FUNDING.PAYPAL } button: ${ color }, expected ${ fundingConfig.colors.join(', ') }`);
    }

    if (shape && fundingConfig.shapes.indexOf(shape) === -1) {
        throw new Error(`Unexpected style.shape for ${ FUNDING.PAYPAL } button: ${ shape }, expected ${ fundingConfig.shapes.join(', ') }`);
    }

    if (height !== undefined) {
        if (typeof height !== 'number') {
            throw new TypeError(`Expected style.height to be a number, got: ${ height }`);
        }

        const [ minHeight, maxHeight ] = [ BUTTON_SIZE_STYLE[BUTTON_SIZE.SMALL].minHeight, BUTTON_SIZE_STYLE[BUTTON_SIZE.HUGE].maxHeight ];

        if (height < minHeight || height > maxHeight) {
            throw new Error(`Expected style.height to be between ${ minHeight }px and ${ maxHeight }px - got ${ height }px`);
        }
    }

    if (layout === BUTTON_LAYOUT.VERTICAL) {
        if (tagline) {
            throw new Error(`style.tagline is not allowed for ${ BUTTON_LAYOUT.VERTICAL } layout`);
        }
    }

    return { label, layout, color, shape, tagline, height, period };
}

const COUNTRIES = values(COUNTRY);
const FUNDING_SOURCES = values(FUNDING);
const ENVS = values(ENV);
const PLATFORMS = values(PLATFORM);

export function normalizeButtonProps(props : ?ButtonPropsInputs) : RenderButtonProps {

    if (!props) {
        throw new Error(`Expected props`);
    }

    let {
        clientID,
        fundingSource,
        // $FlowFixMe
        style = {},
        remembered = [],
        locale = DEFAULT_PROPS.LOCALE,
        env = DEFAULT_PROPS.ENV,
        platform = DEFAULT_PROPS.PLATFORM,
        commit = DEFAULT_PROPS.COMMIT,
        fundingEligibility,
        sessionID = uniqueID(),
        buttonSessionID = uniqueID(),
        csp = {},
        components = [ COMPONENTS.BUTTONS ],
        nonce = '',
        onShippingChange,
        personalization,
        clientAccessToken,
        content = {}
    } = props;

    const { country, lang } = locale;

    if (!country || COUNTRIES.indexOf(country) === -1) {
        throw new Error(`Expected valid country, got ${ country || 'undefined' }`);
    }

    if (!lang || COUNTRY_LANGS[country].indexOf(lang) === -1) {
        throw new Error(`Expected valid lang, got ${ lang || 'undefined' }`);
    }

    if (remembered.some(source => FUNDING_SOURCES.indexOf(source) === -1)) {
        throw new Error(`Expected valid funding sources, got ${ JSON.stringify(remembered) }`);
    }

    if (ENVS.indexOf(env) === -1) {
        throw new Error(`Expected valid env, got ${ env || 'undefined' }`);
    }

    if (!fundingEligibility) {
        throw new Error(`Expected fundingEligibility`);
    }

    if (PLATFORMS.indexOf(platform) === -1) {
        throw new Error(`Expected valid platform, got ${ platform || 'undefined' }`);
    }

    if (csp && csp.nonce) {
        nonce = csp.nonce;
    }

    if (fundingSource) {
        if (SUPPORTED_FUNDING_SOURCES.indexOf(fundingSource) === -1) {
            throw new Error(`Invalid funding source: ${ fundingSource }`);
        }

        if (!isFundingEligible(fundingSource, { platform, fundingEligibility, components, onShippingChange })) {
            throw new Error(`Funding Source not eligible: ${ fundingSource }`);
        }
    }

    style = normalizeButtonStyle(props, style);

    return { clientID, fundingSource, style, locale, remembered, env, fundingEligibility, platform, clientAccessToken,
        buttonSessionID, commit, sessionID, nonce, components, onShippingChange, personalization, content };
}
<|endoftext|>


<commit_before>import angular from 'angular';
import _ from 'lodash';

import ngModule from '../module';
import '../templates';
import './constants';
import './directive';
import './manager';
import { uuid } from '../../core/utils/';

const ModalFactory = ($rootScope, $timeout, $compile, $controller, $log, AV_MODAL, avTemplateCache, $q, avModalManager) => {

  class Modal {

    constructor(options) {

      const self = this;

      this.templateDefer = $q.defer();
      this.templatePromise = this.templateDefer.promise;

      this.options = this.buildOptions(options);

      avTemplateCache.get(options).then( _template => {
        self.options.template = _template;
        self.build();
      });

    }

    static create(options) {
      return new Modal(options);
    }

    buildOptions(userOptions) {

      const options = angular.extend({}, AV_MODAL.OPTIONS, userOptions);

      options.scope = options.scope || $rootScope.$new();

      if (options.controller) {

        const locals = angular.extend({ $scope: options.scope }, options.locals);

        debugger;

        const controller = $controller(options.controller, locals);

        if (options.controllerAs) {
          if (options.scope[options.controllerAs]) {
            $log.warn('Overwriting ' + options.controllerAs + 'on scope with AvModal controllerAs, consider passing in no scope, or specifying a different controllerAs than the existing controller');
          }
          options.scope[options.controllerAs] = controller;
        }
      }
      return options;
    }

    build() {

      const scope = this.options.scope;
      this.$element = angular.element(this.options.template);

      this.createId();

      this.scope();

      $compile(this.$element)(scope);

      $timeout( () => {
        this.init();
      }, 0, true);

      // Append to container or <body>
      this.options.container ? this.$element.appendTo(this.options.container) : this.$element.appendTo('body');

    }

    init() {

      this.$element.data('AvModal', this);

      this.templateDefer.resolve(true);

      this.listeners();

      // Initialize Bootstrap jQuery plugin
      this.$element.modal({
        'backdrop': this.options.backdrop,
        'keyboard': this.options.keyboard,
        'show': false,
        'remote': this.options.remote
      });

      if (_.isUndefined(this.options.show) || this.options.show) {
        this.$element.modal('show');
      }

    }

      // Add helpers to scope so clients can call internal methods
    scope() {

      const self = this;
      const scope = this.options.scope;

      scope.modalShow = function() {
        return self.show();
      };

      scope.modalToggle = function() {
        return self.toggle();
      };

      scope.modalHide = function() {
        return self.hide();
      };

    }

    listeners() {

      const self = this;
      const scope = this.options.scope;
      const $element = this.$element;

      this.animationShowDefer = $q.defer();
      this.animationHideDefer = $q.defer();

      $element.on(AV_MODAL.BS_EVENTS.SHOW, function(event) {
        scope.$emit(AV_MODAL.EVENTS.SHOW, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.SHOWN, function(event) {

        if (angular.isFunction(self.options.onShown)) {
          self.options.onShown();
        }

        self.animationShowDefer.resolve(true);

        scope.$emit(AV_MODAL.EVENTS.SHOWN, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.HIDE, function(event) {
        scope.$emit(AV_MODAL.EVENTS.HIDE, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.HIDDEN, function(event) {

        if (angular.isFunction(self.options.onHidden)) {
          self.options.onHidden.call(this);
        }

        self.animationHideDefer.resolve(true);
        scope.$emit(AV_MODAL.EVENTS.HIDDEN, event, self);

        scope.$evalAsync(function() {
          self.destroy();
        });

      });

      // Garbage collection
      scope.$on('$destroy', function() {
        avModalManager.remove(self.id);
        self.destroy();
      });

    }

    show() {

      this.animationShowDefer = $q.defer();

      this.templatePromise.then( () => {
        this.isShown() ? this.animationShowDefer.resolve(true) : this.$element.modal('show');
      });

      return this.animationShowDefer.promise;

    }

    hide() {

      this.animationHideDefer = $q.defer();

      this.templatePromise.then( () => {
        !this.isShown() ? this.animationHideDefer.resolve(true) : this.$element.modal('hide');
      });

      return this.animationHideDefer.promise;
    }

    isShown() {
      return this.$element.data(AV_MODAL.NAMESPACE.MODAL).isShown;
    }

    toggle() {
      return this.templatePromise.then( () => {
        return this.isShown() ? this.hide() : this.show();
      });
    }

    destroy() {

      return this.templatePromise.then( () => {
        this.$element.data('AvModal', null);
        this.$element.remove();
      });

    }

    createId() {
      // Create a unique id for the modal if not present or passed in via options
      let id = this.$element.attr('id');
      if (!id) {
        // Get id from options or create a unique id
        id = this.options.id ? this.options.id : uuid('av-modal-id');
        this.$element.attr('id', id);
      }

      this.id = id;

      avModalManager.add(id);
    }

  }

  return Modal;
};

ngModule.factory('AvModal', ModalFactory);
<commit_msg>remove debugger<commit_after>import angular from 'angular';
import _ from 'lodash';

import ngModule from '../module';
import '../templates';
import './constants';
import './directive';
import './manager';
import { uuid } from '../../core/utils/';

const ModalFactory = ($rootScope, $timeout, $compile, $controller, $log, AV_MODAL, avTemplateCache, $q, avModalManager) => {

  class Modal {

    constructor(options) {

      const self = this;

      this.templateDefer = $q.defer();
      this.templatePromise = this.templateDefer.promise;

      this.options = this.buildOptions(options);

      avTemplateCache.get(options).then( _template => {
        self.options.template = _template;
        self.build();
      });

    }

    static create(options) {
      return new Modal(options);
    }

    buildOptions(userOptions) {

      const options = angular.extend({}, AV_MODAL.OPTIONS, userOptions);

      options.scope = options.scope || $rootScope.$new();

      if (options.controller) {

        const locals = angular.extend({ $scope: options.scope }, options.locals);
        const controller = $controller(options.controller, locals);

        if (options.controllerAs) {
          if (options.scope[options.controllerAs]) {
            $log.warn('Overwriting ' + options.controllerAs + 'on scope with AvModal controllerAs, consider passing in no scope, or specifying a different controllerAs than the existing controller');
          }
          options.scope[options.controllerAs] = controller;
        }
      }
      return options;
    }

    build() {

      const scope = this.options.scope;
      this.$element = angular.element(this.options.template);

      this.createId();

      this.scope();

      $compile(this.$element)(scope);

      $timeout( () => {
        this.init();
      }, 0, true);

      // Append to container or <body>
      this.options.container ? this.$element.appendTo(this.options.container) : this.$element.appendTo('body');

    }

    init() {

      this.$element.data('AvModal', this);

      this.templateDefer.resolve(true);

      this.listeners();

      // Initialize Bootstrap jQuery plugin
      this.$element.modal({
        'backdrop': this.options.backdrop,
        'keyboard': this.options.keyboard,
        'show': false,
        'remote': this.options.remote
      });

      if (_.isUndefined(this.options.show) || this.options.show) {
        this.$element.modal('show');
      }

    }

      // Add helpers to scope so clients can call internal methods
    scope() {

      const self = this;
      const scope = this.options.scope;

      scope.modalShow = function() {
        return self.show();
      };

      scope.modalToggle = function() {
        return self.toggle();
      };

      scope.modalHide = function() {
        return self.hide();
      };

    }

    listeners() {

      const self = this;
      const scope = this.options.scope;
      const $element = this.$element;

      this.animationShowDefer = $q.defer();
      this.animationHideDefer = $q.defer();

      $element.on(AV_MODAL.BS_EVENTS.SHOW, function(event) {
        scope.$emit(AV_MODAL.EVENTS.SHOW, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.SHOWN, function(event) {

        if (angular.isFunction(self.options.onShown)) {
          self.options.onShown();
        }

        self.animationShowDefer.resolve(true);

        scope.$emit(AV_MODAL.EVENTS.SHOWN, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.HIDE, function(event) {
        scope.$emit(AV_MODAL.EVENTS.HIDE, event, self);
      });

      $element.on(AV_MODAL.BS_EVENTS.HIDDEN, function(event) {

        if (angular.isFunction(self.options.onHidden)) {
          self.options.onHidden.call(this);
        }

        self.animationHideDefer.resolve(true);
        scope.$emit(AV_MODAL.EVENTS.HIDDEN, event, self);

        scope.$evalAsync(function() {
          self.destroy();
        });

      });

      // Garbage collection
      scope.$on('$destroy', function() {
        avModalManager.remove(self.id);
        self.destroy();
      });

    }

    show() {

      this.animationShowDefer = $q.defer();

      this.templatePromise.then( () => {
        this.isShown() ? this.animationShowDefer.resolve(true) : this.$element.modal('show');
      });

      return this.animationShowDefer.promise;

    }

    hide() {

      this.animationHideDefer = $q.defer();

      this.templatePromise.then( () => {
        !this.isShown() ? this.animationHideDefer.resolve(true) : this.$element.modal('hide');
      });

      return this.animationHideDefer.promise;
    }

    isShown() {
      return this.$element.data(AV_MODAL.NAMESPACE.MODAL).isShown;
    }

    toggle() {
      return this.templatePromise.then( () => {
        return this.isShown() ? this.hide() : this.show();
      });
    }

    destroy() {

      return this.templatePromise.then( () => {
        this.$element.data('AvModal', null);
        this.$element.remove();
      });

    }

    createId() {
      // Create a unique id for the modal if not present or passed in via options
      let id = this.$element.attr('id');
      if (!id) {
        // Get id from options or create a unique id
        id = this.options.id ? this.options.id : uuid('av-modal-id');
        this.$element.attr('id', id);
      }

      this.id = id;

      avModalManager.add(id);
    }

  }

  return Modal;
};

ngModule.factory('AvModal', ModalFactory);
<|endoftext|>


<commit_before>import { createElement as h } from 'react'
import { render } from 'react-dom'
import { bindActionCreators } from 'redux'
import { Provider, connect } from 'react-redux'

import isDemo from '../../utils/isDemo'

import enhanceState from './enhancers/enhanceState'
import createStore from './utils/createStore'
import * as storage from './utils/storage'
import reducers from './reducers'
import * as actions from './actions'

import { initialState as initialTokenState } from './reducers/token'
import { initialState as initialRouteState } from './reducers/route'
import { initialState as initialViewsState } from './reducers/views'
import { initialState as initialPagesState } from './reducers/pages'
import { initialState as initialReferrersState } from './reducers/referrers'
import { initialState as initialDurationsState } from './reducers/durations'
import { initialState as initialLanguagesState } from './reducers/languages'
import { initialState as initialOsState } from './reducers/os'
import { initialState as initialSizesState } from './reducers/sizes'

import Main from './components/Main'

const persistedState = storage.load()
const store = createStore(reducers, persistedState)

const mapStateToProps = (state) => enhanceState(state)
const mapDispatchToProps = (dispatch) => bindActionCreators(actions, dispatch)

const ConnectedMain = connect(mapStateToProps, mapDispatchToProps)(Main)
const container = document.querySelector('#main')

if (isDemo === true) {
	console.warn('Ackee runs in demo mode')
}

store.subscribe(() => {

	const currentState = store.getState()

	storage.save({
		token: {
			...initialTokenState(),
			value: currentState.token.value
		},
		route: {
			...initialRouteState(),
			value: currentState.route.value
		},
		views: {
			...initialViewsState(),
			type: currentState.views.type,
			interval: currentState.views.interval
		},
		pages: {
			...initialPagesState(),
			dateRange: currentState.pages.dateRange,
			sorting: currentState.pages.sorting
		},
		referrers: {
			...initialReferrersState(),
			dateRange: currentState.referrers.dateRange,
			sorting: currentState.referrers.sorting
		},
		durations: {
			...initialDurationsState(),
			type: currentState.durations.type
		},
		languages: {
			...initialLanguagesState(),
			dateRange: currentState.languages.dateRange,
			sorting: currentState.languages.sorting
		},
		os: {
			...initialOsState(),
			dateRange: currentState.os.dateRange,
			type: currentState.os.type,
			sorting: currentState.os.sorting
		},
		sizes: {
			...initialSizesState(),
			dateRange: currentState.sizes.dateRange,
			type: currentState.sizes.type
		}
	})

})

const App = h(Provider, { store },
	h(ConnectedMain)
)

render(App, container)<commit_msg>Save state of browsers and devices<commit_after>import { createElement as h } from 'react'
import { render } from 'react-dom'
import { bindActionCreators } from 'redux'
import { Provider, connect } from 'react-redux'

import isDemo from '../../utils/isDemo'

import enhanceState from './enhancers/enhanceState'
import createStore from './utils/createStore'
import * as storage from './utils/storage'
import reducers from './reducers'
import * as actions from './actions'

import { initialState as initialTokenState } from './reducers/token'
import { initialState as initialRouteState } from './reducers/route'
import { initialState as initialViewsState } from './reducers/views'
import { initialState as initialPagesState } from './reducers/pages'
import { initialState as initialReferrersState } from './reducers/referrers'
import { initialState as initialDurationsState } from './reducers/durations'
import { initialState as initialLanguagesState } from './reducers/languages'
import { initialState as initialOsState } from './reducers/os'
import { initialState as initialBrowsersState } from './reducers/browsers'
import { initialState as initialDevicesState } from './reducers/devices'
import { initialState as initialSizesState } from './reducers/sizes'

import Main from './components/Main'

const persistedState = storage.load()
const store = createStore(reducers, persistedState)

const mapStateToProps = (state) => enhanceState(state)
const mapDispatchToProps = (dispatch) => bindActionCreators(actions, dispatch)

const ConnectedMain = connect(mapStateToProps, mapDispatchToProps)(Main)
const container = document.querySelector('#main')

if (isDemo === true) {
	console.warn('Ackee runs in demo mode')
}

store.subscribe(() => {

	const currentState = store.getState()

	storage.save({
		token: {
			...initialTokenState(),
			value: currentState.token.value
		},
		route: {
			...initialRouteState(),
			value: currentState.route.value
		},
		views: {
			...initialViewsState(),
			type: currentState.views.type,
			interval: currentState.views.interval
		},
		pages: {
			...initialPagesState(),
			dateRange: currentState.pages.dateRange,
			sorting: currentState.pages.sorting
		},
		referrers: {
			...initialReferrersState(),
			dateRange: currentState.referrers.dateRange,
			sorting: currentState.referrers.sorting
		},
		durations: {
			...initialDurationsState(),
			type: currentState.durations.type
		},
		languages: {
			...initialLanguagesState(),
			dateRange: currentState.languages.dateRange,
			sorting: currentState.languages.sorting
		},
		os: {
			...initialOsState(),
			dateRange: currentState.os.dateRange,
			type: currentState.os.type,
			sorting: currentState.os.sorting
		},
		browsers: {
			...initialBrowsersState(),
			dateRange: currentState.browsers.dateRange,
			type: currentState.browsers.type,
			sorting: currentState.browsers.sorting
		},
		devices: {
			...initialDevicesState(),
			dateRange: currentState.devices.dateRange,
			type: currentState.devices.type,
			sorting: currentState.devices.sorting
		},
		sizes: {
			...initialSizesState(),
			dateRange: currentState.sizes.dateRange,
			type: currentState.sizes.type
		}
	})

})

const App = h(Provider, { store },
	h(ConnectedMain)
)

render(App, container)<|endoftext|>


<commit_before>let wheelHandlers = {
  playbackSpeed: (() => {
    let maxPlaybackRate = 100,
        minPlaybackRate = 0.0000001,
        lastWheelTime = new Date().getTime();

    return ($scope, videoEl, event) => {
      let time = new Date().getTime(),
          dt = time - lastWheelTime,
          currentRate = videoEl.playbackRate || minPlaybackRate;

      let delta = 0;
      if (event.deltaY > 0) {
        delta = -0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }
      else if (event.deltaY < 0) {
        delta = 0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }

      if (delta !== 0) {
        let newRate = currentRate + delta;
        $scope.$apply(() => $scope.setPlaybackRate(clamp(newRate, maxPlaybackRate, minPlaybackRate)));
      }

      lastWheelTime = time;
    };
  })(),
  zoom: (() => {
    let lastWheelTime = new Date().getTime();

    return ($scope, videoEl, event) => {
      let time = new Date().getTime(),
          dt = time - lastWheelTime,
          currentRate = videoEl.playbackRate || minPlaybackRate;

      let delta = 0;
      if (event.deltaY > 0) {
        delta = -0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }
      else if (event.deltaY < 0) {
        delta = 0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }

      if (delta !== 0) {
        let newRate = currentRate + delta;
        $scope.$apply(() => $scope.setPlaybackRate(clamp(newRate, maxPlaybackRate, minPlaybackRate)));
      }

      lastWheelTime = time;
    };
  })()
};

module.exports = [() => {
  return {
    restrict: 'E',
    template: require('./template.html'),
    link: ($scope, element, attributes) => {
      let videoEl = element.find('video')[0],
          overlayEl = element.find('div')[0],
          currentMode = 'playbackSpeed',
          video = angular.element(videoEl),
          overlay = angular.element(overlayEl);

      $scope.videoEl = videoEl;

      videoEl.addEventListener('loadeddata', loadeddata);
      videoEl.addEventListener('loadedmetadata', loadedmetadata);
      videoEl.addEventListener('loadstart', loadstart);
      videoEl.addEventListener('error', error);
      overlayEl.addEventListener('wheel', wheel);

      function loadeddata(event) {
        console.log('loadeddata', event);
      }

      function loadedmetadata(event) {
        console.log('loadedmetadata', event);
      }

      function loadstart(event) {
        $scope.$apply(() => {
          $scope.video.success = true;
        });
      }

      function error() {
        $scope.$apply(() => {
          $scope.video.src = undefined;
          $scope.video.success = false;
          $scope.video.error = videoEl.error;
          $scope.haveVideo = false;

          console.log($scope);
        });
        console.log('error', arguments);
      }

      function wheel(event) {
        wheelHandlers[currentMode]($scope, videoEl, event);
      }

      $scope.togglePlay = () => {
        if (videoEl.paused) videoEl.play();
        else videoEl.pause();
      };

      $scope.setCurrentTime = time => {
        if (videoEl.duration > 0) videoEl.currentTime = time;
      };

      $scope.incrementCurrentTime = delta => {
        if (videoEl.duration > 0) videoEl.currentTime += delta;
      };

      $scope.setPlaybackRate = rate => {
        if (rate === undefined) rate = 1;

        videoEl.playbackRate = rate;
        if      (rate < 0.0005) rate = rate.toFixed(7);
        else if (rate < 0.005) rate = rate.toFixed(6);
        else if (rate < 0.05) rate = rate.toFixed(5);
        else if (rate < 0.5) rate = rate.toFixed(4);
        else rate = rate.toFixed(3);
        $scope.playbackRate = rate;
      };

      $scope.createMediaElementSource = context => {
        return context.createMediaElementSource(videoEl);
      };

      $scope.setPlaybackRate(videoEl.playbackRate);
    },
    controller: ['$scope', $scope => {
      $scope.showFilters = true;
    }]
  };
}];

function clamp(value, max, min) {
  return Math.min(max, Math.max(min, value));
}<commit_msg>Reset playbackRate on new video.<commit_after>let wheelHandlers = {
  playbackSpeed: (() => {
    let maxPlaybackRate = 100,
        minPlaybackRate = 0.0000001,
        lastWheelTime = new Date().getTime();

    return ($scope, videoEl, event) => {
      let time = new Date().getTime(),
          dt = time - lastWheelTime,
          currentRate = videoEl.playbackRate || minPlaybackRate;

      let delta = 0;
      if (event.deltaY > 0) {
        delta = -0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }
      else if (event.deltaY < 0) {
        delta = 0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }

      if (delta !== 0) {
        let newRate = currentRate + delta;
        $scope.$apply(() => $scope.setPlaybackRate(clamp(newRate, maxPlaybackRate, minPlaybackRate)));
      }

      lastWheelTime = time;
    };
  })(),
  zoom: (() => {
    let lastWheelTime = new Date().getTime();

    return ($scope, videoEl, event) => {
      let time = new Date().getTime(),
          dt = time - lastWheelTime,
          currentRate = videoEl.playbackRate || minPlaybackRate;

      let delta = 0;
      if (event.deltaY > 0) {
        delta = -0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }
      else if (event.deltaY < 0) {
        delta = 0.001 * (1000 / clamp(dt, 1000, 0)) * currentRate;
      }

      if (delta !== 0) {
        let newRate = currentRate + delta;
        $scope.$apply(() => $scope.setPlaybackRate(clamp(newRate, maxPlaybackRate, minPlaybackRate)));
      }

      lastWheelTime = time;
    };
  })()
};

module.exports = [() => {
  return {
    restrict: 'E',
    template: require('./template.html'),
    link: ($scope, element, attributes) => {
      let videoEl = element.find('video')[0],
          overlayEl = element.find('div')[0],
          currentMode = 'playbackSpeed',
          video = angular.element(videoEl),
          overlay = angular.element(overlayEl);

      $scope.videoEl = videoEl;

      videoEl.addEventListener('loadeddata', loadeddata);
      videoEl.addEventListener('loadedmetadata', loadedmetadata);
      videoEl.addEventListener('loadstart', loadstart);
      videoEl.addEventListener('error', error);
      overlayEl.addEventListener('wheel', wheel);

      function loadeddata(event) {
        console.log('loadeddata', event);
      }

      function loadedmetadata(event) {
        console.log('loadedmetadata', event);
      }

      function loadstart(event) {
        $scope.$apply(() => {
          $scope.video.success = true;
          $scope.setPlaybackRate(1);
        });
      }

      function error() {
        $scope.$apply(() => {
          $scope.video.src = undefined;
          $scope.video.success = false;
          $scope.video.error = videoEl.error;
          $scope.haveVideo = false;

          console.log($scope);
        });
        console.log('error', arguments);
      }

      function wheel(event) {
        wheelHandlers[currentMode]($scope, videoEl, event);
      }

      $scope.togglePlay = () => {
        if (videoEl.paused) videoEl.play();
        else videoEl.pause();
      };

      $scope.setCurrentTime = time => {
        if (videoEl.duration > 0) videoEl.currentTime = time;
      };

      $scope.incrementCurrentTime = delta => {
        if (videoEl.duration > 0) videoEl.currentTime += delta;
      };

      $scope.setPlaybackRate = rate => {
        if (rate === undefined) rate = 1;

        videoEl.playbackRate = rate;
        if      (rate < 0.0005) rate = rate.toFixed(7);
        else if (rate < 0.005) rate = rate.toFixed(6);
        else if (rate < 0.05) rate = rate.toFixed(5);
        else if (rate < 0.5) rate = rate.toFixed(4);
        else rate = rate.toFixed(3);
        $scope.playbackRate = rate;
      };

      $scope.createMediaElementSource = context => {
        return context.createMediaElementSource(videoEl);
      };

      $scope.setPlaybackRate(videoEl.playbackRate);
    },
    controller: ['$scope', $scope => {
      $scope.showFilters = true;
    }]
  };
}];

function clamp(value, max, min) {
  return Math.min(max, Math.max(min, value));
}<|endoftext|>


<commit_before>

//expose the main layout panels for use later.
 var northPanel, southPanel, eastPanel, westPanel, centerPanel;

//The simple function will be called when the document is finished loading.  See event at bottem of file
Simple = function() {

   return {
       init : function() {
           var mainLayout = new Ext.BorderLayout("layout", {
               north: {
                   split: false, initialSize: 30
               },
               south: {
                   split: false, initialSize: 400
               },
               east: {
                   split: true, initialSize: 0
               },
               west: {
                   split: true, initialSize: 300
               },
               center: { split: true, initialSize: 80
               }
           });
           mainLayout.beginUpdate();
           mainLayout.add('north', northPanel = new Ext.ContentPanel('north-div', {
              fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('south', southPanel = new Ext.ContentPanel('south-div', {
               fitToFrame: true, closable: false
           }));
           mainLayout.add('east', eastPanel = new Ext.ContentPanel('east-div', {
               fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('west', westPanel = new Ext.ContentPanel('west-div', {
               fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('center', centerPanel = new Ext.ContentPanel('center-div', {
               fitToFrame: true , autoScroll: true
           }));
           mainLayout.endUpdate();
                       mainLayout.getRegion('east').hide();
                       mainLayout.getRegion('north').hide();
                       initBioMaterialGrid( );
                       initTree( );
               }
   };
}();

var showbms = function( id ) {
       var ids =  id.split(",");
       // note how we pass the new array in directly, without wraping it in an object first.
       ds.load({params:[ids]});
};

var ds;

var initBioMaterialGrid = function(div) {
       var     recordType = Ext.data.Record.create([
                       {name:"id", type:"int"},
                       {name:"name", type:"string"},
                       {name:"description", type:"string"}
               ]);

       ds = new Ext.data.Store(
               {
                       proxy:new Ext.data.DWRProxy(BioMaterialController.getBioMaterials),
                       reader:new Ext.data.ListRangeReader({id:"id"}, recordType),
                       remoteSort:false,
                       sortInfo:{field:'name'}
               });

       var cm = new Ext.grid.ColumnModel([
                       {header: "Name", width: 50, dataIndex:"name"},
                       {header: "Description",  width: 80, dataIndex:"description"}
                       ]);
       cm.defaultSortable = true;

       grid = new Ext.grid.Grid("south-div", {autoSizeColumns: true, ds:ds,cm:cm, loadMask: true });
       grid.render();

       var id = dwr.util.getValue("cslist");
       showbms(id);
};

var initTree = function(div){

   var tree = new Ext.tree.TreePanel("west-div", {
       animate:true,
       loader: new Ext.tree.DwrTreeLoader({dataUrl:MgedOntologyService.getBioMaterialTerms})
   });

   tree.on('click', function(node){
                   MgedOntologyService.getTerm(node.id,displayRestrictionsPanel);
          });

   // set the root node
   var root = new Ext.tree.AsyncTreeNode({
       text: 'Top of the tree',
       draggable:false,
       allowChildre:true,
       id:'root'
   });
   tree.setRootNode(root);

   // render the tree
   tree.render();
   root.expand();

};

//The call back method for the dwr call
var displayRestrictionsPanel = function(node){
	console.log(dwr.util.toDescriptiveString(node, 10));
	createRestrictionGui(node);
};

//Recursive function that walks the node given to it and creates a coresponding form to fill in
var createRestrictionGui = function(node, indent) {

		var dh = Ext.DomHelper;  //allows html output

		if (indent === undefined){
			dh.overwrite("center-div", {html : ""});
			indent = "";
		}

		dh.append("center-div", {html : indent + "Details for: " + node.uri });

        var res = node.restrictions;
        if ( (res !== undefined) && (res !== null) && (res.size() > 0) ) {

            for ( var i = 0, len = res.length; i < len; i++ ) {
            	var restrictedOn = res[i].restrictionOn;
            	var restrictedTo = res[i].restrictedTo;
            	var divId = (Math.random() * 100000).toFixed();
            	dh.append("center-div", {tag: 'div', id: divId});

                if ( (res[i].restrictedTo !== undefined) && (res[i].restrictedTo !== null)) {	//is it a class restriction?

                    dh.append( "center-div", {html : indent + " Restricted To Slot to fill in: " + restrictedOn.label + " with a " + restrictedTo.term });

                    if (restrictedTo.individuals !== undefined && restrictedTo.individuals !== null && restrictedTo.individuals.size() > 0){

                    	var recordType = Ext.data.Record.create([
							{name:"label", type : "string" },
							{name:"uri", type: "string" }
						]);

						var records = [];
						for(var i = 0, len = restrictedTo.individuals.length; i < len; i++) {
							records.push(new recordType(restrictedTo.individuals[i]));
						}

	                    var store = new Ext.data.Store({recordType : recordType} );
						store.add(records);

					    var combo = new Ext.form.ComboBox({
					        store: store,
					        displayField:'label',
					        typeAhead: true,
					        mode: 'local',
					        triggerAction: 'all',
					        emptyText:'Select an individual',
					        selectOnFocus:true
					    });

					    //Need to make a div to apply the combo box to.
					 	dh.append(divId, {tag: 'input', type: 'text', id: "input" + divId , size:'20'});
					    combo.applyTo("input" + divId);
                    }

                    dh.append(divId, "This will be a free-text field");
                    dh.append(divId, "This will be a search field");

                    createRestrictionGui( restrictedTo, "    " + indent );

                } else if ( res[i].type !== undefined ) {	//Primitive Type
                    var primitiveRestrictedTo = res[i].type
                    dh.append("center-div", {html : indent + " Primitive Type Slot to fill in: " + restrictedOn.label + " with a " + primitiveRestrictedTo.term });

                } else if ( res[i].cardinality !== undefined  ) { //Cardinality Type
                    // this will be rare.
                    var cardinality = res[i].cardinality;
                    var cardinalityType = res[i].cardinalityType;
                    dh.append("center-div",{ html: indent + " Cardinality Slot to fill in: " + restrictedOn.label + " with " + cardinalityType.term + " "
                            + cardinality + " things" });
                    // todo check range of the property (what 'things' should be) if specified.
                }
                else if ((res[id].restrictions !== undefined) &&  (res[id].restrictions !== null)) {
                	  dh.append("center-div",{ html: indent + " Restrictions  slot: " + res[id].restrictions });
                	  createRestrictionGui(res[id].restrictions, "===>" + indent);
                }
                else{
                	  dh.append("center-div",{ html: indent + " Catch all slot: " });

                }
            }
        }
	    dh.append("center-div", {html : indent + "End of details for " + node.uri}) ;
    };

Ext.EventManager.onDocumentReady(Simple.init, Simple, true);

<commit_msg>display or restrictions working. Added form elements<commit_after>

//expose the main layout panels for use later.
 var northPanel, southPanel, eastPanel, westPanel, centerPanel;

//The simple function will be called when the document is finished loading.  See event at bottem of file
Simple = function() {

   return {
       init : function() {
           var mainLayout = new Ext.BorderLayout("layout", {
               north: {
                   split: false, initialSize: 30
               },
               south: {
                   split: false, initialSize: 400
               },
               east: {
                   split: true, initialSize: 0
               },
               west: {
                   split: true, initialSize: 300
               },
               center: { split: true, initialSize: 80
               }
           });
           mainLayout.beginUpdate();
           mainLayout.add('north', northPanel = new Ext.ContentPanel('north-div', {
              fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('south', southPanel = new Ext.ContentPanel('south-div', {
               fitToFrame: true, closable: false
           }));
           mainLayout.add('east', eastPanel = new Ext.ContentPanel('east-div', {
               fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('west', westPanel = new Ext.ContentPanel('west-div', {
               fitToFrame: true, closable: false, autoScroll: true
           }));
           mainLayout.add('center', centerPanel = new Ext.ContentPanel('center-div', {
               fitToFrame: true , autoScroll: true
           }));
           mainLayout.endUpdate();
                       mainLayout.getRegion('east').hide();
                       mainLayout.getRegion('north').hide();
                       initBioMaterialGrid( );
                       initTree( );
               }
   };
}();

var showbms = function( id ) {
       var ids =  id.split(",");
       // note how we pass the new array in directly, without wraping it in an object first.
       ds.load({params:[ids]});
};

var ds;

var initBioMaterialGrid = function(div) {
       var     recordType = Ext.data.Record.create([
                       {name:"id", type:"int"},
                       {name:"name", type:"string"},
                       {name:"description", type:"string"}
               ]);

       ds = new Ext.data.Store(
               {
                       proxy:new Ext.data.DWRProxy(BioMaterialController.getBioMaterials),
                       reader:new Ext.data.ListRangeReader({id:"id"}, recordType),
                       remoteSort:false,
                       sortInfo:{field:'name'}
               });

       var cm = new Ext.grid.ColumnModel([
                       {header: "Name", width: 50, dataIndex:"name"},
                       {header: "Description",  width: 80, dataIndex:"description"}
                       ]);
       cm.defaultSortable = true;

       grid = new Ext.grid.Grid("south-div", {autoSizeColumns: true, ds:ds,cm:cm, loadMask: true });
       grid.render();

       var id = dwr.util.getValue("cslist");
       showbms(id);
};

var initTree = function(div){

   var tree = new Ext.tree.TreePanel("west-div", {
       animate:true,
       loader: new Ext.tree.DwrTreeLoader({dataUrl:MgedOntologyService.getBioMaterialTerms})
   });

   tree.on('click', function(node){
                   MgedOntologyService.getTerm(node.id,displayRestrictionsPanel);
          });

   // set the root node
   var root = new Ext.tree.AsyncTreeNode({
       text: 'Top of the tree',
       draggable:false,
       allowChildre:true,
       id:'root'
   });
   tree.setRootNode(root);

   // render the tree
   tree.render();
   root.expand();

};

//The call back method for the dwr call
var displayRestrictionsPanel = function(node){
	console.log(dwr.util.toDescriptiveString(node, 10));
	createRestrictionGui(node);
};

//Recursive function that walks the node given to it and creates a coresponding form to fill in
var createRestrictionGui = function(node, indent, parentDivId) {

		var dh = Ext.DomHelper;  //allows html output

		if (indent === undefined){
			dh.overwrite("center-div", {html : ""});
			indent = "";
		}
		if (parentDivId === undefined) {
			parentDivId = "center-div";
		}

		//dh.append(parentDivId, {html : indent + "Details for: " + node.uri });

        var res = node.restrictions;
        if ( (res !== undefined) && (res !== null) && (res.size() > 0) ) {

            for ( var i = 0, len = res.length; i < len; i++ ) {
            	var restrictedOn = res[i].restrictionOn;
            	var restrictedTo = res[i].restrictedTo;
            	//make a nested div for adding to.
            	var divId = (Math.random() * 100000).toFixed();
            	dh.append(parentDivId, {tag: 'div', id: divId});

            	if (restrictedOn.type !== undefined ) {	//Primitive Type
                    var primitiveRestrictedTo = restrictedOn.type
                    dh.append(parentDivId, {html : indent + " Primitive Type Slot to fill in: " + restrictedOn.label + " with a " + primitiveRestrictedTo.value });
            	} else if ( (restrictedTo !== undefined) && (restrictedTo !== null)) {	//is it a class restriction?

                    if (restrictedTo.restrictions === undefined || restrictedTo.restrictions === null || restrictedTo.restrictions.size() === 0){	// ie) we are at a leaf node so display gui
                        dh.append(divId, {html : indent + " Restricted To Slot to fill in: " + restrictedOn.label + " with a " + restrictedTo.term });

	                    var simple = createForm();

    	                if (restrictedTo.individuals !== undefined && restrictedTo.individuals !== null && restrictedTo.individuals.size() > 0){  //are there examples?
        		            	simple.add(createComboBox(restrictedTo.individuals));
                	    }

	                    simple.render(divId);
                    } else{        //Not a leaf node. recurse down another level
                        dh.append(divId, {html : indent + " The " + restrictedOn.label + " restriction has " + restrictedTo.restrictions.size()+ " slots to fill in"});
    	            	createRestrictionGui( restrictedTo, "    " + indent, divId );
                   }

                } else if ( res[i].cardinality !== undefined  ) { //Cardinality Type
                    // this will be rare.
                    var cardinality = res[i].cardinality;
                    var cardinalityType = res[i].cardinalityType;
                    dh.append(parentDivId,{ html: indent + " Cardinality Slot to fill in: " + restrictedOn.label + " with " + cardinalityType.term + " "
                            + cardinality + " things" });
                    // todo check range of the property (what 'things' should be) if specified.
                } else{
                	  dh.append(parentDivId,{ html: indent + " Error: This should not happen" });
                }
            }
        }
	    //dh.append(parentDivId, {html : indent + "End of details for " + node.uri}) ;
    };

var createComboBox = function(individuals){
	     	var recordType = Ext.data.Record.create([
							{name:"label", type : "string" },
							{name:"uri", type: "string" }
						]);

						//convert the arry of objects into an array of records
						var records = [];
						for(var i = 0, len = individuals.length; i < len; i++) {
							records.push(new recordType(individuals[i]));
						}

	                    var store = new Ext.data.Store({recordType : recordType} );
						store.add(records);

					    var combo = new Ext.form.ComboBox({
					    	fieldLabel: 'pick one',
					        store: store,
					        displayField:'label',
					        typeAhead: true,
					        mode: 'local',
					        triggerAction: 'all',
					        emptyText:'Select an individual',
					        selectOnFocus:true
					    });

					    return combo;

};

var createForm = function(){
	var simple = new Ext.form.Form({
					        labelWidth: 75, // label settings here cascade unless overridden
					        url:'save-form.php'
					    });
					    simple.add(
					        new Ext.form.TextField({
					            fieldLabel: 'Lookup',
					            name: 'lookup',
					            width:175,
					            allowBlank:true
					        }),

					        new Ext.form.TextField({
					            fieldLabel: 'custom',
					            name: 'custom',
					            width:175
					        })
					    );

					    //simple.addButton('Save');
					    //simple.addButton('Cancel');

					   return simple;
}

Ext.EventManager.onDocumentReady(Simple.init, Simple, true);

<|endoftext|>


<commit_before>const webpack = require('webpack');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const StringReplacePlugin = require('string-replace-webpack-plugin');

module.exports = function (options) {
    const DATAS = {
        VERSION: JSON.stringify(require("../package.json").version),
        DEBUG_INFO_ENABLED: options.env === 'dev'
    };
    return {
        entry: {
            'polyfills': './src/main/webapp/app/polyfills',
            'vendor': './src/main/webapp/app/vendor',
            'main': './src/main/webapp/app/app.main'
        },
        resolve: {
            extensions: ['.ts', '.js'],
            modules: ['node_modules']
        },
        output: {
            path: <% if (buildTool === 'gradle') { %>'./build/www'<% } else { %>'./target/www'<% } %>,
            filename: '[name].bundle.js',
            chunkFilename: '[id].chunk.js'
        },
        devServer: {
            proxy: [{
                context: [<% if (authenticationType == 'oauth2') { %>
                    '/oauth',<% } %>
                    '/api',
                    '/management',
                    '/swagger-resources',
                    '/v2/api-docs',
                    '/h2-console'
                ],
                target: 'http://127.0.0.1:<%= serverPort %>',
                secure: false
            }]
        },
        module: {
            rules: [
                { test: /[\/]angular\.js$/, loader: "exports-loader?angular" },
                { test: /bootstrap\/dist\/js\/umd\//, loader: 'imports-loader?jQuery=jquery' },
                {
                    test: /\.ts$/,
                    loaders: [
                        'angular2-template-loader',
                        'awesome-typescript-loader'
                    ],
                    exclude: ['node_modules/generator-jhipster']
                },
                {
                    test: /\.html$/,
                    loader: 'raw-loader',
                    exclude: ['./src/main/webapp/index.html']
                },
                <%_ if (useSass) { _%>
                { test: /\.scss$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },
                <%_ } _%>
                {
                    test: /\.css$/,
                    loader: ExtractTextPlugin.extract({
                        fallbackLoader: "style-loader",
                        loader: "css-loader"
                    })
                },
                {
                    test: /\.(jpe?g|png|gif|svg|woff|woff2|ttf|eot)$/i,
                    loaders: [
                        'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
                        'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
                    ]
                },
                {
                    test: /app.constants.ts$/,
                    loader: StringReplacePlugin.replace({
                        replacements: [{
                            pattern: /\/\* @toreplace (\w*?) \*\//ig,
                            replacement: function (match, p1, offset, string) {
                                return `_${p1} = ${DATAS[p1]};`;
                            }
                        }
                    ]})
                }
            ]
        },
        plugins: [
            new CommonsChunkPlugin({
                name: ['polyfills', 'vendor'].reverse()
            }),
            new CopyWebpackPlugin([
                { from: './node_modules/swagger-ui/dist', to: 'swagger-ui/dist' },
                { from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' }<% if (enableTranslation) { %>,
                { from: './src/main/webapp/i18n', to: 'i18n' }<% } %>
            ]),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery"
            }),
            new HtmlWebpackPlugin({
                template: './src/main/webapp/index.ejs',
                chunksSortMode: 'dependency',
                inject: 'body',
                data: DATAS
            }),
            new StringReplacePlugin()
        ]
    };
};
<commit_msg>split vendor and main bundle<commit_after>const webpack = require('webpack');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const StringReplacePlugin = require('string-replace-webpack-plugin');

module.exports = function (options) {
    const DATAS = {
        VERSION: JSON.stringify(require("../package.json").version),
        DEBUG_INFO_ENABLED: options.env === 'dev'
    };
    return {
        entry: {
            'polyfills': './src/main/webapp/app/polyfills',
            'vendor': [
                './src/main/webapp/app/vendor',
                '@angular/common',
                '@angular/compiler',
                '@angular/core',
                '@angular/forms',
                '@angular/http',
                '@angular/platform-browser',
                '@angular/platform-browser-dynamic',
                '@angular/upgrade',
                '@ng-bootstrap/ng-bootstrap',
                'angular2-cookie',
                'jquery',
                'ng-jhipster',
                'ng2-webstorage',
                'rxjs',
                <%_ if (websocket == 'spring-websocket') { _%>
                'sockjs-client',
                'webstomp-client',
                <%_ } _%>
                'ui-router-ng2'
            ],
            'main': './src/main/webapp/app/app.main'
        },
        resolve: {
            extensions: ['.ts', '.js'],
            modules: ['node_modules']
        },
        output: {
            path: <% if (buildTool === 'gradle') { %>'./build/www'<% } else { %>'./target/www'<% } %>,
            filename: '[name].bundle.js',
            chunkFilename: '[id].chunk.js'
        },
        devServer: {
            proxy: [{
                context: [<% if (authenticationType == 'oauth2') { %>
                    '/oauth',<% } %>
                    '/api',
                    '/management',
                    '/swagger-resources',
                    '/v2/api-docs',
                    '/h2-console'
                ],
                target: 'http://127.0.0.1:<%= serverPort %>',
                secure: false
            }]
        },
        module: {
            rules: [
                { test: /[\/]angular\.js$/, loader: "exports-loader?angular" },
                { test: /bootstrap\/dist\/js\/umd\//, loader: 'imports-loader?jQuery=jquery' },
                {
                    test: /\.ts$/,
                    loaders: [
                        'angular2-template-loader',
                        'awesome-typescript-loader'
                    ],
                    exclude: ['node_modules/generator-jhipster']
                },
                {
                    test: /\.html$/,
                    loader: 'raw-loader',
                    exclude: ['./src/main/webapp/index.html']
                },
                <%_ if (useSass) { _%>
                { test: /\.scss$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },
                <%_ } _%>
                {
                    test: /\.css$/,
                    loader: ExtractTextPlugin.extract({
                        fallbackLoader: "style-loader",
                        loader: "css-loader"
                    })
                },
                {
                    test: /\.(jpe?g|png|gif|svg|woff|woff2|ttf|eot)$/i,
                    loaders: [
                        'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
                        'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
                    ]
                },
                {
                    test: /app.constants.ts$/,
                    loader: StringReplacePlugin.replace({
                        replacements: [{
                            pattern: /\/\* @toreplace (\w*?) \*\//ig,
                            replacement: function (match, p1, offset, string) {
                                return `_${p1} = ${DATAS[p1]};`;
                            }
                        }
                    ]})
                }
            ]
        },
        plugins: [
            new CommonsChunkPlugin({
                names: ['manifest', 'polyfills', 'vendor'].reverse()
            }),
            new CopyWebpackPlugin([
                { from: './node_modules/swagger-ui/dist', to: 'swagger-ui/dist' },
                { from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' }<% if (enableTranslation) { %>,
                { from: './src/main/webapp/i18n', to: 'i18n' }<% } %>
            ]),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery"
            }),
            new HtmlWebpackPlugin({
                template: './src/main/webapp/index.ejs',
                chunksSortMode: 'dependency',
                inject: 'body',
                data: DATAS
            }),
            new StringReplacePlugin()
        ]
    };
};
<|endoftext|>


<commit_before>/**
 * @fileoverview This file provides the "themeswitcher" directive.
 * That directive is used to create the theme switcher in the page.
 *
 */
goog.provide('app.themeswitcherDirective');

goog.require('app');
goog.require('app.Themes');

/**
 * @param {string} appThemeswitcherTemplateUrl Url to themes template
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 */
app.themeswitcherDirective = function(appThemeswitcherTemplateUrl) {
  return {
    restrict: 'E',
    controller: 'AppThemeswitcherController',
    scope: {
      'currentTheme': '=appThemeswitcherCurrenttheme'
    },
    controllerAs: 'ctrl',
    bindToController: true,
    templateUrl: appThemeswitcherTemplateUrl
  };
};

app.module.directive('appThemeswitcher', app.themeswitcherDirective);

/**
 * @constructor
 * @param {app.Themes} appThemes Themes service.
 * @export
 * @ngInject
 */
app.ThemeswitcherController = function(appThemes) {

  appThemes.getThemesObject().then(goog.bind(
      /**
       * Keep only the themes dedicated to the theme switcher
       * @param {Array.<Object>} themes Array of theme objects.
       */
      function(themes) {
        this['themes'] = goog.array.filter(themes, function(object) {
          return 'true' == object['metadata']['display_in_switcher'];
        });
      }, this));

};

/**
 * @param {string} themeId The id of the theme.
 * @export
 */
app.ThemeswitcherController.prototype.switchTheme = function(themeId) {
  this['currentTheme'] = themeId;
};

app.module.controller('AppThemeswitcherController',
    app.ThemeswitcherController);
<commit_msg>Make theme switcher listen to "load" events from app.Themes<commit_after>/**
 * @fileoverview This file provides the "themeswitcher" directive.
 * That directive is used to create the theme switcher in the page.
 *
 */
goog.provide('app.themeswitcherDirective');

goog.require('app');
goog.require('app.Themes');
goog.require('app.ThemesEventType');
goog.require('goog.events');

/**
 * @param {string} appThemeswitcherTemplateUrl Url to themes template
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 */
app.themeswitcherDirective = function(appThemeswitcherTemplateUrl) {
  return {
    restrict: 'E',
    controller: 'AppThemeswitcherController',
    scope: {
      'currentTheme': '=appThemeswitcherCurrenttheme'
    },
    controllerAs: 'ctrl',
    bindToController: true,
    templateUrl: appThemeswitcherTemplateUrl
  };
};

app.module.directive('appThemeswitcher', app.themeswitcherDirective);

/**
 * @constructor
 * @param {app.Themes} appThemes Themes service.
 * @export
 * @ngInject
 */
app.ThemeswitcherController = function(appThemes) {

  /**
   * @type {app.Themes}
   * @private
   */
  this.appThemes_ = appThemes;

  goog.events.listen(appThemes, app.ThemesEventType.LOAD,
      /**
       * @param {goog.events.Event} evt Event.
       */
      function(evt) {
        this.setThemes_();
      }, undefined, this);

};

/**
 * @private
 */
app.ThemeswitcherController.prototype.setThemes_ = function() {
  this.appThemes_.getThemesObject().then(goog.bind(
      /**
       * Keep only the themes dedicated to the theme switcher
       * @param {Array.<Object>} themes Array of theme objects.
       */
      function(themes) {
        this['themes'] = goog.array.filter(themes, function(object) {
          return 'true' == object['metadata']['display_in_switcher'];
        });
      }, this));
};

/**
 * @param {string} themeId The id of the theme.
 * @export
 */
app.ThemeswitcherController.prototype.switchTheme = function(themeId) {
  this['currentTheme'] = themeId;
};

app.module.controller('AppThemeswitcherController',
    app.ThemeswitcherController);
<|endoftext|>