import React, { useCallback, useRef, useState } from 'react';
import Form, {
  ButtonItem,
  GroupItem,
  SimpleItem,
  Label,
  CompareRule,
  EmailRule,
  PatternRule,
  RangeRule,
  RequiredRule,
  StringLengthRule,
  AsyncRule,
  CustomRule,
  type FormTypes,
  FormRef,
} from 'devextreme-react/form';
import { ButtonType } from 'devextreme-react/common';
import notify from 'devextreme/ui/notify';
import Validator from 'devextreme/ui/validator';
import 'devextreme-react/autocomplete';
import 'devextreme-react/date-range-box';
import service from './data.ts';
const customer = service.getCustomer();
const checkBoxOptions = {
  text: 'I agree to the Terms and Conditions',
  value: false,
  width: 270,
};
const cityEditorOptions = {
  dataSource: service.getCities(),
  valueChangeEvent: 'keyup',
  minSearchLength: 2,
};
const countryEditorOptions = {
  dataSource: service.getCountries(),
};
const emailEditorOptions = {
  valueChangeEvent: 'keyup',
};
const nameEditorOptions = {
  valueChangeEvent: 'keyup',
};
const addressEditorOptions = {
  valueChangeEvent: 'keyup',
};
const phoneEditorOptions = {
  mask: '+1 (X00) 000-0000',
  valueChangeEvent: 'keyup',
  maskRules: {
    X: /[02-9]/,
  },
  maskInvalidMessage: 'The phone must have a correct USA phone format',
};
const noDigitsPattern = /^[^0-9]+$/;
const phonePattern = /^[02-9]\d{9}$/;
const colCountByScreen = {
  xs: 2,
  sm: 2,
  md: 2,
  lg: 2,
};
const maxDate = new Date().setFullYear(new Date().getFullYear() - 21);
const dateBoxOptions = {
  placeholder: 'Birth Date',
  acceptCustomValue: false,
  openOnFieldClick: true,
};
const dateRangeBoxOptions = {
  startDatePlaceholder: 'Start Date',
  endDatePlaceholder: 'End Date',
  acceptCustomValue: false,
};
function sendRequest(value: string) {
  const invalidEmail = 'test@dx-email.com';
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(value !== invalidEmail);
    }, 1000);
  });
}
const passwordComparison = () => customer.Password;
const checkComparison = () => true;
const asyncValidation = (params: { value: any; }) => sendRequest(params.value);
const validateVacationDatesRange = ({ value }) => {
  const [startDate, endDate] = value;
  if (startDate === null || endDate === null) {
    return true;
  }
  const millisecondsPerDay = 24 * 60 * 60 * 1000;
  const daysDifference = Math.abs((endDate - startDate) / millisecondsPerDay);
  return daysDifference < 25;
};
const validateVacationDatesPresence = ({ value }) => {
  const [startDate, endDate] = value;
  if (startDate === null && endDate === null) {
    return true;
  }
  return startDate !== null && endDate !== null;
};
const registerButtonOptions = {
  text: 'Register',
  type: 'default' as ButtonType,
  useSubmitBehavior: true,
  width: '120px',
};
function App() {
  const formRef = useRef<FormRef>(null);
  const [resetButtonOptions, setResetButtonOptions] = useState({
    disabled: true,
    icon: 'refresh',
    text: 'Reset',
    width: '120px',
    onClick: () => {
      formRef.current.instance().reset();
    },
  });
  const changePasswordMode = useCallback((name) => {
    const editor = formRef.current.instance().getEditor(name);
    editor.option('mode', editor.option('mode') === 'text' ? 'password' : 'text');
  }, []);
  const getPasswordOptions = useCallback(() => ({
    mode: 'password',
    valueChangeEvent: 'keyup',
    onValueChanged: () => {
      const editor = formRef.current.instance().getEditor('ConfirmPassword');
      if (editor.option('value')) {
        const instance = Validator.getInstance(editor.element()) as Validator;
        instance.validate();
      }
    },
    buttons: [
      {
        name: 'password',
        location: 'after',
        options: {
          stylingMode: 'text',
          icon: 'eyeopen',
          onClick: () => changePasswordMode('Password'),
        },
      },
    ],
  }), [changePasswordMode]);
  const getConfirmOptions = useCallback(() => ({
    mode: 'password',
    valueChangeEvent: 'keyup',
    buttons: [
      {
        name: 'password',
        location: 'after',
        options: {
          stylingMode: 'text',
          icon: 'eyeopen',
          onClick: () => changePasswordMode('ConfirmPassword'),
        },
      },
    ],
  }), [changePasswordMode]);
  const handleSubmit = useCallback((e: { preventDefault: () => void; }) => {
    notify({
      message: 'You have submitted the form',
      position: {
        my: 'center top',
        at: 'center top',
      },
    }, 'success', 3000);
    e.preventDefault();
  }, []);
  const onOptionChanged = useCallback((e: FormTypes.OptionChangedEvent) => {
    if (e.name === 'isDirty') {
      setResetButtonOptions({ ...resetButtonOptions, disabled: !e.value });
    }
  }, [resetButtonOptions, setResetButtonOptions]);
  return (
    <React.Fragment>
      <form action="your-action" onSubmit={handleSubmit}>
        <Form
          ref={formRef}
          formData={customer}
          readOnly={false}
          onOptionChanged={onOptionChanged}
          showColonAfterLabel={true}
          showValidationSummary={true}
          validationGroup="customerData"
        >
          <GroupItem caption="Credentials">
            <SimpleItem dataField="Email" editorType="dxTextBox" editorOptions={emailEditorOptions}>
              <RequiredRule message="Email is required" />
              <EmailRule message="Email is invalid" />
              <AsyncRule
                message="Email is already registered"
                validationCallback={asyncValidation} />
            </SimpleItem>
            <SimpleItem dataField="Password" editorType="dxTextBox" editorOptions={getPasswordOptions()}>
              <RequiredRule message="Password is required" />
            </SimpleItem>
            <SimpleItem name="ConfirmPassword" dataField="ConfirmPassword" editorType="dxTextBox" editorOptions={getConfirmOptions()}>
              <Label text="Confirm Password" />
              <RequiredRule message="Confirm Password is required" />
              <CompareRule
                message="Password and Confirm Password do not match"
                comparisonTarget={passwordComparison}
              />
            </SimpleItem>
          </GroupItem>
          <GroupItem caption="Personal Data">
            <SimpleItem dataField="Name" editorOptions={nameEditorOptions}>
              <RequiredRule message="Name is required" />
              <PatternRule message="Do not use digits in the Name"
                pattern={noDigitsPattern} />
            </SimpleItem>
            <SimpleItem dataField="Date"
              editorType="dxDateBox"
              editorOptions={dateBoxOptions}>
              <Label text="Date of birth" />
              <RequiredRule message="Date of birth is required" />
              <RangeRule max={maxDate} message="You must be at least 21 years old" />
            </SimpleItem>
            <SimpleItem dataField="VacationDates"
              editorType="dxDateRangeBox"
              editorOptions={dateRangeBoxOptions}
            >
              <Label text="Vacation Dates" />
              <CustomRule message="The vacation period must not exceed 25 days" validationCallback={validateVacationDatesRange} />
              <CustomRule message="Both start and end dates must be selected" validationCallback={validateVacationDatesPresence} />
            </SimpleItem>
          </GroupItem>
          <GroupItem caption="Billing address">
            <SimpleItem dataField="Country" editorType="dxSelectBox" editorOptions={countryEditorOptions}>
              <RequiredRule message="Country is required" />
            </SimpleItem>
            <SimpleItem dataField="City" editorType="dxAutocomplete" editorOptions={cityEditorOptions}>
              <PatternRule pattern={noDigitsPattern} message="Do not use digits in the City name" />
              <StringLengthRule min={2} message="City must have at least 2 symbols" />
              <RequiredRule message="City is required" />
            </SimpleItem>
            <SimpleItem dataField="Address" editorOptions={addressEditorOptions}>
              <RequiredRule message="Address is required" />
            </SimpleItem>
            <SimpleItem dataField="Phone"
              helpText="Enter the phone number in USA phone format"
              editorOptions={phoneEditorOptions}
            >
              <PatternRule
                message="The phone must have a correct USA phone format"
                pattern={phonePattern}
              />
            </SimpleItem>
          </GroupItem>
          <GroupItem cssClass="last-group" colCountByScreen={colCountByScreen}>
            <SimpleItem dataField="Accepted"
              editorType="dxCheckBox"
              editorOptions={checkBoxOptions}>
              <Label visible={false} />
              <CompareRule message="You must agree to the Terms and Conditions"
                comparisonTarget={checkComparison}
              />
            </SimpleItem>
            <GroupItem cssClass="buttons-group" colCountByScreen={colCountByScreen}>
              <ButtonItem buttonOptions={resetButtonOptions} name="Reset" />
              <ButtonItem buttonOptions={registerButtonOptions} />
            </GroupItem>
          </GroupItem>
        </Form>
      </form>
    </React.Fragment>
  );
}
export default App;
    
    import React, { useCallback, useRef, useState } from 'react';
