text:
/**
 *
 * SettingPage
 */

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import { findIndex, get, isEmpty, upperFirst } from 'lodash';
import cn from 'classnames';
import HTML5Backend from 'react-dnd-html5-backend';
import { DragDropContext } from 'react-dnd';
import { FormattedMessage } from 'react-intl';
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
import PropTypes from 'prop-types';
import BackHeader from 'components/BackHeader';
import HeaderNav from 'components/HeaderNav';
import Input from 'components/InputsIndex';
import InputSelect from 'components/InputSelect';
import PluginHeader from 'components/PluginHeader';
import PopUpWarning from 'components/PopUpWarning';

import pluginId from '../../pluginId';

import Block from '../../components/Block';
import CustomDragLayer from '../../components/CustomDragLayer';
import DraggableAttr from '../../components/DraggableAttr';
import FormTitle from '../../components/FormTitle';
import VariableDraggableAttr from '../../components/VariableDraggableAttr';

import {
  beginMove,
  endMove,
  moveAttr,
  moveAttrEditView,
  moveVariableAttrEditView,
  onChangeInputType,
  onChangeSettings,
  onClickAddAttr,
  onClickAddAttrField,
  onRemove,
  onRemoveEditViewFieldAttr,
  onRemoveEditViewRelationAttr,
  onReset,
  onSubmit,
  setLayout,
} from '../App/actions';
import {
  makeSelectAddedField,
  makeSelectDraggedItemName,
  makeSelectGrid,
  makeSelectHoverIndex,
  makeSelectInitDragLine,
  makeSelectModifiedSchema,
  makeSelectShouldResetGrid,
  makeSelectSubmitSuccess,
} from '../App/selectors';

import { onClickEditField, onClickEditListItem, onClickEditRelation } from './actions';
import reducer from './reducer';
import saga from './saga';
import makeSelectSettingPage from './selectors';

import SectionTitle from './SectionTitle';

import forms from './forms.json';
import styles from './styles.scss';

class SettingPage extends React.PureComponent {
  state = {
    isDraggingSibling: false,
    isOpen: false,
    isOpenField: false,
    isOpenRelation: false,
    showWarning: false,
    showWarningCancel: false,
    shouldSelectField: false,
    shouldSelectRelation: false,
  };

