{
    "STRING_DIFF": {
        "before": "# Change Log\nAll notable changes to this project will be documented in this file.\nThis project adheres to [Semantic Versioning](http://semver.org/).\n\nThis file is similar to the format suggested by [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog).\n\n## Unreleased\n\n## 44.1.0 - 2019-07-08\n- [Feature] Test render props option for `onDatesChange` access in **DateRangePicker** ([#1186](https://github.com/optimizely/oui/pull/1186))\n\n## 44.0.1 - 2019-07-01\n- [Patch] Add Container, Row, Col to main.js for exporting and consumption on Axiom guidelines site ((#1183)[https://github.com/optimizely/oui/pull/1183])\n",
        "after": "# Change Log\nAll notable changes to this project will be documented in this file.\nThis project adheres to [Semantic Versioning](http://semver.org/).\n\nThis file is similar to the format suggested by [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog).\n\n## Unreleased\n\n## 44.1.1 - 2019-07-08\n- [Patch] Add `addOnBlur` and `addOnPaste` props to the `TokensInput` component ([#1185](https://github.com/optimizely/oui/pull/1185))\n\n## 44.1.0 - 2019-07-08\n- [Feature] Introduce render props option for `onDatesChange` access in **DateRangePicker** ([#1186](https://github.com/optimizely/oui/pull/1186))\n\n## 44.0.1 - 2019-07-01\n- [Patch] Add Container, Row, Col to main.js for exporting and consumption on Axiom guidelines site ((#1183)[https://github.com/optimizely/oui/pull/1183])\n"
    },
    "JSON_DIFF": {
        "before": {
            "audience_conditions": "[\"and\", [\"or\", [\"or\",{\"name\": \"user_id\", \"value\": 123, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 456, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 789, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 321, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 654, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 987, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 111, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 333, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 777, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 999, \"match_type\": \"exact\", \"type\": \"custom_attribute\"}]]]",
            "description": "creator: @tom | This Audience is for User IDs only. (User 1: 123) (User 2: 456) (User 3: 789) (User 4: 321) (User 5: 654) (User 6: 987) (User 7: 111) (User 8: 333) (User 9: 777) (User 10: 999)",
            "environments": {
                "staging": {
                    "id": 123,
                    "is_primary": true,
                    "rollout_rules": [
                        {
                            "status": "not_started",
                            "percentage_included": 0
                        }
                    ]
                },
                "production": {
                    "id": 456,
                    "is_primary": false,
                    "rollout_rules": [
                        {
                            "status": "not_started",
                            "json_string": "[\"or\", { \"aud\": 123 }, { \"aud\": 456 }, { \"aud\": 789 }]",
                            "percentage_included": 0
                        }
                    ]
                }
            },
            "name": "My experiment name",
            "javascript": "import React from 'react';\nimport PropTypes from 'prop-types';\n/**\n * @param {Object} props - Properties passed to component\n * @returns {ReactElement}\n */\n\nconst Button = ({\n  ariaLabel,\n  isSubmit,\n  isLink,\n  children,\n  isActive,\n  isDisabled,\n  isLoading,\n  loadingText,\n  onBlur,\n  onClick,\n  onMouseDown,\n  size,\n  style,\n  testSection,\n  width = 'default',\n  buttonRef,\n  title,\n}) => {\n\n  const buttonClassNames = classNames(\n    'oui-button', {\n      'is-active': isActive,\n      'oui-button--loading': isLoading,\n    });\n\n  const type = isSubmit ? 'submit' : 'button';\n\n  function handleOnClick(event) {\n    if (isDisabled || isLoading) {\n      return;\n    }\n    onClick(event);\n  }\n\n  if (isLink) {\n    return (\n      <div\n        data-oui-component={ true }\n        className={ buttonClassNames }\n        disabled={ isDisabled }\n        onBlur={ onBlur }\n        data-test-section={ testSection }\n        ref={ buttonRef }>\n        { children }\n      </div>\n    );\n  }\n\n  return (\n    <button\n      data-oui-component={ true }\n      className={ buttonClassNames }\n      disabled={ isDisabled || isLoading }\n      type={ type }\n      onBlur={ onBlur }\n      onClick={ handleOnClick }\n      onMouseDown={ onMouseDown }\n      data-test-section={ testSection }\n      aria-label={ ariaLabel }\n      aria-live=\"polite\"\n      title={ title }\n      ref={ buttonRef }>\n      { isLoading && <Spinner data-test-section=\"button-spinner\" size=\"tiny\"/> }\n      { isLoading ? loadingText || 'Processing' : children }\n    </button>\n  );\n};\n\nButton.propTypes = {\n  /** Describes buttons that have an icon but no text */\n  ariaLabel: PropTypes.string,\n  /** React ref to the underlying button component */\n  buttonRef: PropTypes.oneOfType([\n    PropTypes.func,\n    PropTypes.shape({ current: PropTypes.instanceOf(Element) }),\n  ]),\n  /** Text within the button */\n  children: PropTypes.node.isRequired,\n  /** Render button with active state */\n  isActive: PropTypes.bool,\n  /** Prevent users from interacting with the button */\n  isDisabled: PropTypes.bool,\n  /** Changes the button to a div for insertion within a Link component */\n  isLink: PropTypes.bool,\n  /** When true, adds a spinner to the button and disables the button */\n  isLoading: PropTypes.bool,\n  /** Make the button act as a submit button */\n  isSubmit: PropTypes.bool,\n  /** When the button adds a spinner, it displays this text */\n  loadingText: PropTypes.string,\n  /** Function that fires when the button loses focus */\n  onBlur: PropTypes.func,\n  /** Function that fires when the button is clicked on */\n  onClick: PropTypes.func,\n  /** Function that fires when the button is mouse downed */\n  onMouseDown: PropTypes.func,\n  /** Various height and width options */\n  size: PropTypes.oneOf([\n    'tiny',\n    'small',\n    'large',\n    'narrow',\n    'tight',\n  ]),\n  /** Various color options */\n  style: PropTypes.oneOf([\n    'highlight',\n    'danger',\n    'danger-outline',\n    'outline',\n    'outline-reverse',\n    'plain',\n    'toggle',\n    'underline',\n    'unstyled',\n  ]),\n  /** Hook for automated JavaScript tests */\n  testSection: PropTypes.string,\n  /** Title of the button shown as tooltip text when the button is hovered */\n  title: PropTypes.string,\n  /** Various height and width options */\n  width: PropTypes.oneOf([\n    'default',\n    'full',\n  ]),\n};\n\nButton.defaultProps = {\n  isLink: false,\n  isLoading: false,\n  isDisabled: false,\n  isSubmit: false,\n  loadingText: '',\n  onBlur: () => {},\n  onClick: () => {},\n  onMouseDown: () => {},\n  width: 'default',\n};\n\nButton.displayName = 'Button';\n\nexport default Button;"
        },
        "after": {
            "audience_conditions": "[\"and\", [\"or\", [\"or\",{\"name\": \"user_id\", \"value\": 123, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 456, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 789, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 321, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 654, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 987, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 111, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 333, \"match_type\": \"exact\", \"type\": \"custom_attribute\"},{\"name\": \"user_id\", \"value\": 777, \"match_type\": \"exact\", \"type\": \"custom_attribute\"}]]]",
            "description": "creator: @tom | This Audience is for User IDs only. (User 1: 123) (User 2: 456) (User 3: 789) (User 4: 321) (User 5: 654) (User 6: 987) (User 7: 111) (User 8: 333) (User 9: 777) (User 10: 999) (User 11: 222)",
            "environments": {
                "staging": {
                    "id": 123,
                    "is_primary": true,
                    "rollout_rules": [
                        {
                            "status": "running",
                            "percentage_included": 0
                        }
                    ]
                },
                "production": {
                    "id": 456,
                    "is_primary": false,
                    "rollout_rules": [
                        {
                            "status": "not_started",
                            "json_string": "[\"or\", { \"aud\": 123 }, { \"aud\": 456 }]",
                            "percentage_included": 0
                        }
                    ]
                }
            },
            "name": "My updated experiment name",
            "javascript": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Spinner from '../Spinner';\n\n/**\n * @param {Object} props - Properties passed to component\n * @returns {ReactElement}\n */\n\nconst Button = ({\n  ariaLabel,\n  isSubmit,\n  isLink,\n  children,\n  isActive,\n  isDisabled,\n  isLoading,\n  loadingText,\n  onBlur,\n  onClick,\n  onMouseDown,\n  size,\n  style,\n  testSection,\n  width = 'default',\n  buttonRef,\n  title,\n}) => {\n\n  const buttonClassNames = classNames(\n    'oui-button', {\n      'is-active': isActive,\n      'oui-button--loading': isLoading,\n    });\n\n  const type = isSubmit ? 'submit' : 'button';\n\n  function handleOnClick(event) {\n    if (isDisabled || isLoading) {\n      return;\n    }\n    onClick(event);\n  }\n\n  if (isLink) {\n    return (\n      <div\n        data-oui-component={ true }\n        className={ buttonClassNames }\n        disabled={ isDisabled }\n        onBlur={ onBlur }\n        data-test-section={ testSection }\n        ref={ buttonRef }>\n        { children }\n      </div>\n    );\n  }\n\n  return (\n    <button\n      data-oui-component={ true }\n      className={ buttonClassNames }\n      disabled={ isDisabled || isLoading }\n      type={ type }\n      onBlur={ onBlur }\n      onClick={ handleOnClick }\n      onMouseDown={ onMouseDown }\n      data-test-section={ testSection }\n      aria-label={ ariaLabel }\n      aria-live=\"polite\"\n      title={ title }\n      ref={ buttonRef }>\n      { isLoading && <Spinner data-test-section=\"button-spinner\" size=\"tiny\"/> }\n      { isLoading ? loadingText || 'Processing' : children }\n    </button>\n  );\n};\n\nButton.propTypes = {\n  /** Describes buttons that have an icon but no text */\n  ariaLabel: PropTypes.string,\n  /** React ref to the underlying button component */\n  buttonRef: PropTypes.oneOfType([\n    PropTypes.func,\n    PropTypes.shape({ current: PropTypes.instanceOf(Element) }),\n  ]),\n  /** Text within the button */\n  children: PropTypes.node.isRequired,\n  /** Render button with active state */\n  isActive: PropTypes.bool,\n  /** Prevent users from interacting with the button */\n  isDisabled: PropTypes.bool,\n  /** Changes the button to a div for insertion within a Link component */\n  isLink: PropTypes.bool,\n  /** When true, adds a spinner to the button and disables the button */\n  isLoading: PropTypes.bool,\n  /** Make the button act as a submit button */\n  isSubmit: PropTypes.bool,\n  /** When the button adds a spinner, it displays this text */\n  loadingText: PropTypes.string,\n  /** Function that fires when the button loses focus */\n  onBlur: PropTypes.func,\n  /** Function that fires when the button is clicked on */\n  onClick: PropTypes.func,\n  /** Function that fires when the button is mouse downed */\n  onMouseDown: PropTypes.func,\n  /** Various height and width options */\n  size: PropTypes.oneOf([\n    'tiny',\n    'small',\n    'large',\n    'narrow',\n    'tight',\n  ]),\n  /** Various color options */\n  style: PropTypes.oneOf([\n    'highlight',\n    'danger',\n    'danger-outline',\n    'outline',\n    'outline-reverse',\n    'plain',\n    'toggle',\n    'underline',\n    'unstyled',\n  ]),\n  /** Hook for automated JavaScript tests */\n  testSection: PropTypes.string,\n  /** Title of the button shown as tooltip text when the button is hovered */\n  title: PropTypes.string,\n  /** Various height and width options */\n  width: PropTypes.oneOf([\n    'default',\n    'full',\n  ]),\n};\n\nButton.defaultProps = {\n  isLink: false,\n  isLoading: false,\n  isDisabled: false,\n  isSubmit: false,\n  loadingText: '',\n  onBlur: () => {},\n  onClick: () => {},\n  onMouseDown: () => {},\n  width: 'default',\n};\n\nButton.displayName = 'Button';\n\nexport default Button;"
        }
    }
}