import Form, {
  ButtonItem,
  GroupItem,
  SimpleItem,
  Label,
  CompareRule,
  EmailRule,
  PatternRule,
  RangeRule,
  RequiredRule,
  StringLengthRule,
  AsyncRule,
  CustomRule,
} from 'devextreme-react/form';
import notify from 'devextreme/ui/notify';
import Validator from 'devextreme/ui/validator';
import 'devextreme-react/autocomplete';
import 'devextreme-react/date-range-box';
import service from './data.js';
const customer = service.getCustomer();
const checkBoxOptions = {
  text: 'I agree to the Terms and Conditions',
  value: false,
  width: 270,
};
const cityEditorOptions = {
  dataSource: service.getCities(),
  valueChangeEvent: 'keyup',
  minSearchLength: 2,
};
const countryEditorOptions = {
  dataSource: service.getCountries(),
};
const emailEditorOptions = {
  valueChangeEvent: 'keyup',
};
const nameEditorOptions = {
  valueChangeEvent: 'keyup',
};
const addressEditorOptions = {
  valueChangeEvent: 'keyup',
};
const phoneEditorOptions = {
  mask: '+1 (X00) 000-0000',
  valueChangeEvent: 'keyup',
  maskRules: {
    X: /[02-9]/,
  },
  maskInvalidMessage: 'The phone must have a correct USA phone format',
};
const noDigitsPattern = /^[^0-9]+$/;
const phonePattern = /^[02-9]\d{9}$/;
const colCountByScreen = {
  xs: 2,
  sm: 2,
  md: 2,
  lg: 2,
};
const maxDate = new Date().setFullYear(new Date().getFullYear() - 21);
const dateBoxOptions = {
  placeholder: 'Birth Date',
  acceptCustomValue: false,
  openOnFieldClick: true,
};
const dateRangeBoxOptions = {
  startDatePlaceholder: 'Start Date',
  endDatePlaceholder: 'End Date',
  acceptCustomValue: false,
};
function sendRequest(value) {
  const invalidEmail = 'test@dx-email.com';
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(value !== invalidEmail);
    }, 1000);
  });
}
const passwordComparison = () => customer.Password;
const checkComparison = () => true;
const asyncValidation = (params) => sendRequest(params.value);
const validateVacationDatesRange = ({ value }) => {
  const [startDate, endDate] = value;
  if (startDate === null || endDate === null) {
    return true;
  }
  const millisecondsPerDay = 24 * 60 * 60 * 1000;
  const daysDifference = Math.abs((endDate - startDate) / millisecondsPerDay);
  return daysDifference < 25;
};
const validateVacationDatesPresence = ({ value }) => {
  const [startDate, endDate] = value;
  if (startDate === null && endDate === null) {
    return true;
  }
  return startDate !== null && endDate !== null;
};
const registerButtonOptions = {
  text: 'Register',
  type: 'default',
  useSubmitBehavior: true,
  width: '120px',
};
function App() {
  const formRef = useRef(null);
  const [resetButtonOptions, setResetButtonOptions] = useState({
    disabled: true,
    icon: 'refresh',
    text: 'Reset',
    width: '120px',
    onClick: () => {
      formRef.current.instance().reset();
    },
  });
  const changePasswordMode = useCallback((name) => {
    const editor = formRef.current.instance().getEditor(name);
    editor.option('mode', editor.option('mode') === 'text' ? 'password' : 'text');
  }, []);
  const getPasswordOptions = useCallback(
    () => ({
      mode: 'password',
      valueChangeEvent: 'keyup',
      onValueChanged: () => {
        const editor = formRef.current.instance().getEditor('ConfirmPassword');
        if (editor.option('value')) {
          const instance = Validator.getInstance(editor.element());
          instance.validate();
        }
      },
      buttons: [
        {
          name: 'password',
          location: 'after',
          options: {
            stylingMode: 'text',
            icon: 'eyeopen',
            onClick: () => changePasswordMode('Password'),
          },
        },
      ],
    }),
    [changePasswordMode],
  );
  const getConfirmOptions = useCallback(
    () => ({
      mode: 'password',
      valueChangeEvent: 'keyup',
      buttons: [
        {
          name: 'password',
          location: 'after',
          options: {
            stylingMode: 'text',
            icon: 'eyeopen',
            onClick: () => changePasswordMode('ConfirmPassword'),
          },
        },
      ],
    }),
    [changePasswordMode],
  );
  const handleSubmit = useCallback((e) => {
    notify(
      {
        message: 'You have submitted the form',
        position: {
          my: 'center top',
          at: 'center top',
        },
      },
      'success',
      3000,
    );
    e.preventDefault();
  }, []);
  const onOptionChanged = useCallback(
    (e) => {
      if (e.name === 'isDirty') {
        setResetButtonOptions({ ...resetButtonOptions, disabled: !e.value });
      }
    },
    [resetButtonOptions, setResetButtonOptions],
  );
  return (
    <React.Fragment>
      <form
        action="your-action"
        onSubmit={handleSubmit}
      >
        <Form
          ref={formRef}
          formData={customer}
          readOnly={false}
          onOptionChanged={onOptionChanged}
          showColonAfterLabel={true}
          showValidationSummary={true}
          validationGroup="customerData"
        >
          <GroupItem caption="Credentials">
            <SimpleItem
              dataField="Email"
              editorType="dxTextBox"
              editorOptions={emailEditorOptions}
            >
              <RequiredRule message="Email is required" />
              <EmailRule message="Email is invalid" />
              <AsyncRule
                message="Email is already registered"
                validationCallback={asyncValidation}
              />
            </SimpleItem>
            <SimpleItem
              dataField="Password"
              editorType="dxTextBox"
              editorOptions={getPasswordOptions()}
            >
              <RequiredRule message="Password is required" />
            </SimpleItem>
            <SimpleItem
              name="ConfirmPassword"
              dataField="ConfirmPassword"
              editorType="dxTextBox"
              editorOptions={getConfirmOptions()}
            >
              <Label text="Confirm Password" />
              <RequiredRule message="Confirm Password is required" />
              <CompareRule
                message="Password and Confirm Password do not match"
                comparisonTarget={passwordComparison}
              />
            </SimpleItem>
          </GroupItem>
          <GroupItem caption="Personal Data">
            <SimpleItem
              dataField="Name"
              editorOptions={nameEditorOptions}
            >
              <RequiredRule message="Name is required" />
              <PatternRule
                message="Do not use digits in the Name"
                pattern={noDigitsPattern}
              />
            </SimpleItem>
            <SimpleItem
              dataField="Date"
              editorType="dxDateBox"
              editorOptions={dateBoxOptions}
            >
              <Label text="Date of birth" />
              <RequiredRule message="Date of birth is required" />
              <RangeRule
                max={maxDate}
                message="You must be at least 21 years old"
              />
            </SimpleItem>
            <SimpleItem
              dataField="VacationDates"
              editorType="dxDateRangeBox"
              editorOptions={dateRangeBoxOptions}
            >
              <Label text="Vacation Dates" />
              <CustomRule
                message="The vacation period must not exceed 25 days"
                validationCallback={validateVacationDatesRange}
              />
              <CustomRule
                message="Both start and end dates must be selected"
                validationCallback={validateVacationDatesPresence}
              />
            </SimpleItem>
          </GroupItem>
          <GroupItem caption="Billing address">
            <SimpleItem
              dataField="Country"
              editorType="dxSelectBox"
              editorOptions={countryEditorOptions}
            >
              <RequiredRule message="Country is required" />
            </SimpleItem>
            <SimpleItem
              dataField="City"
              editorType="dxAutocomplete"
              editorOptions={cityEditorOptions}
            >
              <PatternRule
                pattern={noDigitsPattern}
                message="Do not use digits in the City name"
              />
              <StringLengthRule
                min={2}
                message="City must have at least 2 symbols"
              />
              <RequiredRule message="City is required" />
            </SimpleItem>
            <SimpleItem
              dataField="Address"
              editorOptions={addressEditorOptions}
            >
              <RequiredRule message="Address is required" />
            </SimpleItem>
            <SimpleItem
              dataField="Phone"
              helpText="Enter the phone number in USA phone format"
              editorOptions={phoneEditorOptions}
            >
              <PatternRule
                message="The phone must have a correct USA phone format"
                pattern={phonePattern}
              />
            </SimpleItem>
          </GroupItem>
          <GroupItem
            cssClass="last-group"
            colCountByScreen={colCountByScreen}
          >
            <SimpleItem
              dataField="Accepted"
              editorType="dxCheckBox"
              editorOptions={checkBoxOptions}
            >
              <Label visible={false} />
              <CompareRule
                message="You must agree to the Terms and Conditions"
                comparisonTarget={checkComparison}
              />
            </SimpleItem>
            <GroupItem
              cssClass="buttons-group"
              colCountByScreen={colCountByScreen}
            >
              <ButtonItem
                buttonOptions={resetButtonOptions}
                name="Reset"
              />
              <ButtonItem buttonOptions={registerButtonOptions} />
            </GroupItem>
          </GroupItem>
        </Form>
      </form>
    </React.Fragment>
  );
}
export default App;
    
    import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.tsx';