  componentDidMount() {
    this.handleClickEditAttr(0);
    const fields = this.getEditPageDisplayedFields();
    const relations = this.getEditPageDisplayedRelations();
    this.props.setLayout(`${this.getPath()}.editDisplay`);

    if (fields.length > 0) {
      this.handleClickEditField(0);
    } else if (relations.length > 0) {
      this.handleClickEditRelation(0);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { schema } = prevProps;
    const prevDisplayedFields = get(
      schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'fields'],
      [],
    );
    const prevDisplayedRelations = get(
      schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'relations'],
      [],
    );
    const currentDisplayedFields = get(
      this.props.schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'fields'],
      [],
    );
    const currentDisplayedRelations = get(
      this.props.schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'relations'],
      [],
    );

    if (prevProps.submitSuccess !== this.props.submitSuccess) {
      this.toggle();
    }

    if (
      prevDisplayedFields.length === 0 &&
      currentDisplayedFields.length > 0 &&
      prevState.shouldSelectField !== this.state.shouldSelectField
    ) {
      this.handleClickEditField(0);
    }

    if (
      prevDisplayedRelations.length === 0 &&
      currentDisplayedRelations.length > 0 &&
      prevState.shouldSelectRelation !== this.state.shouldSelectRelation
    ) {
      this.handleClickEditRelation(0);
    }

    if (prevProps.addedField !== this.props.addedField) {
      this.props.setLayout(`${this.getPath()}.editDisplay`);
    }

    if (prevProps.shouldResetGrid !== this.props.shouldResetGrid) {
      this.props.setLayout(`${this.getPath()}.editDisplay`);
    }
  }

  componentWillUnmount() {
    // Reset the modified data
    this.props.onReset();
  }

  getAttrData = attrName =>
    get(this.getEditPageDisplaySettings(), ['availableFields', attrName], {});

  getDefaultSort = () => this.getValue(`${this.getPath()}.defaultSort`, 'string');

  getDropDownItems = () => {
    const name = get(this.props.schema, `models.${this.getPath()}.primaryKey`, 'id');
    // The id attribute is not present on the schema so we need to add it manually
    const defaultAttr = {
      [name]: { name, label: 'Id', type: 'string', searchable: true, sortable: true },
    };
    const attributes = Object.assign(
      get(this.props.schema, `models.${this.getPath()}.attributes`, {}),
      defaultAttr,
    );

    return Object.keys(attributes)
      .filter(attr => {
        return (
          findIndex(this.getListDisplay(), ['name', attr]) === -1 &&
          !attributes[attr].hasOwnProperty('collection') &&
          !attributes[attr].hasOwnProperty('model')
        );
      })
      .map(attr => {
        const searchable = attributes[attr].type !== 'json' && attributes[attr].type !== 'array';
        const obj = Object.assign(attributes[attr], {
          name: attr,
          label: upperFirst(attr),
          searchable,
          sortable: searchable,
        });

        return obj;
      });
  };

  getDropDownFieldItems = () => {
    const currentDisplayedFields = this.getEditPageDisplayedFields();
    const availableFields = this.getEditPageFields();

    return Object.keys(availableFields).filter(field => {
      return currentDisplayedFields.indexOf(field) === -1;
    });
  };

  getDropDownRelationsItems = () => {
    const currentDisplayedRelations = this.getEditPageDisplayedRelations();

    return this.getRelations().filter(relation => {
      return currentDisplayedRelations.indexOf(relation) === -1;
    });
  };

  getEditPageDisplaySettings = () => {
    return get(this.props.schema, 'models.'.concat(this.getPath().concat('.editDisplay')), {
      fields: [],
      relations: [],
    });
  };

  getEditPageDisplayedFields = () => get(this.getEditPageDisplaySettings(), ['fields'], []);

  getEditPageDisplayedRelations = () => get(this.getEditPageDisplaySettings(), ['relations'], []);

  getEditPageFields = () => get(this.props.schema, ['models', ...this.getPath().split('.'), 'editDisplay', 'availableFields'], {});

  getEditPagePossibleEntryTitleFields = () => {
    const availableFields = this.getEditPageFields();

    const stringAndNumberFields = Object.keys(availableFields)
      .filter(field => {
        const currentField = availableFields[field];

        return currentField.type === 'string' || currentField.type === 'number';
      });

    return [this.getPrimaryKey(), ...stringAndNumberFields];
  }

  getLayout = () => {
    const {
      match: {
        params: { slug, endPoint },
      },
      schema: { layout },
    } = this.props;

    return get(layout, [endPoint || slug, 'attributes'], {});
  };

  getListDisplay = () => get(this.props.schema, `models.${this.getPath()}.listDisplay`, []);

  getModelName = () => {
    const {
      match: {
        params: { slug, endPoint },
      },
    } = this.props;

    return endPoint || slug;
  };

  getPath = () => {
    const {
      match: {
        params: { slug, source, endPoint },
      },
    } = this.props;

    return [slug, source, endPoint].filter(param => param !== undefined).join('.');
  };

  getRelationLabel = attrName => {
    const attrLabel = get(
      this.props.schema,
      ['models', ...this.getPath().split('.'), 'relations', attrName, 'label'],
      'iii',
    );

    return attrLabel;
  };

  getRelations = () => {
    const relations = get(
      this.props.schema,
      'models.'.concat(this.getPath()).concat('.relations'),
      {},
    );

    return Object.keys(relations).filter(relation => {
      const isUploadRelation = get(relations, [relation, 'plugin'], '') === 'upload';
      const isMorphSide =
        get(relations, [relation, 'nature'], '')
          .toLowerCase()
          .includes('morph') && get(relations, [relation, relation]) !== undefined;

      return !isUploadRelation && !isMorphSide;
    });
  };

  getSelectOptions = input => {
    const selectOptions = this.getListDisplay().reduce((acc, curr) => {
      if (curr.sortable === true) {
        return acc.concat([curr.name]);
      }

      return acc;
    }, []);

    if (selectOptions.length === 0) {
      selectOptions.push(this.getPrimaryKey());
    }

    return input.name === 'defaultSort' ? selectOptions : input.selectOptions;
  };

  getPluginHeaderActions = () => {
    return [
      {
        label: 'content-manager.popUpWarning.button.cancel',
        kind: 'secondary',
        onClick: this.handleReset,
        type: 'button',
      },
      {
        kind: 'primary',
        label: 'content-manager.containers.Edit.submit',
        onClick: (e) => {
          this.context.emitEvent('willSaveContentTypeLayout');
          this.handleSubmit(e);
        },
        type: 'submit',
      },
    ];
  };

  getPrimaryKey = () =>
    get(this.props.schema, ['models', this.getModelName()].concat(['primaryKey']), 'id');

  getValue = (keys, type) => {
    const value = get(this.props.schema, ['models'].concat(keys.split('.')));

    return type === 'toggle' ? value : value.toString();
  };

  getViewType = () => {
    const { match: { params: { viewType } } } = this.props;

    return viewType;
  }

  generateHeaderNavLinks = () => {
    const { match: { params: { slug, source, endPoint } } } = this.props;
    const suffix = [source, endPoint]
      .reduce((acc, curr) => {
        if (curr) {
          acc = `${acc}/${curr}`;
        }

        return acc;
      }, slug);

    return [
      {
        name: 'content-manager.containers.SettingPage.listSettings.title',
        to: `/plugins/content-manager/ctm-configurations/list-settings/${suffix}`,
      },
      {
        name: 'content-manager.containers.SettingPage.editSettings.title',
        to: `/plugins/content-manager/ctm-configurations/edit-settings/${suffix}`,
      },
    ];
  }

  handleChange = e => {
    const defaultSort = this.getDefaultSort();
    const name = e.target.name.split('.');
    name.pop();
    const attrName = get(this.props.schema.models, name.concat(['name']));
    const isDisablingDefaultSort = attrName === defaultSort && e.target.value === false;

    if (isDisablingDefaultSort) {
      const enableAttrsSort = this.getSelectOptions({ name: 'defaultSort' }).filter(
        attr => attr !== attrName,
      );

      if (enableAttrsSort.length === 0) {
        strapi.notification.info('content-manager.notification.info.SettingPage.disableSort');
      } else {
        const newDefaultSort =
          enableAttrsSort.length === 0 ? this.getPrimaryKey() : enableAttrsSort[0];
        const target = { name: `${this.getPath()}.defaultSort`, value: newDefaultSort };
        this.props.onChangeSettings({ target });
        this.props.onChangeSettings(e);
      }
    } else {
      this.props.onChangeSettings(e);
    }
  };

  handleClickEditAttr = index => {
    const attrToEdit = get(
      this.props.schema,
      ['models'].concat(this.getPath().split('.')).concat(['listDisplay', index]),
      {},
    );
    this.props.onClickEditListItem(attrToEdit);
  };

  handleClickEditField = index => {
    const fieldToEditName = get(
      this.props.schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'fields', index],
      '',
    );
    const fieldToEdit = get(
      this.props.schema,
      ['models', ...this.getPath().split('.'), 'editDisplay', 'availableFields', fieldToEditName],
      {},
    );

    return this.props.onClickEditField(fieldToEdit);
  };

  handleClickEditRelation = index => {
    const relationToEditName = get(this.getEditPageDisplayedRelations(), index, '');
    const relationToEdit = get(this.props.schema, [
      'models',
      ...this.getPath().split('.'),
      'relations',
      relationToEditName,
    ]);

    return this.props.onClickEditRelation(relationToEdit);
  };

  handleConfirmReset = () => {
    this.props.onReset();
    this.toggleWarningCancel();
  };

  handleGoBack = () => this.props.history.goBack();

  handleRemove = (index, keys) => {
    const attrToRemove = get(this.getListDisplay(), index, {});
    const defaultSort = this.getDefaultSort();
    const isRemovingDefaultSort = defaultSort === attrToRemove.name;

    if (isRemovingDefaultSort) {
      const enableAttrsSort = this.getSelectOptions({ name: 'defaultSort' }).filter(
        attr => attr !== attrToRemove.name,
      );
      const newDefaultSort = enableAttrsSort.length > 1 ? enableAttrsSort[0] : this.getPrimaryKey();
      const target = { name: `${this.getPath()}.defaultSort`, value: newDefaultSort };
      this.props.onChangeSettings({ target });
    }

    this.props.onRemove(index, keys);
  };

  handleRemoveField = (index, keys) => {
    const {
      settingPage: { fieldToEdit },
    } = this.props;
    const fieldToEditName = get(
      this.props.schema,
      ['models', ...keys.split('.'), 'fields', index],
      '',
    );
    this.manageRemove(index, keys, fieldToEditName, fieldToEdit, false);
  };

  handleRemoveRelation = (index, keys) => {
    const {
      settingPage: { relationToEdit },
    } = this.props;
    const relationToRemoveName = get(this.props.schema, ['models', ...keys.split('.'), index]);
    this.manageRemove(index, keys, relationToRemoveName, relationToEdit);
  };

  manageRemove = (index, keys, itemName, data, isRelation = true) => {
    const isRemovingSelectedItem = isRelation ? itemName === data.alias : itemName === data.name;
    const displayedRelations = this.getEditPageDisplayedRelations();
    const displayedFields = this.getEditPageDisplayedFields();
    const allRelations = this.getRelations();
    const allFields =  Object.keys(get(this.props.schema, ['models', ...this.getPath().split('.'), 'editDisplay', 'availableFields'], {}));

    if (isRemovingSelectedItem && displayedRelations.length === 1 && allFields.length === 0) {
      return strapi.notification.info('content-manager.notification.error.displayedFields');
    }

    if (isRemovingSelectedItem && displayedFields.length === 1 && allRelations.length === 0) {
      return strapi.notification.info('content-manager.notification.error.displayedFields');
    }

    if (isRelation) {
      this.props.onRemoveEditViewRelationAttr(index, keys);
    } else {
      this.props.onRemoveEditViewFieldAttr(index, keys);
    }

    if (isRemovingSelectedItem) {
      const selectNextItemCond = isRelation
        ? displayedRelations.length > 1
        : displayedFields.length > 1;
      const selectOtherItemCond = isRelation
        ? displayedFields.length > 0
        : displayedRelations.length > 0;
      const selectNextFunc = isRelation ? this.handleClickEditRelation : this.handleClickEditField;
      const selectOtherFunc = !isRelation
        ? this.handleClickEditRelation
        : this.handleClickEditField;

      if (selectNextItemCond) {
        let nextIndex = index - 1 > 0 ? index - 1 : index + 1;

        if (!isRelation) {
          const nextItem = get(this.getEditPageDisplayedFields(), nextIndex);

          if (nextItem.includes('__col-md')) {
            nextIndex = index - 2 > 0 ? index - 2 : index + 2;
          }
        }
        selectNextFunc(nextIndex);
      } else if (selectOtherItemCond) {
        selectOtherFunc(0);
      } else {
        const toAdd = isRelation
          ? this.getDropDownFieldItems()[0]
          : this.getDropDownRelationsItems()[0];

        if (isRelation) {
          this.props.onClickAddAttrField(toAdd, `${this.getPath()}.editDisplay.fields`);
          this.setState(prevState => ({ shouldSelectField: !prevState.shouldSelectField }));
        } else {
          this.props.onClickAddAttr(toAdd, `${this.getPath()}.editDisplay.relations`);
          this.setState(prevState => ({ shouldSelectRelation: !prevState.shouldSelectRelation }));
        }
      }
    }
  };

  handleReset = e => {
    e.preventDefault();
    this.setState({ showWarningCancel: true });
  };

  handleSubmit = e => {
    e.preventDefault();
    this.setState({ showWarning: true });
  };

  findIndexFieldToEdit = () => {
    const {
      settingPage: { fieldToEdit },
    } = this.props;

    if (isEmpty(fieldToEdit)) {
      return -1;
    }

    const index = this.getEditPageDisplayedFields().indexOf(fieldToEdit.name);

    return index;
  };

  findIndexListItemToEdit = () => {
    const index = findIndex(this.getListDisplay(), [
      'name',
      get(this.props.settingPage, ['listItemToEdit', 'name']),
    ]);

    return index === -1 ? 0 : index;
  };

  findIndexRelationItemToEdit = () => {
    const {
      settingPage: { relationToEdit },
    } = this.props;

    if (isEmpty(relationToEdit)) {
      return -1;
    }

    const index = this.getEditPageDisplayedRelations().indexOf(relationToEdit.alias);

    return index;
  };

  hasRelations = () => {
    return this.getRelations().length > 0;
  };

  isEditingTextField = () => {
    const {
      settingPage: { fieldToEdit },
    } = this.props;
    const type = get(fieldToEdit, 'type', null);

    return type === 'text';
  }

  shouldDisplayCursorNotAllowed = dropdownType => {
    switch (dropdownType) {
      case 'list':
        return this.getDropDownItems().length === 0;
      case 'relations':
        return this.getDropDownRelationsItems().length === 0;
      case 'fields':
        return this.getDropDownFieldItems().length === 0;
      default:
        return false;
    }
  };

  toggle = () => this.setState(prevState => ({ showWarning: !prevState.showWarning }));

  toggleWarningCancel = () =>
    this.setState(prevState => ({ showWarningCancel: !prevState.showWarningCancel }));

  toggleDropdown = () => {
    if (this.getDropDownItems().length > 0) {
      this.setState(prevState => ({ isOpen: !prevState.isOpen }));
    }
  };

  toggleDropDownFields = () => {
    if (this.getDropDownFieldItems().length > 0) {
      this.setState(prevState => ({ isOpenField: !prevState.isOpenField }));
    }
  };

  toggleDropdownRelations = () => {
    if (this.getDropDownRelationsItems().length > 0) {
      this.setState(prevState => ({ isOpenRelation: !prevState.isOpenRelation }));
    }
  };

  // We need to remove the Over state on the DraggableAttr component
  updateSiblingHoverState = () => {
    this.setState(prevState => ({ isDraggingSibling: !prevState.isDraggingSibling }));
  };

  renderDraggableAttrEditSettingsField = (attr, index) => {
    return (
      <VariableDraggableAttr
        beginMove={this.props.beginMove}
        data={this.getAttrData(attr)}
        draggedItemName={this.props.draggedItemName}
        endMove={this.props.endMove}
        grid={this.props.grid}
        hoverIndex={this.props.hoverIndex}
        id={attr}
        index={index}
        initDragLine={this.props.initDragLine}
        isEditing={index === this.findIndexFieldToEdit()}
        key={attr}
        keys={`${this.getPath()}.editDisplay`}
        layout={this.getLayout()}
        name={attr}
        moveAttr={this.props.moveVariableAttrEditView}
        onRemove={this.handleRemoveField}
        onClickEdit={this.handleClickEditField}
      />
    );
  };

  renderDraggableAttrEditSettingsRelation = (attr, index) => {
    return (
      <DraggableAttr
        index={index}
        isDraggingSibling={false}
        isEditing={index === this.findIndexRelationItemToEdit()}
        key={attr}
        keys={`${this.getPath()}.editDisplay.relations`}
        name={attr}
        label={this.getRelationLabel(attr)}
        moveAttr={this.props.moveAttrEditView}
        onClickEdit={this.handleClickEditRelation}
        onRemove={this.handleRemoveRelation}
        updateSiblingHoverState={() => {}}
      />
    );
  };

  renderDraggableAttrListSettings = (attr, index) => {
    return (
      <div key={attr.name} className={styles.draggedWrapper}>
        <div>{index + 1}.</div>
        <DraggableAttr
          index={index}
          isDraggingSibling={this.state.isDraggingSibling}
          isEditing={index === this.findIndexListItemToEdit()}
          key={attr.name}
          keys={this.getPath()}
          label={attr.label}
          name={attr.name}
          moveAttr={this.props.moveAttr}
          onClickEdit={this.handleClickEditAttr}
          onRemove={this.handleRemove}
          updateSiblingHoverState={this.updateSiblingHoverState}
        />
      </div>
    );
  };

  renderDropDownItemSettingField = item => {
    return (
      <DropdownItem
        key={item}
        onClick={() => this.props.onClickAddAttrField(item, `${this.getPath()}.editDisplay.fields`)}
      >
        {item}
      </DropdownItem>
    );
  };

  renderDropDownItemEditSettingsRelation = item => {
    return (
      <DropdownItem
        key={item}
        onClick={() => this.props.onClickAddAttr(item, `${this.getPath()}.editDisplay.relations`)}
      >
        {item}
      </DropdownItem>
    );
  };

  renderDropDownItemListSettings = item => {
    return (
      <DropdownItem
        key={item.name}
        onClick={() => {
          this.props.onClickAddAttr(item, `${this.getPath()}.listDisplay`);
        }}
      >
        {item.label}
      </DropdownItem>
    );
  };

  renderDropDownP = msg => <p>{msg}</p>;

  renderForm = () => {
    const {
      settingPage: { fieldToEdit, relationToEdit },
    } = this.props;

    if (isEmpty(fieldToEdit)) {
      return forms.editView.relationForm.map(this.renderFormEditSettingsRelation);
    }

    if (isEmpty(relationToEdit)) {
      return forms.editView.fieldForm.map(this.renderFormEditSettingsField);
    }

    return null;
  };

  renderFormEditSettingsField = (input, i) => {
    const {
      onChangeSettings,
      schema,
      settingPage: {
        fieldToEdit: { name },
      },
    } = this.props;
    const path = [...this.getPath().split('.'), 'editDisplay', 'availableFields', name, input.name];
    const value = get(schema, ['models', ...path], '');

    return (
      <Input key={i} onChange={onChangeSettings} value={value} {...input} name={path.join('.')} />
    );
  };

  renderFormEditSettingsRelation = (input, i) => {
    const {
      onChangeSettings,
      schema,
      settingPage: {
        relationToEdit: { alias },
      },
    } = this.props;
    const path = [...this.getPath().split('.'), 'relations', alias, input.name];
    const value = get(schema, ['models', ...path], '');

    return (
      <Input key={i} onChange={onChangeSettings} value={value} {...input} name={path.join('.')} />
    );
  };

  renderFormListAttrSettings = (input, i) => {
    const indexListItemToEdit = this.findIndexListItemToEdit();
    const inputName = `${this.getPath()}.listDisplay.${indexListItemToEdit}.${input.name}`;
    const inputType = this.getListDisplay()[indexListItemToEdit].type;

    if (indexListItemToEdit === -1) {
      return <div key={i} />;
    }

    if (
      (inputType === 'json' || inputType === 'array') &&
      (input.name === 'sortable' || input.name === 'searchable')
    ) {
      return null;
    }

    return (
      <Input
        key={input.name}
        onChange={this.handleChange}
        value={this.getValue(inputName, input.type)}
        {...input}
        name={inputName}
      />
    );
  };

  renderInputMainSettings = input => {
    const inputName = `${this.getPath()}.${input.name}`;

    return (
      <Input
        {...input}
        key={input.name}
        name={inputName}
        onChange={this.props.onChangeSettings}
        selectOptions={this.getSelectOptions(input)}
        value={this.getValue(inputName, input.type)}
      />
    );
  };

  renderEditSettings = () => {
    const { isOpenField, isOpenRelation } = this.state;
    const displayedFieldPath = [...this.getPath().split('.'), 'editDisplay', 'displayedField'];
    const value = get(this.props.schema, ['models', ...displayedFieldPath], null);

    return (
      <Block
        style={{ marginBottom: '13px', paddingBottom: '30px', paddingTop: '25px' }}
      >
        <SectionTitle isSettings />
        <div className="row">
          <div className={cn('col-md-12', styles.editFormTitle)}>
            <FormTitle
              title="content-manager.containers.SettingPage.editSettings.entry.title"
              description="content-manager.containers.SettingPage.editSettings.entry.title.description"
            />
          </div>
          <div className="col-md-4">
            <InputSelect
              name={displayedFieldPath.join('.')}
              onChange={this.props.onChangeSettings}
              style={{ marginBottom: '6px' }}
              selectOptions={this.getEditPagePossibleEntryTitleFields()}
              value={value}
            />
          </div>
          <div className="col-md-12">
            <div className={styles.separatorHigher} />
          </div>
        </div>

        <SectionTitle />
        <div className="row">
          <div className={cn('col-md-8', styles.draggedDescription, styles.edit_settings)}>
            <FormTitle
              title="content-manager.global.displayedFields"
              description="content-manager.containers.SettingPage.editSettings.description"
            />
            <div className={cn(styles.sort_wrapper, 'col-md-12', styles.padded)}>
              <CustomDragLayer />
              <div className={cn('row', styles.noPadding)}>
                {this.getEditPageDisplayedFields().map(
                  this.renderDraggableAttrEditSettingsField,
                )}
                <div className={cn('col-md-6')}>
                  <div
                    className={cn(
                      styles.dropdownRelations,
                      styles.dropdownWrapper,
                      isOpenField && styles.dropdownWrapperOpen,
                      this.shouldDisplayCursorNotAllowed('fields') &&
                        styles.dropDownNotAllowed,
                    )}
                  >
                    <ButtonDropdown isOpen={isOpenField} toggle={this.toggleDropDownFields}>
                      <DropdownToggle>
                        <FormattedMessage id="content-manager.containers.SettingPage.addField">
                          {this.renderDropDownP}
                        </FormattedMessage>
                      </DropdownToggle>
                      <DropdownMenu>
                        {this.getDropDownFieldItems().map(
                          this.renderDropDownItemSettingField,
                        )}
                      </DropdownMenu>
                    </ButtonDropdown>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {/* RELATIONS SORT */}
          {this.hasRelations() && (
            <div className={cn('col-md-4', styles.draggedDescription, styles.edit_settings)}>
              <FormTitle
                title="content-manager.containers.SettingPage.relations"
                description="content-manager.containers.SettingPage.editSettings.description"
              />
              <div className={cn(styles.sort_wrapper, 'col-md-12')}>
                <div className="row">
                  {/* DRAGGABLE BLOCK */}
                  {this.getEditPageDisplayedRelations().map(
                    this.renderDraggableAttrEditSettingsRelation,
                  )}
                  {/* DRAGGABLE BLOCK */}
                  <div
                    className={cn(
                      styles.dropdownRelations,
                      styles.dropdownWrapper,
                      isOpenRelation && styles.dropdownWrapperOpen,
                      this.shouldDisplayCursorNotAllowed('relations') &&
                        styles.dropDownNotAllowed,
                    )}
                  >
                    <ButtonDropdown
                      isOpen={isOpenRelation}
                      toggle={this.toggleDropdownRelations}
                    >
                      <DropdownToggle>
                        <FormattedMessage id="content-manager.containers.SettingPage.addRelationalField">
                          {this.renderDropDownP}
                        </FormattedMessage>
                      </DropdownToggle>
                      <DropdownMenu>
                        {this.getDropDownRelationsItems().map(
                          this.renderDropDownItemEditSettingsRelation,
                        )}
                      </DropdownMenu>
                    </ButtonDropdown>
                  </div>
                </div>
              </div>
            </div>
          )}
          {/* RELATIONS SORT */}
        </div>

        {/* EDIT MAIN ATTR FORM */}
        <div className="row">
          <div className="col-md-8">
            <div className={styles.editWrapper} style={{ paddingTop: '26px' }}>
              <div className="row">
                {this.renderForm()}
                {/* DISPLAY A TOGGLE THAT CHANGES THE TEXTAREA TO WYSIWYG */}
                {/* @aurelsicoko remove this line if you want to remove this feature */}
                {this.isEditingTextField() && this.renderInputWysiwyg()}
              </div>
            </div>
          </div>
        </div>
        {/* EDIT MAIN ATTR FORM */}
      </Block>
    );
  }

  renderListSettings = () => {
    const { isOpen } = this.state;

    return (
      <Block
        style={{ marginBottom: '13px', paddingBottom: '30px', paddingTop: '25px' }}
      >
        <SectionTitle isSettings />
        <div className="row">
          {/* GENERAL LIST SETTINGS FORM */}
          <div className="col-md-12">
            <div className="row">{forms.inputs.map(this.renderInputMainSettings)}</div>
          </div>

          <div className="col-md-12">
            <div className={styles.separatorHigher} />
          </div>
        </div>
        <SectionTitle />
        <div className="row">
          <div className={cn('col-md-12', styles.draggedDescription)}>
            <FormTitle
              title="content-manager.global.displayedFields"
              description="content-manager.containers.SettingPage.attributes.description"
            />
          </div>

          <div className="col-md-5">
            {this.getListDisplay().map(this.renderDraggableAttrListSettings)}
            <div
              className={cn(
                styles.dropdownWrapper,
                isOpen && styles.dropdownWrapperOpen,
                this.shouldDisplayCursorNotAllowed('list') && styles.dropDownNotAllowed,
              )}
            >
              <ButtonDropdown isOpen={isOpen} toggle={this.toggleDropdown}>
                <DropdownToggle>
                  <FormattedMessage id="content-manager.containers.SettingPage.addField">
                    {this.renderDropDownP}
                  </FormattedMessage>
                </DropdownToggle>
                <DropdownMenu>
                  {this.getDropDownItems().map(this.renderDropDownItemListSettings)}
                </DropdownMenu>
              </ButtonDropdown>
            </div>
          </div>

          {/* LIST ATTR FORM */}
          <div className="col-md-7">
            <div className={styles.editWrapper}>
              <div className="row">{forms.editList.map(this.renderFormListAttrSettings)}</div>
            </div>
          </div>
          {/* LIST ATTR FORM */}
        </div>
      </Block>
    );
  };

  renderInputWysiwyg = () => {
    const {
      match: {
        params: { slug, endPoint },
      },
      onChangeInputType,
      settingPage: { fieldToEdit },
    } = this.props;

    const inputName = get(fieldToEdit, 'name', null);
    const name = `layout.${endPoint || slug}.attributes.${inputName}.appearance`;
    const value = get(this.getLayout(), [inputName, 'appearance']) === 'WYSIWYG';

    return <Input label={{ id: 'content-manager.form.Input.wysiwyg'}} type="toggle" name={name} onChange={onChangeInputType} value={value} />;
  }

  render() {
    const { showWarning, showWarningCancel } = this.state;
    const { match: { params: { viewType } }, onSubmit } = this.props;
    const content = viewType === 'list-settings' ? this.renderListSettings : this.renderEditSettings;

    return (
      <form onSubmit={this.handleSubmit}>
        <BackHeader onClick={this.handleGoBack} />
        <div className={cn('container-fluid', styles.containerFluid)}>
          <PluginHeader
            actions={this.getPluginHeaderActions()}
            title={`Content Manager - ${upperFirst(this.getModelName())}`}
            description={{ id: 'content-manager.containers.SettingPage.pluginHeaderDescription' }}
          />
          <PopUpWarning
            isOpen={showWarning}
            toggleModal={this.toggle}
            content={{
              title: 'content-manager.popUpWarning.title',
              message: 'content-manager.popUpWarning.warning.updateAllSettings',
              cancel: 'content-manager.popUpWarning.button.cancel',
              confirm: 'content-manager.popUpWarning.button.confirm',
            }}
            popUpWarningType="danger"
            onConfirm={() => onSubmit(this.context)}
          />
          <PopUpWarning
            isOpen={showWarningCancel}
            toggleModal={this.toggleWarningCancel}
            content={{
              title: 'content-manager.popUpWarning.title',
              message: 'content-manager.popUpWarning.warning.cancelAllSettings',
              cancel: 'content-manager.popUpWarning.button.cancel',
              confirm: 'content-manager.popUpWarning.button.confirm',
            }}
            popUpWarningType="danger"
            onConfirm={this.handleConfirmReset}
          />

          <HeaderNav links={this.generateHeaderNavLinks()} />
          <div className={cn('row', styles.container)}>
            {content()}
          </div>
        </div>
      </form>
    );
  }
}

SettingPage.contextTypes = {
  emitEvent: PropTypes.func,
};

SettingPage.defaultProps = {
  draggedItemName: null,
  grid: [],
};

SettingPage.propTypes = {
  addedField: PropTypes.bool.isRequired,
  beginMove: PropTypes.func.isRequired,
  draggedItemName: PropTypes.string,
  endMove: PropTypes.func.isRequired,
  grid: PropTypes.array,
  history: PropTypes.object.isRequired,
  hoverIndex: PropTypes.number.isRequired,
  initDragLine: PropTypes.number.isRequired,
  match: PropTypes.object.isRequired,
  moveAttr: PropTypes.func.isRequired,
  moveAttrEditView: PropTypes.func.isRequired,
  moveVariableAttrEditView: PropTypes.func.isRequired,
  onChangeInputType: PropTypes.func.isRequired,
  onChangeSettings: PropTypes.func.isRequired,
  onClickAddAttr: PropTypes.func.isRequired,
  onClickAddAttrField: PropTypes.func.isRequired,
  onClickEditField: PropTypes.func.isRequired,
  onClickEditListItem: PropTypes.func.isRequired,
  onClickEditRelation: PropTypes.func.isRequired,
  onRemove: PropTypes.func.isRequired,
  onRemoveEditViewFieldAttr: PropTypes.func.isRequired,
  onRemoveEditViewRelationAttr: PropTypes.func.isRequired,
  onReset: PropTypes.func.isRequired,
  onSubmit: PropTypes.func.isRequired,
  schema: PropTypes.object.isRequired,
  setLayout: PropTypes.func.isRequired,
  settingPage: PropTypes.object.isRequired,
  shouldResetGrid: PropTypes.bool.isRequired,
  submitSuccess: PropTypes.bool.isRequired,
};