ReactDOM.render(
  <App />,
  document.getElementById('app'),
);
    
    const customer = {
  Email: '',
  Password: '',
  Name: 'Peter',
  Date: null,
  VacationDates: [null, null],
  Country: '',
  City: null,
  Address: '',
  Phone: '',
  Accepted: false,
};
const countries: string[] = ['Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Australia', 'Austria', 'Azerbaijan', 'The Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belgium', 'Belize', 'Benin', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Brazil', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burma', 'Burundi', 'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Central African Republic', 'Chad', 'Chile', 'Colombia', 'Comoros', 'Democratic Republic of the Congo', 'Republic of the Congo', 'Costa Rica', 'Ivory Coast', 'Croatia', 'Cuba', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Fiji', 'Finland', 'France', 'Gabon', 'The Gambia', 'Georgia', 'Germany', 'Ghana', 'Greece', 'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iraq', 'Republic of Ireland', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kiribati', 'North Korea', 'South Korea', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Republic of Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Mauritania', 'Mauritius', 'Mexico', 'Federated States of Micronesia', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique', 'Namibia', 'Nauru', 'Nepal', 'Kingdom of the Netherlands', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Norway', 'Oman', 'Pakistan', 'Palau', 'State of Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Qatar', 'Romania', 'Rwanda', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa', 'San Marino', 'São Tomé and Príncipe', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Sudan', 'Spain', 'Sri Lanka', 'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Tajikistan', 'Tanzania', 'Thailand', 'Togo', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Tuvalu', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam', 'Yemen', 'Zambia', 'Zimbabwe'];
const cities: string[] = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Philadelphia', 'Phoenix', 'San Antonio', 'San Diego', 'Dallas', 'San Jose', 'Austin', 'Indianapolis', 'Jacksonville', 'San Francisco', 'Columbus', 'Charlotte', 'Fort Worth', 'Detroit', 'El Paso', 'Memphis', 'Seattle', 'Denver', 'Washington', 'Boston', 'Nashville', 'Baltimore', 'Oklahoma City', 'Louisville', 'Portland', 'Las Vegas', 'Milwaukee', 'Albuquerque', 'Tucson', 'Fresno', 'Sacramento', 'Long Beach', 'Kansas City', 'Mesa', 'Virginia Beach', 'Atlanta', 'Colorado Springs', 'Omaha', 'Raleigh', 'Miami', 'Oakland', 'Minneapolis', 'Tulsa', 'Cleveland', 'Wichita', 'Arlington', 'New Orleans', 'Bakersfield', 'Tampa', 'Honolulu', 'Aurora', 'Anaheim', 'Santa Ana', 'St. Louis', 'Riverside', 'Corpus Christi', 'Lexington', 'Pittsburgh', 'Anchorage', 'Stockton', 'Cincinnati', 'Saint Paul', 'Toledo', 'Greensboro', 'Newark', 'Plano', 'Henderson', 'Lincoln', 'Buffalo', 'Jersey City', 'Chula Vista', 'Fort Wayne', 'Orlando', 'Chandler', 'Laredo', 'Norfolk', 'Durham', 'Madison', 'Lubbock', 'Irvine', 'Winston–Salem', 'Glendale', 'Garland', 'Hialeah', 'Reno', 'Chesapeake', 'Gilbert', 'Baton Rouge', 'Irving', 'Scottsdale', 'North Las Vegas', 'Fremont', 'Boise', 'Richmond'];
export default {
  getCustomer() {
    return customer;
  },
  getCountries() {
    return countries;
  },
  getCities() {
    return cities;
  },
};
    
    window.exports = window.exports || {};
window.config = {
  transpiler: 'ts',
  typescriptOptions: {
    module: 'system',
    emitDecoratorMetadata: true,
    experimentalDecorators: true,
    jsx: 'react',
  },
  meta: {
    'react': {
      'esModule': true,
    },
    'typescript': {
      'exports': 'ts',
    },
    'devextreme/time_zone_utils.js': {
      'esModule': true,
    },
    'devextreme/localization.js': {
      'esModule': true,
    },
    'devextreme/viz/palette.js': {
      'esModule': true,
    },
    'openai': {
      'esModule': true,
    },
  },
  paths: {
    'npm:': 'https://cdn.jsdelivr.net/npm/',
    'bundles:': '../../../../bundles/',
    'externals:': '../../../../bundles/externals/',
  },
  defaultExtension: 'js',
  map: {
    'ts': 'npm:plugin-typescript@8.0.0/lib/plugin.js',
    'typescript': 'npm:typescript@4.2.4/lib/typescript.js',
    'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js',
    'react': 'npm:react@17.0.2/umd/react.development.js',
    'react-dom': 'npm:react-dom@17.0.2/umd/react-dom.development.js',
    'prop-types': 'npm:prop-types/prop-types.js',
    'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js',
    'luxon': 'npm:luxon@3.4.4/build/global/luxon.min.js',
    'es6-object-assign': 'npm:es6-object-assign',
    'devextreme': 'npm:devextreme@link:../../packages/devextreme/artifacts/npm/devextreme/cjs',
    'devextreme-react': 'npm:devextreme-react@link:../../packages/devextreme-react/npm/cjs',
    'devextreme-quill': 'npm:devextreme-quill@1.7.6/dist/dx-quill.min.js',
    'devexpress-diagram': 'npm:devexpress-diagram@2.2.24/dist/dx-diagram.js',
    'devexpress-gantt': 'npm:devexpress-gantt@4.1.64/dist/dx-gantt.js',
    'inferno': 'npm:inferno@8.2.3/dist/inferno.min.js',
    'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js',
    'inferno-create-element': 'npm:inferno-create-element@8.2.3/dist/inferno-create-element.min.js',
    'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js',
    'inferno-hydrate': 'npm:inferno-hydrate/dist/inferno-hydrate.min.js',
    'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js',
    'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js',
    'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js',
    '@preact/signals-core': 'npm:@preact/signals-core@1.8.0/dist/signals-core.min.js',
    'devextreme-cldr-data': 'npm:devextreme-cldr-data@1.0.3',
    // SystemJS plugins
    'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js',
    'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js',
    // Prettier
    'prettier/standalone': 'npm:prettier@2.8.8/standalone.js',
    'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js',
  },
  packages: {
    'devextreme': {
      defaultExtension: 'js',
    },
    'devextreme-react': {
      main: 'index.js',
    },
    'devextreme-react/common': {
      main: 'index.js',
    },
    'devextreme/events/utils': {
      main: 'index',
    },
    'devextreme/common/core/events/utils': {
      main: 'index',
    },
    'devextreme/localization/messages': {
      format: 'json',
      defaultExtension: 'json',
    },
    'devextreme/events': {
      main: 'index',
    },
    'es6-object-assign': {
      main: './index.js',
      defaultExtension: 'js',
    },
  },
  packageConfigPaths: [
    'npm:@devextreme/*/package.json',
  ],
  babelOptions: {
    sourceMaps: false,
    stage0: true,
    react: true,
  },
};
System.config(window.config);
// eslint-disable-next-line
const useTgzInCSB = ['openai'];
    
    import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('app'));
    
    const customer = {
  Email: '',
  Password: '',
  Name: 'Peter',
  Date: null,
  VacationDates: [null, null],
  Country: '',
  City: null,
  Address: '',
  Phone: '',
  Accepted: false,
};
const countries = [
  'Afghanistan',
  'Albania',
  'Algeria',
  'Andorra',
  'Angola',
  'Antigua and Barbuda',
  'Argentina',
  'Armenia',
  'Australia',
  'Austria',
  'Azerbaijan',
  'The Bahamas',
  'Bahrain',
  'Bangladesh',
  'Barbados',
  'Belgium',
  'Belize',
  'Benin',
  'Bhutan',
  'Bolivia',
  'Bosnia and Herzegovina',
  'Botswana',
  'Brazil',
  'Brunei',
  'Bulgaria',
  'Burkina Faso',
  'Burma',
  'Burundi',
  'Cambodia',
  'Cameroon',
  'Canada',
  'Cape Verde',
  'Central African Republic',
  'Chad',
  'Chile',
  'Colombia',
  'Comoros',
  'Democratic Republic of the Congo',
  'Republic of the Congo',
  'Costa Rica',
  'Ivory Coast',
  'Croatia',
  'Cuba',
  'Cyprus',
  'Czech Republic',
  'Denmark',
  'Djibouti',
  'Dominica',
  'Dominican Republic',
  'East Timor',
  'Ecuador',
  'Egypt',
  'El Salvador',
  'Equatorial Guinea',
  'Eritrea',
  'Estonia',
  'Ethiopia',
  'Fiji',
  'Finland',
  'France',
  'Gabon',
  'The Gambia',
  'Georgia',
  'Germany',
  'Ghana',
  'Greece',
  'Grenada',
  'Guatemala',
  'Guinea',
  'Guinea-Bissau',
  'Guyana',
  'Haiti',
  'Honduras',
  'Hungary',
  'Iceland',
  'India',
  'Indonesia',
  'Iraq',
  'Republic of Ireland',
  'Israel',
  'Italy',
  'Jamaica',
  'Japan',
  'Jordan',
  'Kazakhstan',
  'Kenya',
  'Kiribati',
  'North Korea',
  'South Korea',
  'Kuwait',
  'Kyrgyzstan',
  'Laos',
  'Latvia',
  'Lebanon',
  'Lesotho',
  'Liberia',
  'Libya',
  'Liechtenstein',
  'Lithuania',
  'Luxembourg',
  'Republic of Macedonia',
  'Madagascar',
  'Malawi',
  'Malaysia',
  'Maldives',
  'Mali',
  'Malta',
  'Marshall Islands',
  'Mauritania',
  'Mauritius',
  'Mexico',
  'Federated States of Micronesia',
  'Moldova',
  'Monaco',
  'Mongolia',
  'Montenegro',
  'Morocco',
  'Mozambique',
  'Namibia',
  'Nauru',
  'Nepal',
  'Kingdom of the Netherlands',
  'New Zealand',
  'Nicaragua',
  'Niger',
  'Nigeria',
  'Norway',
  'Oman',
  'Pakistan',
  'Palau',
  'State of Palestine',
  'Panama',
  'Papua New Guinea',
  'Paraguay',
  'Peru',
  'Philippines',
  'Poland',
  'Portugal',
  'Qatar',
  'Romania',
  'Rwanda',
  'Saint Kitts and Nevis',
  'Saint Lucia',
  'Saint Vincent and the Grenadines',
  'Samoa',
  'San Marino',
  'São Tomé and Príncipe',
  'Saudi Arabia',
  'Senegal',
  'Serbia',
  'Seychelles',
  'Sierra Leone',
  'Singapore',
  'Slovakia',
  'Slovenia',
  'Solomon Islands',
  'Somalia',
  'South Africa',
  'South Sudan',
  'Spain',
  'Sri Lanka',
  'Sudan',
  'Suriname',
  'Swaziland',
  'Sweden',
  'Switzerland',
  'Syria',
  'Tajikistan',
  'Tanzania',
  'Thailand',
  'Togo',
  'Tonga',
  'Trinidad and Tobago',
  'Tunisia',
  'Turkey',
  'Turkmenistan',
  'Tuvalu',
  'Uganda',
  'Ukraine',
  'United Arab Emirates',
  'United Kingdom',
  'United States',
  'Uruguay',
  'Uzbekistan',
  'Vanuatu',
  'Vatican City',
  'Venezuela',
  'Vietnam',
  'Yemen',
  'Zambia',
  'Zimbabwe',
];
const cities = [
  'New York',
  'Los Angeles',
  'Chicago',
  'Houston',
  'Philadelphia',
  'Phoenix',
  'San Antonio',
  'San Diego',
  'Dallas',
  'San Jose',
  'Austin',
  'Indianapolis',
  'Jacksonville',
  'San Francisco',
  'Columbus',
  'Charlotte',
  'Fort Worth',
  'Detroit',
  'El Paso',
  'Memphis',
  'Seattle',
  'Denver',
  'Washington',
  'Boston',
  'Nashville',
  'Baltimore',
  'Oklahoma City',
  'Louisville',
  'Portland',
  'Las Vegas',
  'Milwaukee',
  'Albuquerque',
  'Tucson',
  'Fresno',
  'Sacramento',
  'Long Beach',
  'Kansas City',
  'Mesa',
  'Virginia Beach',
  'Atlanta',
  'Colorado Springs',
  'Omaha',
  'Raleigh',
  'Miami',
  'Oakland',
  'Minneapolis',
  'Tulsa',
  'Cleveland',
  'Wichita',
  'Arlington',
  'New Orleans',
  'Bakersfield',
  'Tampa',
  'Honolulu',
  'Aurora',
  'Anaheim',
  'Santa Ana',
  'St. Louis',
  'Riverside',
  'Corpus Christi',
  'Lexington',
  'Pittsburgh',
  'Anchorage',
  'Stockton',
  'Cincinnati',
  'Saint Paul',
  'Toledo',
  'Greensboro',
  'Newark',
  'Plano',
  'Henderson',
  'Lincoln',
  'Buffalo',
  'Jersey City',
  'Chula Vista',
  'Fort Wayne',
  'Orlando',
  'Chandler',
  'Laredo',
  'Norfolk',
  'Durham',
  'Madison',
  'Lubbock',
  'Irvine',
  'Winston–Salem',
  'Glendale',
  'Garland',
  'Hialeah',
  'Reno',
  'Chesapeake',
  'Gilbert',
  'Baton Rouge',
  'Irving',
  'Scottsdale',
  'North Las Vegas',
  'Fremont',
  'Boise',
  'Richmond',
];
export default {
  getCustomer() {
    return customer;
  },
  getCountries() {
    return countries;
  },
  getCities() {
    return cities;
  },
};
    
    <!DOCTYPE html>
<html lang="en">
  <head>
    <title>DevExtreme Demo</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
    <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/25.1.6/css/dx.light.css" />
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" />
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <script src="https://cdn.jsdelivr.net/npm/core-js@2.6.12/client/shim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/systemjs@0.21.3/dist/system.js"></script>
    <script type="text/javascript" src="config.js"></script>
    <script type="text/javascript">
      System.import("./index.tsx");
    </script>
  </head>
  <body class="dx-viewport">
    <div class="demo-container">
      <div id="app"></div>
    </div>
  </body>
</html>
    
    form {
  margin: 10px 10px 15px;
}
.last-group {
  margin-top: 30px;
  margin-bottom: 10px;
}
.last-group .dx-item-content {
  align-items: start;
  justify-content: center;
}
.last-group .dx-field-item {
  padding: 0 !important;
}
.buttons-group {
  display: flex;
  width: 100%;
  justify-content: end;
}
.buttons-group .dx-item-content {
  gap: 10px;
}