const mapDispatchToProps = dispatch =>
  bindActionCreators(
    {
      beginMove,
      endMove,
      moveAttr,
      moveAttrEditView,
      moveVariableAttrEditView,
      onChangeInputType,
      onChangeSettings,
      onClickAddAttr,
      onClickAddAttrField,
      onClickEditField,
      onClickEditListItem,
      onClickEditRelation,
      onRemove,
      onRemoveEditViewFieldAttr,
      onRemoveEditViewRelationAttr,
      onReset,
      onSubmit,
      setLayout,
    },
    dispatch,
  );
const mapStateToProps = createStructuredSelector({
  addedField: makeSelectAddedField(),
  draggedItemName: makeSelectDraggedItemName(),
  grid: makeSelectGrid(),
  hoverIndex: makeSelectHoverIndex(),
  initDragLine: makeSelectInitDragLine(),
  schema: makeSelectModifiedSchema(),
  settingPage: makeSelectSettingPage(),
  shouldResetGrid: makeSelectShouldResetGrid(),
  submitSuccess: makeSelectSubmitSuccess(),
});
const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps,
);
const withReducer = strapi.injectReducer({ key: 'settingPage', reducer, pluginId });
const withSaga = strapi.injectSaga({ key: 'settingPage', saga, pluginId });

export default compose(
  withReducer,
  withSaga,
  withConnect,
)(DragDropContext(HTML5Backend)(SettingPage));


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- From: file:/E:/WWWWWWWWW/Trying/aChartAndroidlib/src/main/res/values-v14/styles.xml -->
    <eat-comment/>
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- API 14 theme customizations can go here. -->
    </style>
</resources>

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Orleans;

namespace Interface
{
    public class UserProperties
    {
        public string Name { get; set; }
        public string Status { get; set; }
        public HashSet<IUser> Friends { get; set; }

        public UserProperties()
        {
            Friends = new HashSet<IUser>();
        }

        public override string ToString()
        {
            string friends = "";
            foreach (var friend in Friends)
                friends += $"{friend.GetPrimaryKeyString()}, ";

            return $"Name='{Name}' Status='{Status}' Friends: {friends}";
        }
    }
    public interface IUser : IGrainWithStringKey
    {
        Task SetName(string name);
        Task SetStatus(string status);

        Task<UserProperties> GetProperties();

        Task<bool> InviteFriend(IUser friend);
        Task<bool> AddFriend(IUser friend);
        Task Poke(IUser user, string message);
    }
}


text:
'use strict';

const processData = input => {
    const lines = input.split('\n');
    const arr = lines[0].split(/\s+/).map(i => parseInt(i));
    const n = arr[0];
    const k = arr[1];
    const problemsPerChapter = lines[1].split(/\s+/).map(i => parseInt(i));
    let specialProblems = 0;
    let page = 1;
    for(let i = 0; i < n; i++) {
        const problems = problemsPerChapter[i];
        for(let p = 1; p <= problems; p++) {
            if(p === page) {
                specialProblems++;
            }
            if(p !== problems && p % k === 0) {
                page++;
            }
        }
        page++;
    }
    console.log(specialProblems);
};

process.stdin.resume();
process.stdin.setEncoding("ascii");

var _input = "";
process.stdin.on("data", input => _input += input);
process.stdin.on("end", () => processData(_input));


text:
const DrawCard = require('../../../drawcard.js');

class MagisterIllyrio extends DrawCard {
    setupCardAbilities(ability) {
        this.action({
            title: 'Pay 2 gold to stand a character',
            method: 'stand',
            limit: ability.limit.perPhase(1)
        });
    }

    stand(player) {
        if(this.controller !== player || player.gold < 2) {
            return;
        }

        this.game.promptForSelect(player, {
            activePromptTitle: 'Select a character to stand',
            waitingPromptTitle: 'Waiting for opponent to use ' + this.name,
            cardCondition: card => card.location === 'play area' && card.getType() === 'character',
            onSelect: (p, card) => this.onStandSelected(p, card)
        });

        return true;
    }

    onStandSelected(player, card) {
        this.game.addMessage('{0} uses {1} to pay 2 gold and stand {2}', player, this, card);

        player.standCard(card);
        player.gold -= 2;

        return true;
    }
}

MagisterIllyrio.code = '01163';

module.exports = MagisterIllyrio;


text:
package cli

import (
	"github.com/stelligent/mu/common"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestNewInitCommand(t *testing.T) {
	assert := assert.New(t)

	ctx := common.NewContext()

	command := newInitCommand(ctx)

	assert.NotNil(command)
	assert.Equal("init", command.Name, "Name should match")
	assert.Equal("initialize mu.yml file", command.Usage, "Usage should match")
	assert.Equal(3, len(command.Flags), "Flags len should match")

}


text:
require 'serverspec'

include Serverspec::Helper::Exec
include Serverspec::Helper::DetectOS

RSpec.configure do |c|
  c.before :all do
    c.os = backend(Serverspec::Commands::Base).check_os
    c.path = '/sbin:/usr/sbin'
  end
end

describe file('/srv/frog/webapp/webapp/settings.py') do
  it { should be_owned_by 'frog' }
  it { should be_grouped_into 'frog' }
  it { should be_mode 600 }
  its(:content) { should match(/'ENGINE': 'django.db.backends.mysql'/) }
  its(:content) { should match(/'NAME': 'frog'/) }
  its(:content) { should match(/'USER': 'frog'/) }
  its(:content) { should match(/'PASSWORD': 'frogadmin'/) }
  its(:content) { should match(/'HOST': '.*rds.amazonaws.com'/) }
  its(:content) { should match(/'PORT': [0-9]*/) }
end


text:
VirtualPersistAPI Use Cases
===========================

VirtualPersistAPI (VPA) is conceived as persistent data storage for use with virtual worlds like Second Life.

Main use case
-------------

The main use case will be a script in Second Life that needs to persist some data.

This script will need to be able to:

- Persist and update data (using a POST request)

- Query which data is available (using a GET request specifying category and key lookup)

- Query data (using a GET request)

- Delete data (using a DELETE request)

The amount of data to be stored per record is limited mainly by LSL's request limitations. Currently, the maximum request body size is 2048 bytes by default, but can be set to 4096 or 16384 bytes under some circumstances.

Other use cases
---------------

This system could be used by any consumer to persist arbitrary data. It could serve as a data store for non-LSL based systems, using the API.


text:
import _ from 'lodash';
import 'ui/directives/validate_ip';
import 'ui/directives/validate_cidr_mask';
import AggTypesBucketsBucketAggTypeProvider from 'ui/agg_types/buckets/_bucket_agg_type';
import AggTypesBucketsCreateFilterIpRangeProvider from 'ui/agg_types/buckets/create_filter/ip_range';
import ipRangesTemplate from 'ui/agg_types/controls/ip_ranges.html';

export default function RangeAggDefinition(Private) {
  let BucketAggType = Private(AggTypesBucketsBucketAggTypeProvider);
  let createFilter = Private(AggTypesBucketsCreateFilterIpRangeProvider);

  return new BucketAggType({
    name: 'ip_range',
    title: 'IPv4 Range',
    createFilter: createFilter,
    getKey: function (bucket, key, agg) {
      if (key) return key;
      const from = _.get(bucket, 'from', '-Infinity');
      const to = _.get(bucket, 'to', 'Infinity');
      return `${from} to ${to}`;
    },
    makeLabel: function (aggConfig) {
      return aggConfig.getFieldDisplayName() + ' IP ranges';
    },
    params: [
      {
        name: 'field',
        filterFieldTypes: 'ip'
      }, {
        name: 'ipRangeType',
        default: 'fromTo',
        write: _.noop
      }, {
        name: 'ranges',
        default: {
          fromTo: [
            {from: '0.0.0.0', to: '127.255.255.255'},
            {from: '128.0.0.0', to: '191.255.255.255'}
          ],
          mask: [
            {mask: '0.0.0.0/1'},
            {mask: '128.0.0.0/2'}
          ]
        },
        editor: ipRangesTemplate,
        write: function (aggConfig, output) {
          const ipRangeType = aggConfig.params.ipRangeType;
          let ranges = aggConfig.params.ranges[ipRangeType];

          if (ipRangeType === 'fromTo') {
            ranges = _.map(ranges, (range) => {
              return _.omit(range, _.isNull);
            });
          }

          output.params.ranges = ranges;
        }
      }
    ]
  });
};


text:
package com.subgraph.orchid;

import com.subgraph.orchid.data.HexDigest;

public interface BridgeRouter extends Router {
	void setIdentity(HexDigest identity);
	void setDescriptor(RouterDescriptor descriptor);
}


text:
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_XR_FrequentQueries]

(
	@start			DATETIME=NULL,			--the start of the time window. If NULL, defaults to 4 hours ago.
	@end			DATETIME=NULL,			-- the end of the time window. If NULL, defaults to 1 second ago.
	@source			NVARCHAR(20)=N'trace',		--'trace' = standard AutoWho.Executor background trace;
												-- 'pastsv' reviews data from past sp_XR_SessionViewer calls done in "current" mode
												-- 'pastqp' reviews data from past sp_XR_QueryProgress calls done in "current" or "time series" mode.
												-- This param is ignored if this invocation is "current" mode (i.e. start/end are null)
	@units			NVARCHAR(20)=N'mb',		-- mb, native, or pages
	@minocc			INT=15,					-- the minimum number of unique occurrences a statement or input buffer must have to qualify for the output
	@dbs			NVARCHAR(512)=N'',		--list of DB names to include
	@xdbs			NVARCHAR(512)=N'',		--list of DB names to exclude
	@spids			NVARCHAR(128)=N'',		--comma-separated list of session_ids to include
	@xspids			NVARCHAR(128)=N'',		--comma-separated list of session_ids to exclude
	@attr			NCHAR(1)=N'n',			--Whether to include the session/connection attributes for the request's first entry in sar (in the time range)
	@plan			NVARCHAR(20)=N'none',		--none / statement		whether to include the query plan for each statement
	@context		NCHAR(1)=N'n',			--Whether or not to include the database_id from dm_exec_sessions in the grouping columns.
	@help			NVARCHAR(10)=N'n'		-- "params", "columns", or "all" (anything else <> "N" maps to "all")
)
AS
BEGIN
	SET NOCOUNT ON;
	SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
	SET ANSI_PADDING ON;

	DECLARE @scratch__int				INT,
			@lv__StartUTC				DATETIME,
			@lv__EndUTC					DATETIME,
			@helpexec					NVARCHAR(4000),
			@err__msg					NVARCHAR(MAX),
			@DynSQL						NVARCHAR(MAX),
			@helpstr					NVARCHAR(MAX),
			@lv__CollectionInitiatorID	TINYINT,
			@lv__qplan					NCHAR(1)
			;

	--We always print out the exec syntax (whether help was requested or not) so that the user can switch over to the Messages
	-- tab and see what their options are.
	SET @helpexec = N'
exec sp_XR_FrequentQueries @start=''<start datetime>'', @end=''<end datetime>'', @minocc=15,
	@source=N''trace'',		-- t/trace, sv/pastsv, qp/pastqp
	@units=N''mb'',			-- m/mb, n/native, p/pages
	@dbs=N'''', @xdbs=N'''', @spids=N'''', @xspids=N'''',
	@attr=N''n'', @plan=N''none'',			--n/none, s/statement
	@context=N''n'',
	@help = N''n''							--n, p/params, c/columns, a/all
	';

	--handle case-sensitivity and nulls for string parameters
	SELECT
		@help = LOWER(ISNULL(@help,N'all')),		--unlike the other parms, an invalid help still gets help info rather than raiserror
		@source = LOWER(ISNULL(@source,N'z')),
		@units = LOWER(ISNULL(@units,N'z')),
		@attr = LOWER(ISNULL(@attr,N'z')),
		@plan = LOWER(ISNULL(@plan,N'z')),
		@context = LOWER(ISNULL(@context,N'z'))
		;

	IF @help <> N'n'
	BEGIN
		GOTO helpbasic
	END

	IF @start IS NULL
	BEGIN
		SET @start = DATEADD(HOUR, -4, GETDATE());
		RAISERROR('Parameter @start set to 4 hours ago because a NULL value was supplied.', 10, 1) WITH NOWAIT;
	END

	SET @helpexec = REPLACE(@helpexec,'<start datetime>', REPLACE(CONVERT(NVARCHAR(20), @start, 102),'.','-') + ' ' + CONVERT(NVARCHAR(20), @start, 108) + '.' +
													RIGHT(CONVERT(NVARCHAR(20),N'000') + CONVERT(NVARCHAR(20),DATEPART(MILLISECOND, @start)),3)
					);

	IF @end IS NULL
	BEGIN
		SET @end = DATEADD(SECOND,-1, GETDATE());
		RAISERROR('Parameter @end set to 1 second ago because a NULL value was supplied.',10,1) WITH NOWAIT;
	END

	SET @helpexec = REPLACE(@helpexec,'<end datetime>', REPLACE(CONVERT(NVARCHAR(20), @end, 102),'.','-') + ' ' + CONVERT(NVARCHAR(20), @end, 108) + '.' +
														RIGHT(CONVERT(NVARCHAR(20),N'000') + CONVERT(NVARCHAR(20),DATEPART(MILLISECOND, @end)),3)
						);

	SET @lv__StartUTC = DATEADD(MINUTE, DATEDIFF(MINUTE, GETDATE(), GETUTCDATE()), @start);
	SET @lv__EndUTC = DATEADD(MINUTE, DATEDIFF(MINUTE, GETDATE(), GETUTCDATE()), @end);

	--We use UTC for this check b/c of the DST "fall-back" scenario. We don't want to prevent a user from calling this proc for a timerange
	--that already occurred (e.g. 1:30am-1:45am) at the second occurrence of 1:15am that day.
	IF @lv__StartUTC > GETUTCDATE() OR @lv__EndUTC > GETUTCDATE()
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Neither of the parameters @start or @end can be in the future.',16,1);
		RETURN -1;
	END

	IF @end <= @start
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @end cannot be <= to parameter @start', 16, 1);
		RETURN -1;
	END

	IF @source LIKE N't%'
	BEGIN
		SET @source = N'trace';
		SET @lv__CollectionInitiatorID = 255;	--use the standard historical data collected by AutoWho.Executor
	END
	ELSE IF @source LIKE N'%sv'
	BEGIN
		SET @source = N'pastsv';
		SET @lv__CollectionInitiatorID = 1;		--use the data collected by past calls to sp_XR_SessionViewer
	END
	ELSE IF @source LIKE N'%qp'
	BEGIN
		SET @source = N'pastqp';
		SET @lv__CollectionInitiatorID = 2;		--use the data collected by past calls to sp_XR_QueryProgress
	END
	ELSE
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @source must be either "trace" (historical data from standard AutoWho trace, default), "pastsv" (data from past sp_XR_SessionViewer executions), or "pastqp" (data from past sp_XR_QueryProgress executions).',16,1);
		RETURN -1;
	END

	IF @units LIKE N'm%'
	BEGIN
		SET @units = N'mb';
	END
	ELSE IF @units LIKE N'n%'
	BEGIN
		SET @units = N'native';
	END
	ELSE IF @units LIKE N'p%'
	BEGIN
		SET @units = N'pages';
	END
	ELSE
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @units must be either "mb" (megabytes, default), "native" (DMV native units), or "pages" (8kb pages).',16,1);
		RETURN -1;
	END

	IF ISNULL(@minocc, -1) < 0
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @minocc must be an integer >= 0.', 16, 1);
		RETURN -1;
	END

	IF @attr NOT IN (N'n', N'y')
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @attr must be either "n" (default) or "y".', 16, 1);
		RETURN -1;
	END

	IF @context NOT IN (N'n', N'y')
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @context must be either "n" (default) or "y".', 16, 1);
		RETURN -1;
	END

	IF @plan LIKE N'n%'
	BEGIN
		SET @plan = N'none';
		SET @lv__qplan = N'n';
	END
	ELSE IF @plan LIKE N's%'
	BEGIN
		SET @plan = N'statement';
		SET @lv__qplan = N'y';
	END
	ELSE
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @plan must be either "none" or "statement".',16,1);
		RETURN -1;
	END

	--We don't validate the 4 CSV filtering variables, outside of checking for NULL. We leave that to the sub-procs
	IF @dbs IS NULL
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @dbs cannot be NULL; it should either be an empty string or a comma-delimited string of database names.',16,1);
		RETURN -1;
	END

	IF @xdbs IS NULL
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @xdbs cannot be NULL; it should either be an empty string or a comma-delimited string of database names.',16,1);
		RETURN -1;
	END

	IF @spids IS NULL
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @spids cannot be NULL; it should either be an empty string or a comma-delimited string of session IDs.',16,1);
		RETURN -1;
	END

	IF @xspids IS NULL
	BEGIN
		RAISERROR(@helpexec,10,1);
		RAISERROR('Parameter @xspids cannot be NULL; it should either be an empty string or a comma-delimited string of session IDs.',16,1);
		RETURN -1;
	END

	EXEC @@XRDATABASENAME@@.AutoWho.ViewFrequentQueries @init = @lv__CollectionInitiatorID,
			@start = @start,
			@end = @end,
			@minocc = @minocc,
			@spids = @spids,
			@xspids = @xspids,
			@dbs = @dbs,
			@xdbs = @xdbs,
			@attr = @attr,
			@plan = @lv__qplan,
			@context = @context,
			@units=@units
	;

	--we always print out at least the EXEC command
	GOTO helpbasic

helpbasic:

	IF @help <> N'n'
	BEGIN
		IF @help LIKE N'p%'
		BEGIN
			SET @help = N'params';
		END

		ELSE IF @help LIKE N'c%'
		BEGIN
			SET @help = N'columns';
		END
		ELSE
		BEGIN
			--user may have typed gibberish... which is ok, give him/her all the help
			SET @Help = N'all';
		END
	END

	SET @helpstr = @helpexec;
	RAISERROR(@helpstr,10,1) WITH NOWAIT;

	IF @Help = N'n'
	BEGIN
		--because the user may want to use sp_XR_SessionViewer and/or sp_XR_QueryProgress next, if they haven't asked for help explicitly, we print out the syntax for
		--the Session Viewer and Query Progress procedures
		SET @helpstr = N'
EXEC dbo.sp_XR_SessionViewer @start=''<start datetime>'',@end=''<end datetime>'', --@offset=99999,	--99999
	@source=N''trace'',		-- trace, pastSV, pastQP
	@camrate=0, @camstop=60,
	@activity=1,@dur=0, @dbs=N'''',@xdbs=N'''', @spids=N'''',@xspids=N'''', @blockonly=N''N'',
	@attr=N''N'',@resources=N''N'',@batch=N''N'',@plan=N''none'',	--none, statement, full
	@ibuf=N''N'',@bchain=0,@tran=N''N'',@waits=0,		--bchain 0-10, waits 0-3
	@savespace=N''N'',@directives=N'''', @help=N''N''		--"query(ies)"
	';

		RAISERROR(@helpstr,10,1);

--		SET @helpstr = '
--EXEC dbo.sp_XR_QueryProgress @start=''<start datetime>'',@end=''<end datetime>'', --@offset=99999,	--99999
--						@spid=<int>, @request=0, @nodeassociate=N''N'',
--						@help=N''N''		--"query(ies)"
--		';
		--TODO: once QP is ready, include it in the output here

		RETURN 0;
	END

	SET @helpstr = N'
ChiRho version 2008R2.1

Key Concepts and Terminology
-------------------------------------------------------------------------------------------------------------------------------------------
sp_XR_FrequentQueries displays data from AutoWho, a subcomponent of the ChiRho toolkit that snapshots (by default, every 15 seconds) the
session-centric DMVs and stores the results in tables in the AutoWho schema. sp_XR_FrequentQueries searches a time window and identifies
frequently-occurring statements and input buffers, and aggregates average/min/max data for those statements/buffers. This gives the user the
ability to review a time window and compare the typical state of these frequent queries and any common blocking/waiting issues, resource
contention issues, or query plan issues. This proc also has cousins:

	- sp_XR_SessionSummary: aggregates and displays one row per AutoWho snapshot (called a "capture"), giving the user a quick summary of what
							was/wasn''t occurring in the session-centric DMVs at that point in time. A user can quickly review a window of time
							looking for problems in blocking, resource utilization, long transactions, or long queries.

	- sp_XR_SessionViewer: shows a single AutoWho capture at a time, giving the user details on actively-running queries, blocking,
						   resource usage, session/connection attributes, and query plans for a particular point in time.

	- sp_XR_LongRequests: searches a time window and identifies longer-running requests, aggregating data up to the individual statements
						  executed by that request (at least as observed by AutoWho snapshotting). This gives the user the ability to
						  review a long-running request/batch to identify the problem statements or compare between "good" and "bad runs.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
On a typical install of ChiRho, the AutoWho code typically executes in the context of a background trace, polling every 15 seconds. However,
the same AutoWho collection code can be run by sp_XR_SessionViewer whenever it is running in "current mode". Regardless of which method is
used to collect AutoWho data, it is always stored in AutoWho tables. Thus, even a "current mode" run of sp_XR_SessionViewer stores data from
the DMVs into AutoWho tables before displaying to the user. A tag in the AutoWho tables is used to differentiate which method of collection was
used for each capture, essentially partitioning (logically) the data into different "sets". The @source parameter allows the user to target these
different sets when using sp_XR_FrequentQueries, though only rarely will a value other than "trace" be useful.

sp_XR_FrequentQueries examines a time window (often measured in hours) and returns all unique statements (unique combinations of statement text
and request start time) and unique input buffers (unique combos of input buffer text and dm_exec_sessions.last_request_start_time) that have been
observed between the @start and @end times. This proc can be used to compare between a time window when high-frequency activity was running well
versus when it was running poorly. Often environmental problems can be found, such as increased disk activity or tran log write times, or changes
in query plans, or increase blocking, etc.
	';
	RAISERROR(@helpstr,10,1);

	IF @Help NOT IN (N'params',N'all')
	BEGIN
		GOTO helpcolumns
	END

helpparams:
	SET @helpstr = N'
Parameters (all string parameters are case-insensitive)
-------------------------------------------------------------------------------------------------------------------------------------------
@start			Valid Values: NULL, any datetime value in the past

				Defines the start time of the time window/range used to pull & display request-related data from the ChiRho database. The
				time cannot be in the future, and must be < @end. If NULL is passed, the time defaults to 4 hours before the current time
				[ DATEADD(hour, -4, GETDATE()) ]. If a given request started executing before @start, only its data from @start onward
				will be included.

@end			Valid Values: NULL, any datetime in the past

				Defines the end time of the time window/range used. The time cannot be in the future, and must be > @start. If NULL is
				passed, the time defaults to 1 second before the current time [ DATEADD(second, -1, GETDATE()) ]. If a given request
				continued executing after @end, only its data until @end will be included.

@source			Valid Values: "trace" (default), "sv" or "pastsv", "qp" or "pastqp"

				Specifies which subset of data in AutoWho tables to review. AutoWho data is collected through one of three ways:
				the standard background trace ("trace") which usually executes every 15 seconds all day long; through the
				sp_XR_SessionViewer procedure ("pastsv") when run with null @start and @end parameters; through the sp_XR_QueryProgress
				procedure ("pastqp") also when run with null @start/@end. Internally, this data is partitioned based on how the
				collection in initiated, and this @source parameter allows the user to direct which collection type is reviewed.
				Most of the time, the background trace data is desired and thus "trace" is appropriate.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
@units			Valid Values: "m" or "mb" (default), "n" or "native", "p" or "pages"

				Controls the units the following groups of columns: Task TempDB, Session TempDB, Query Memory requested/granted/used,
				physical and logical reads, writes, and transaction log usage.

				Defaults to megabytes. If "pages", the units are in 8kb blocks (the standard SQL Server database page size). If "native",
				the units are those that come from the DMVs. For logical and physical readers, writes, and TempDB usage, this is 8kb pages. For
				query memory this is kilobytes and for transaction log usage this is bytes.

@minocc			Valid Values: Zero or any positive integer, indicating the threshold of unique occurences required

				TODO

@dbs			Valid Values: comma-separated list of database names to be included. Defaults to empty string.

				Filters the output to include only requests whose context database ID (from dbo.sysprocesses) is equal to the DBIDs
				that correspond to the DB names in this list. If a request has multiple context DBIDs, its first one (in the @start/@end
				range) is the defining context DBID for the complete request.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
@xdbs			Valid Values: comma-separated list of database names to be excluded. Defaults to empty string.

				Filters the output to exclude requests whose initial context DBID (see above note in" @dbs" for how this is defined)
				matches one of the DBs specified.

@spids			Valid Values: comma-separated list of session IDs to be included. Defaults to empty string.

				Filters the output to include only requests whose SPIDs are in this list. Note that there is a bit of a mismatch, in
				that the output data is at the request level, but filtering is at the session level. It is currently considered unlikely
				that a user would want to include requests from one session and exclude other requests from that same session.

@xspids			Valid values: comma-separated list of session IDs to be excluded. Defaults to empty string.

				Filters the output to remove requests whose SPIDs are in this list. See above note (in "@spids") about requests
				versus sessions.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
@attr			Valid values: Y or N (default)

				If Y, a new column named "Plan&Info" is added to the result set. (This column is also added to the output when the
				@plan parameter is set to "statement".) For header-level rows, this column contains various attributes from the
				dm_exec_sessions, dm_exec_connections, and dm_exec_requests views.

@plan			Valid values: "n" or "none", "s" or "statement"

				If Y, a new column named "Plan&Info" is added to the result set. (This column is also added to the output when the
				@attr parameter is set to Y.) For detail-level rows, this column contains the query plan XML for the detail-level row''s
				statement.

				NOTE: Because the initial AutoWho capture(s) of a running request can omit the collection of the query plan (depending
				on the values of the "QueryPlanThreshold" and "QueryPlanThresholdBlockRel" AutoWho options), adding in the plan information
				can change the granularity of the output. For example, the first observation of a request, when its duration is 2.5
				seconds, may omit capturing the query plan for that request, while the next observation 15 seconds later will capture it
				(under default config values). Because the output is grouped by both statement and plan identifiers, there will appear to
				be 2 separate statements (output rows) with the same statement text. This situation does not occur when @plan="N" b/c the
				plan IDs are set to an irrelevant constant.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
@help			Valid Values: N, params, columns, all, or even gibberish

				If @Help=N''N'', then no help is printed. If =''params'', this section of Help is printed. If =''columns'', the section
				on result columns is prented. If @Help is passed anything else (even gibberish), it is set to ''all'', and all help
				content is printed.
	';

	RAISERROR(@helpstr,10,1);

	IF @Help = N'params'
	BEGIN
		GOTO exitloc
	END
	ELSE
	BEGIN
		SET @helpstr = N'
		';
		RAISERROR(@helpstr,10,1);
	END

helpcolumns:

	SET @helpstr = N'
Columns
-------------------------------------------------------------------------------------------------------------------------------------------
SPID			The session ID of the request. Rows for a given request are grouped together, but the overall list of requests is
				ordered by request start time, then by session id, then by request_id. To simplify the output and aid the user visually,
				SPID values are only displayed for header-level (request-level) rows, and this column is blank for detail-level
				(statement-level) rows.

FirstSeen		For header-level rows, the first time (after @start time) the request was seen by the AutoWho collection code. For
				detail-level rows, the first time (after @start time) the statement was seen by AutoWho. If a request was already executing
				before @start, any previous collections by AutoWho will not be reflected in this output.

LastSeen		For header-level rows, the last time (before @end time) the request was seen by the AutoWho collection code. For
				detail-level rows, the last time (after @end time) the statement was seen by AutoWho. If a request was already executing
				after @end, any later collections by AutoWho will not be reflected in this output.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
Extent(sec)		The time difference, in seconds, between FirstSeen and LastSeen. Note that this is NOT necessarily the duration of the
				statement for several reasons:
					1) AutoWho polls on intervals (default=15 seconds for the background trace). A query is unlikely to end right after
						an AutoWho collection and so its duration is almost always longer than seen by AutoWho.
					2) A request executing before @start or after @end will have a duration longer than Last minus First.
					3) The same statement text can be visited multiple times, e.g. inside of a loop or in a sub-proc that is called
						multiple times.
				Thus, the word choice of "extent" is intentional: the proc merely notes the time gap between the first time the statement
				was seen and the last. Future versions of this proc may offer the ability to display statement "run-lengths", highlighting
				when a given statement was seen, then not seen for the same request, then seen again.';
	RAISERROR(@helpstr,10,1);

		SET @helpstr = N'
#Seen			The number of times a given statement was seen within @start and @end for the request. This can assist the user in
				determining whether a high "Extent(sec)" value represents one instance of a given statement or many return visits to
				the same statement. A large value in "Extent(sec)" but a lower value in #Seen indicates that the same statement was
				re-visited a number of times. The collection interval of AutoWho can be of assistance. It is 15 seconds by default,
				so an "Extent(sec)" of 300 and a "#Seen" value of 20 would indicate that AutoWho had seen this statement every time
				over a 300 second time interval. (15 seconds multiplied by 4 times-per-minute multiplied by 5 minutes).

DB&Object		For header-level (request-level) rows, indicates the context database for the request. If a request''s context database
				changes the first-observed context database is presented. For detail-level rows, represents the T-SQL object name (if any)
				that the statement resides in. This field is blank for ad-hoc SQL.

Cmd				For header-level (request-level) rows, the input buffer of the request. For detail-level rows, the statement text.';
	RAISERROR(@helpstr,10,1);

		SET @helpstr = N'
Statuses		As a request (actually, a task) executes, it alternates between several states: running, runnable, and suspended. This
				field aggregates the various statuses seen for a given statement (no data is presented for header-level rows). The info
				can be used to determine what % of the time a given request is actually executing versus waiting for CPU (runnable) or
				waiting on other SPIDs or environmental factors (suspended).

				Note that suspended task states are divided between suspended-waiting-for-CXPACKET and all other suspended states. This
				enables the user to separate waiting on other sessions/environmental conditions from inter-thread waiting that is somewhat
				inevitable.

NonCXWaits		The various wait types observed for a given statement are aggregated, along with the observed wait times. All non-CXPACKET
				waits are aggregated under this column. Note that because the underlying data is polling-based, the actual wait-times
				encountered by a given statement may vary. This column is blank for header-level (request-level) rows.

CXWaits			All CXPACKET waits and the sub-waits (e.g. PortOpen on Node 4) are aggregated under this column. This column allows the
				user to see which nodes the CXPACKET waits are occurring on, and to some extent to see whether those CXPACKET waits were
				consumer-side or producer-side.

Plan&Info		For header-level (request-level) rows, provides a clickable-XML value that contains various attributes from dm_exec_sessions,
				dm_exec_connections, and dm_exec_requests. For detail-level (statement-level) rows, provides the query plan in XML form.
				This column is only present when either @attr="Y" or @plan="statement".';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
<resource field groups>
				The following resources are presented in groups: # of tasks, query DOP, CPU, task usage of TempDB, session usage of TempDB,
					query memory requested, query memory granted, query memory used, transaction log usage, logical reads, physical
					reads, and writes.

				IMPORTANT: Some of the resources are used at the query level. (E.g. query memory requests/grants occur at each query).
				Other resources are used/tracked at the request level. (E.g. CPU, reads, writes, and tran log usage). All of these
				resources are shown at the query level because it can be helpful to see how much CPU increases during the execution of
				an individual statement inside of a request/batch, even though the CPU counter represents the total usage by the
				request/batch rather than the statement.

				In fact, as of this release, these resource fields are *only* populated at the statement level rather than the
				request level. This may be re-evaluated in a future release.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
				Within each group are the following fields:
					"_First" --> The value of the resource on the first observation of this statement (within this request) by AutoWho.
								For example, if "CPU_First"=2,235, the first time AutoWho observed that statement (within that batch),
								the dm_exec_requests.cpu counter was 2235.

					"Last" --> The value of the resource on the last observation of this statement within the request.

					"FLDelta" --> Last minus First

					"Min" --> The minimum value for the resource observed by AutoWho for this statement (within this request).

					"Max" --> You can figure this one out.

					"MMDelta" --> Max minus Min.

					"Avg" --> The average of all observations of the resource for this statement (within this request).

				Not all resource groups have all of the above fields.
					- For Tasks and DOP, both deltas are omitted since the difference is easy to do manually

					- For the resources that are typically ever-increasing, at least for the same statement (CPU, transaction log,
						logical/physical reads, and writes), average has been omitted as it does not provide clear value.

					- For the query memory groups, "FLDelta" has been omitted since the difference between first and last is not
						terribly meaningful.';
	RAISERROR(@helpstr,10,1);

	SET @helpstr = N'
				In many cases one or more of the resource fields will be blank. This is to eliminate redundant info that crowds the
				results. In these cases, the values of the hidden fields can be inferred. Here is the logic:

				If a resource value stays constant through all observations of a given statement (within its request), the value
				is displayed in the "_First" column and the rest are blank.

				For ever-increasing resources, if first=min and last=max, the "min", "max", and "MMDelta" fields are left blank.
				Normally, we expect the first observation to be the least and the last to be the highest.

				For volatile resources (tempdb, query memory, tasks), as long as the value changed even a bit in any of the observations,
				all columns are displayed.
			';
	RAISERROR(@helpstr,10,1);

exitloc:

	RETURN 0;
END

GO


text:
pdotnet_file dotnet_file_new() {
  pdotnet_file file;
  if ((file = (pdotnet_file)malloc(sizeof(dotnet_file))) != NULL) {
    memset(file, 0, sizeof(dotnet_file));
    return file;
  }
  return NULL;
}

void dotnet_file_release(pdotnet_file File) {
  if (File != NULL) {
    if (File->fd != NULL) {
      fclose(File->fd);
      File->fd = NULL;
    }
    if (File->buffer != NULL) {
      free(File->buffer);
      File->buffer = NULL;
    }
    free(File);
  }
}

PIMAGE_SECTION_HEADER get_first_section(pdotnet_file File) {
  PIMAGE_SECTION_HEADER section = NULL;
  if (!File) return NULL;
  if (File->base != NULL) {
    if (File->is64bits) {
      section = IMAGE_FIRST_SECTION((PIMAGE_NT_HEADERS64)File->ntheader);
    } else {
      section = IMAGE_FIRST_SECTION(File->ntheader);
    }
    return section;
  }
  return NULL;
}

BOOL dotnet_file_open(pdotnet_file File, const char* FilePath) {
  if (!File || !FilePath) return FALSE;
  if ((File->length = get_file_size(FilePath)) > 0) {
    if ((File->buffer = malloc(File->length)) != NULL) {
      if ((File->fd = fopen(FilePath, "rb")) != NULL) {
        if (fread(File->buffer, File->length, 1, File->fd) == 1) {
          if (is_dot_net_assembly(File->buffer, File->length)) {
            File->base = (PIMAGE_DOS_HEADER)File->buffer;
            File->ntheader = MakePtr(PIMAGE_NT_HEADERS, File->base, File->base->e_lfanew);
            File->is64bits = (File->ntheader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
            return TRUE;
          }
        }
      }
    }
  }
  return FALSE;
}

PIMAGE_SECTION_HEADER dotnet_file_get_enclosing_section_header(pdotnet_file File, DWORD Rva) {
  DWORD size;
  unsigned int i;
  PIMAGE_SECTION_HEADER section = NULL;
  if (!File) return NULL;

  if ((section = get_first_section(File)) != NULL) {
    for (i = 0; i < File->ntheader->FileHeader.NumberOfSections; i++, section++) {
      size = section->Misc.VirtualSize;
      if (!size) {
        size = section->SizeOfRawData;
      }

      if ((Rva >= section->VirtualAddress) && (Rva < (section->VirtualAddress + size))) {
        return section;
      }
    }
  }
  return NULL;
}

void* dotnet_file_get_ptr_from_rva(pdotnet_file File, DWORD Rva) {
  int delta;
  PIMAGE_SECTION_HEADER section = dotnet_file_get_enclosing_section_header(File, Rva);
  if (section != NULL) {
    delta = (int)(section->VirtualAddress - section->PointerToRawData);
    return (void*)(((BYTE*)File->base) + Rva - delta);
  }
  return NULL;
}

PIMAGE_SECTION_HEADER dotnet_file_get_section_header(pdotnet_file File, const char* Name) {
  unsigned int i;
  PIMAGE_SECTION_HEADER section = NULL;
  if (!File || !Name) return NULL;
  if ((section = get_first_section(File)) != NULL) {
    for (i = 0; i < File->ntheader->FileHeader.NumberOfSections; i++, section++) {
      if (strncasecmp(Name, (char*)section->Name, IMAGE_SIZEOF_SHORT_NAME) == 0) {
        return section;
      }
    }
  }
  return NULL;
}

PIMAGE_NT_HEADERS64 dotnet_file_get_nt_headers64(pdotnet_file File) {
  if (File != NULL) {
    if (File->is64bits == TRUE) return (PIMAGE_NT_HEADERS64)File->ntheader;
  }
  return NULL;
}

PIMAGE_COR20_HEADER dotnet_file_get_cor20_header(pdotnet_file File) {
  DWORD rva = 0;
  if (File != NULL) {
    if (File->is64bits == TRUE) {
      rva = ((PIMAGE_NT_HEADERS64)File->ntheader)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
    } else {
      rva = File->ntheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
    }
    if (rva != 0) {
      return (PIMAGE_COR20_HEADER)dotnet_file_get_ptr_from_rva(File, rva);
    }
  }
  return NULL;
}


text:
//---------------------------------------------------------------------------
// MenuState.h
//---------------------------------------------------------------------------

/**
@file MenuState.h

Contiene la declaración del estado de menú.

@see Application::CApplicationState
@see Application::CMenuState

@author David Llansó
@date Agosto, 2010
*/

#ifndef __Application_MenuState_H
#define __Application_MenuState_H

#include "ApplicationState.h"

// Predeclaración de clases para ahorrar tiempo de compilación
namespace Application
{
	class CBaseApplication;
}

namespace CEGUI
{
	class EventArgs;
	class Window;
}

namespace Application
{
	/**
	Como su nombre indica, esta clase es la clase del menú
	principal del juego. Es muy sencilla y lo único que hace es cargar
	un layout de CEGUI al inicio y activarlo y desactivarlo cuando
	se activa o desactiva el estado (haciéndo visible/invisible también
	el puntero del ratón). También asocia los eventos de los botones
	del menú a las funciones C++ que se deben invocar cuando los botones
	son pulsados.
	<p>
	Este estado es CEGUI dependiente, lo cual no es deseable, la aplicación
	debería ser independiente de las tecnologías usadas.

	@ingroup applicationGroup

	@author David Llansó
	@date Agosto, 2010
	*/
	class CMenuState : public CApplicationState
	{
	public:
		/**
		Constructor de la clase
		*/
		CMenuState(CBaseApplication *app);

		/**
		Destructor
		*/
		virtual ~CMenuState();

		/**
		Función llamada cuando se crea el estado (se "engancha" en la
		aplicación, para que inicialice sus elementos.

		@return true si todo fue bien.
		*/
		virtual bool init();

		/**
		Función llamada cuando se elimina ("desengancha") el
		estado de la aplicación.
		*/
		virtual void release();

		virtual bool resume();

		virtual void pause();

		/**
		Función llamada por la aplicación cuando se activa
		el estado.
		*/
		virtual void activate();

		/**
		Función llamada por la aplicación cuando se desactiva
		el estado.
		*/
		virtual void deactivate();

		/**
		Función llamada por la aplicación para que se ejecute
		la funcionalidad del estado.

		@param msecs Número de milisegundos transcurridos desde
		la última llamada (o desde la áctivación del estado, en caso
		de ser la primera vez...).
		*/
		virtual void tick(unsigned int msecs);

		// Métodos de CKeyboardListener

		/**
		Método que será invocado siempre que se pulse una tecla.
		Será la aplicación quién llame a este método cuando el
		estado esté activo. Esta clase NO se registra en el
		InputManager sino que es la aplicación quien lo hace y
		delega en los estados.

		@param key Código de la tecla pulsada.
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		virtual bool keyPressed(GUI::TKey key);

		/**
		Método que será invocado siempre que se termine la pulsación
		de una tecla. Será la aplicación quién llame a este método
		cuando el estado esté activo. Esta clase NO se registra en
		el InputManager sino que es la aplicación quien lo hace y
		delega en los estados.

		@param key Código de la tecla pulsada.
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		virtual bool keyReleased(GUI::TKey key);

		// Métodos de CMouseListener

		/**
		Método que será invocado siempre que se mueva el ratón. La
		aplicación avisa de este evento al estado actual.

		@param mouseState Estado del ratón cuando se lanza el evento.
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		virtual bool mouseMoved(const GUI::CMouseState &mouseState);

		/**
		Método que será invocado siempre que se pulse un botón. La
		aplicación avisa de este evento al estado actual.

		@param mouseState Estado del ratón cuando se lanza el evento.
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		virtual bool mousePressed(const GUI::CMouseState &mouseState);

		/**
		Método que será invocado siempre que se termine la pulsación
		de un botón. La aplicación avisa de este evento al estado
		actual.

		@param mouseState Estado del ratón cuando se lanza el evento.
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		virtual bool mouseReleased(const GUI::CMouseState &mouseState);

		/***************************************************************
		Métodos de CJoystickListener
		***************************************************************/
		/**
		Método que será invocado siempre que se use la cruceta del joystick

		@param pov Estado de la cruceta del joystick CENTERED significa que no se esta usando
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		bool povMoved(GUI::Joystick::POV pov);

		/**
		Método que será invocado siempre que se use los sticks o gatillos del mando (los ejes)

		@param axis identificador del eje movido
		@param abs localización absoluta del stick en ese isntante
		@param movement movimiento relativo en el eje [-1, 1] que hay en ese instante
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		bool axisMoved(GUI::Joystick::Axis axis, float abs, float movement);

		/**
		Método que será invocado siempre que se pulse un boton del joystick

		@param button Identificador del boton pulsado
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		bool buttonPressed(GUI::Joystick::Button button);

		/**
		Método que será invocado siempre que se deje de pulsar un boton del joystick

		@param button Identificador del boton liberado
		@return true si el evento ha sido procesado. En este caso
		el gestor no llamará a otros listeners.
		*/
		bool buttonReleased(GUI::Joystick::Button button);

	private:

		/**
		Ventana CEGUI que muestra el menú.
		*/
		CEGUI::Window* _menuWindow;

		/**
		Función que se quiere realizar cuando se pulse el botón start.
		Simplemente cambia al estado de juego.
		*/
		bool startReleased(const CEGUI::EventArgs& e);

		/**
		Función que se quiere realizar cuando se pulse el botón exit.
		Simplemente termina la aplicación.
		*/
		bool exitReleased(const CEGUI::EventArgs& e);

	}; // CMenuState

} // namespace Application

#endif //  __Application_MenuState_H


text:
require 'fastlane/actions/actions_helper'
require 'forwardable'

module Fastlane
  class Action
    AVAILABLE_CATEGORIES = [
      :testing,
      :building,
      :screenshots,
      :project,
      :code_signing,
      :documentation,
      :beta,
      :push,
      :production,
      :source_control,
      :notifications,
      :misc,
      :deprecated # This should be the last item
    ]

    RETURN_TYPES = [
      :string,
      :array_of_strings,
      :hash_of_strings,
      :bool,
      :int
    ]

    class << self
      attr_accessor :runner

      extend Forwardable

      # to allow a simple `sh` in the custom actions
      def_delegator Actions, :sh_control_output, :sh
    end

    def self.run(params)
    end

    # Implement in subclasses
    def self.description
      "No description provided".red
    end

    def self.details
      nil # this is your change to provide a more detailed description of this action
    end

    def self.available_options
      # [
      #   FastlaneCore::ConfigItem.new(key: :ipa_path,
      #                                env_name: "CRASHLYTICS_IPA_PATH",
      #                                description: "Value Description")
      # ]
      nil
    end

    def self.output
      # Return the keys you provide on the shared area
      # [
      #   ['IPA_OUTPUT_PATH', 'The path to the newly generated ipa file']
      # ]
      nil
    end

    def self.return_type
      # Describes what type of data is expected to be returned, see RETURN_TYPES
      nil
    end

    def self.return_value
      # Describes what this method returns
      nil
    end

    def self.sample_return_value
      # Very optional
      # You can return a sample return value, that might be returned by the actual action
      # This is currently only used when generating the documentation and running its tests
      nil
    end

    def self.author
      nil
    end

    def self.authors
      nil
    end

    def self.is_supported?(platform)
      # you can do things like
      #  true
      #
      #  platform == :ios
      #
      #  [:ios, :mac].include?(platform)
      #
      UI.crash!("Implementing `is_supported?` for all actions is mandatory. Please update #{self}")
    end

    # Returns an array of string of sample usage of this action
    def self.example_code
      nil
    end

    # Is printed out in the Steps: output in the terminal
    # Return nil if you don't want any logging in the terminal/JUnit Report
    def self.step_text
      self.action_name
    end

    # Documentation category, available values defined in AVAILABLE_CATEGORIES
    def self.category
      :undefined
    end

    # instead of "AddGitAction", this will return "add_git" to print it to the user
    def self.action_name
      self.name.split('::').last.gsub('Action', '').fastlane_underscore
    end

    def self.lane_context
      Actions.lane_context
    end

    # Allows the user to call an action from an action
    def self.method_missing(method_sym, *arguments, &_block)
      UI.error("Unknown method '#{method_sym}'")
      UI.user_error!("To call another action from an action use `other_action.#{method_sym}` instead")
    end

    # When shelling out from the actoin, should we use `bundle exec`?
    def self.shell_out_should_use_bundle_exec?
      return File.exist?('Gemfile') && !Helper.contained_fastlane?
    end

    # Return a new instance of the OtherAction action
    # We need to do this, since it has to have access to
    # the runner object
    def self.other_action
      return OtherAction.new(self.runner)
    end

    # Describes how the user should handle deprecated an action if its deprecated
    # Returns a string (or nil)
    def self.deprecated_notes
      nil
    end
  end
end


text:
{{<govuk_template}}

{{$head}}
  {{>includes/elements_head}}
  {{>includes/elements_scripts}}
{{/head}}

{{$propositionHeader}}
  {{>includes/propositional_navigation4}}
{{/propositionHeader}}

{{$headerClass}}with-proposition{{/headerClass}}

{{$content}}

  {{>includes/phase_banner}}

  <form id="mmed-form" action="medical-form" method="get" class="form inline">

Do you understand the need to test your blood glucose/sugar at times relevant to driving ?

        Times relevant to driving means not more than 2 hours before the start of the journey and every 2 hours while driving

          <legend>

              Select an option

          </legend>

            <input id="q7-a1" type="radio" name="q7-answer" value="Y">Yes

            <input id="q7-a2" type="radio" name="q7-answer" value="N">No

      <input id="continue" name="continue" type="button" class="button" value="Continue" onclick="validate();">

  </form>

{{/content}}

{{$bodyEnd}}
{{/bodyEnd}}

{{/govuk_template}}


text:
!!! note "Coming Soon"
    A feature to form a distributed cluster with multiple Concourse nodes will be **released in version 0.6**.


text:
package com.deleidos.rtws.master.core.net.shutdown;

import com.deleidos.rtws.master.core.beans.ShutdownHook;

public class MockShutdown implements ShutdownHook {
	public void shutdown(String host) {
		// Ignore.
	}
}


text:
package another

import "hash"

var (
	H = hash.Hash
)