<commit_before>app.controller(
    'MainController',
    [
        '$scope',
        function ($scope) {
            // placeholder
        }
    ]
);

app.controller(
    'ImageSetListController',
    [
        '$scope',
        'ImageSet',
        'Species',
        'Magnification',
        'DevelopmentStage',
        'Probe',
        function ($scope, ImageSet, Species, Magnification, DevelopmentStage, Probe) {
            $scope.species = [];
            $scope.magnifications = [];
            $scope.development_stages = [];
            $scope.probes = [];
            $scope.image_sets = [];
            $scope.retrieving_data = false;

            var species = Species.query();
            species.$promise.then(function (data) {
                data.forEach(function (s) {
                    $scope.species.push(
                        {
                            'name': s,
                            'query': false
                        }
                    )
                });
            });

            var magnifications = Magnification.query();
            magnifications.$promise.then(function (data) {
                data.forEach(function (m) {
                    $scope.magnifications.push(
                        {
                            'name': m,
                            'query': false
                        }
                    )
                });
            });

            var development_stages = DevelopmentStage.query();
            development_stages.$promise.then(function (data) {
                data.forEach(function (d) {
                    $scope.development_stages.push(
                        {
                            'name': d,
                            'query': false
                        }
                    )
                });
            });

            var probes = Probe.query();
            probes.$promise.then(function (data) {
                data.forEach(function (p) {
                    $scope.probes.push(
                        {
                            'id': p.id,
                            'name': p.label,
                            'query': false
                        }
                    )
                });
            });

            $scope.filter_image_sets = function () {
                $scope.retrieving_data = true;
                $scope.image_sets = [];

                var species_filters = [];
                $scope.species.forEach(function (s) {
                    if (s.query) {
                        species_filters.push(s.name);
                    }
                });

                var mag_filters = [];
                $scope.magnifications.forEach(function (m) {
                    if (m.query) {
                        mag_filters.push(m.name);
                    }
                });

                var dev_stage_filters = [];
                $scope.development_stages.forEach(function (d) {
                    if (d.query) {
                        dev_stage_filters.push(d.name);
                    }
                });

                var probe_filters = [];
                $scope.probes.forEach(function (p) {
                    if (p.query) {
                        probe_filters.push(p.id);
                    }
                });

                $scope.image_sets = ImageSet.query(
                    {
                        'species': species_filters,
                        'magnification': mag_filters,
                        'development_stage': dev_stage_filters,
                        'probe': probe_filters
                    }
                );

                $scope.image_sets.$promise.then(function (data) {
                    $scope.retrieving_data = false;
                }, function (error) {
                    $scope.retrieving_data = false;
                });
            };
        }
    ]
);

app.controller(
    'ImageSetDetailController',
    [
        '$scope',
        '$q',
        '$routeParams',
        '$window',
        'ImageSet',
        'Image',
        'Subregion',
        'AnatomyProbeMap',
        'Classify',
        'TrainModel',
        function ($scope, $q, $routeParams, $window, ImageSet, Image,
                  Subregion, AnatomyProbeMap, Classify, TrainModel) {
            $scope.images = [];
            $scope.selected_image = null;
            $scope.selected_classification = null;
            $scope.mode = 'train';  // can be 'train', or 'classify'

            // drw-poly vars
            $scope.enabled = false;
            $scope.regions = {
                'svg': []
            };
            $scope.poly_height = 997;
            $scope.poly_width = 997;

            $scope.image_set = ImageSet.get({'image_set_id': $routeParams.image_set_id});

            $scope.image_set.$promise.then(function(data) {
                $scope.images = Image.query({'image_set': data.id});
                var anatomy_promises = [];

                data.probes.forEach(function(probe) {
                    anatomy_promises.push(AnatomyProbeMap.query(
                        {
                            'probe': probe.probe
                        }).$promise
                    );
                });

                $q.all(anatomy_promises).then(function(results) {
                    $scope.anatomies = [];

                    results.forEach(function(anatomy_probe_map) {
                        anatomy_probe_map.forEach(function(anatomy_probe) {
                            $scope.anatomies.push(
                                {
                                    'id': anatomy_probe.anatomy,
                                    'name': anatomy_probe.anatomy_name
                                }
                            );
                        });
                    });
                }, function(error) {
                    // Error callback where reason is the value of the first rejected promise
                    $window.alert(JSON.stringify(error, null, 4));
                });
            });

            $scope.image_selected = function(img) {
                $scope.selected_image = img;
                if (!img.image_orig_sha1) {
                    var save_response = Image.get(
                        {
                            'id': img.id
                        },
                        {}
                    );

                    save_response.$promise.then(function(data) {
                        $scope.selected_image = data;
                        $scope.select_classification($scope.selected_classification);
                    }, function (error) {
                        // TODO: figure out how to turn retrieving off for experiment
                        $window.alert(JSON.stringify(error, null, 4))
                    });
                } else {
                    $scope.select_classification($scope.selected_classification);
                }
            };

            $scope.select_classification = function(classification) {
                $scope.selected_classification = classification;

                if ($scope.selected_classification === null) {
                    return false;
                }

                var existing_sub_regions = Subregion.query(
                    {
                        'image': $scope.selected_image.id,
                        'anatomy': classification.id
                    }
                );

                var new_regions = [];
                var new_region_points =[];

                existing_sub_regions.$promise.then(function(data) {
                    data.forEach(function(region) {
                        // empty array for our new region
                        new_region_points = [];

                        region.points.forEach(function(p) {
                            new_region_points.push(
                                [
                                    p.x,
                                    p.y
                                ]
                            );
                        });

                        new_regions.push(new_region_points);
                    });

                    if (new_regions.length > 0) {
                        $scope.regions.svg = new_regions;
                        $scope.enabled = false;
                    } else {
                        $scope.regions.svg = [];
                        $scope.enabled = true;
                    }
                });
            };

            $scope.set_mode = function (mode) {
                $scope.mode = mode;
                $scope.regions.svg = [];

                if (mode === 'classify') {
                    $scope.enabled = true;
                } else if (mode === 'train') {
                    if ($scope.selected_classification !== null) {
                        $scope.select_classification($scope.selected_classification);
                    }
                } else {
                    $scope.enabled = false;
                }
            };

            $scope.post_regions = function () {
                // will post all the regions for this classification in bulk,
                // since there cannot be any existing regions for the image / class combo.
                var regions = [];

                if ($scope.regions.svg.length === 0) {
                    $window.alert('There are no regions drawn, please segment something first.');
                } else if ($scope.selected_classification === null) {
                    $window.alert('There is no label associated with the active polygon, please choose a label first.');
                } else {
                    $scope.regions.svg.forEach(function(p) {
                        var region = {};
                        var region_points = [];

                        //Get points
                        for (var i = 0; i < p.length; i++) {
                            region_points.push(
                                {
                                    "x": p[i][0],
                                    "y": p[i][1],
                                    "order": i
                                }
                            );
                        }

                        region.anatomy = $scope.selected_classification.id;
                        region.image = $scope.selected_image.id;
                        region.points = region_points;

                        regions.push(region)
                    });

                    // How to get results of post to conditionally get ready for next
                    var post_region_response = Subregion.save(regions);

                    var new_regions = [];
                    var new_region_points =[];

                    post_region_response.$promise.then(function(data) {
                        data.forEach(function(region) {
                            // empty array for our new region
                            new_region_points = [];

                            region.points.forEach(function(p) {
                                new_region_points.push(
                                    [
                                        p.x,
                                        p.y
                                    ]
                                );
                            });

                            new_regions.push(new_region_points);
                        });

                        if (new_regions.length > 0) {
                            $scope.regions.svg = new_regions;
                            $scope.enabled = false;
                        }
                    }, function (error) {
                        $window.alert(JSON.stringify(error.data, null, 4))
                    });
                }
            };

            $scope.train_model = function () {
                TrainModel.save(
                    {
                        'imageset': $scope.image_set.id
                    }
                );
            };

            $scope.classify_region = function () {
                var classify_promises = [];

                $scope.regions.svg.forEach(function (region) {
                    var payload = {};
                    var points = [];

                    //Get points
                    for (var i = 0; i < region.length; i++) {
                        points.push(
                            {
                                "x": region[i][0],
                                "y": region[i][1],
                                "order": i
                            }
                        );
                    }
                    payload.image_id = $scope.selected_image.id;
                    payload.points = points;

                    // How to get results of post to conditionally get ready for next
                    classify_promises.push(Classify.save(payload).$promise);
                });

                $q.all(classify_promises).then(function (results) {
                    console.log(results);
                    $window.alert(JSON.stringify(results, null, 4));
                });
            }
        }
    ]
);
<commit_msg>front-end validation to disable drawing regions for trained image set<commit_after>app.controller(
    'MainController',
    [
        '$scope',
        function ($scope) {
            // placeholder
        }
    ]
);

app.controller(
    'ImageSetListController',
    [
        '$scope',
        'ImageSet',
        'Species',
        'Magnification',
        'DevelopmentStage',
        'Probe',
        function ($scope, ImageSet, Species, Magnification, DevelopmentStage, Probe) {
            $scope.species = [];
            $scope.magnifications = [];
            $scope.development_stages = [];
            $scope.probes = [];
            $scope.image_sets = [];
            $scope.retrieving_data = false;

            var species = Species.query();
            species.$promise.then(function (data) {
                data.forEach(function (s) {
                    $scope.species.push(
                        {
                            'name': s,
                            'query': false
                        }
                    )
                });
            });

            var magnifications = Magnification.query();
            magnifications.$promise.then(function (data) {
                data.forEach(function (m) {
                    $scope.magnifications.push(
                        {
                            'name': m,
                            'query': false
                        }
                    )
                });
            });

            var development_stages = DevelopmentStage.query();
            development_stages.$promise.then(function (data) {
                data.forEach(function (d) {
                    $scope.development_stages.push(
                        {
                            'name': d,
                            'query': false
                        }
                    )
                });
            });

            var probes = Probe.query();
            probes.$promise.then(function (data) {
                data.forEach(function (p) {
                    $scope.probes.push(
                        {
                            'id': p.id,
                            'name': p.label,
                            'query': false
                        }
                    )
                });
            });

            $scope.filter_image_sets = function () {
                $scope.retrieving_data = true;
                $scope.image_sets = [];

                var species_filters = [];
                $scope.species.forEach(function (s) {
                    if (s.query) {
                        species_filters.push(s.name);
                    }
                });

                var mag_filters = [];
                $scope.magnifications.forEach(function (m) {
                    if (m.query) {
                        mag_filters.push(m.name);
                    }
                });

                var dev_stage_filters = [];
                $scope.development_stages.forEach(function (d) {
                    if (d.query) {
                        dev_stage_filters.push(d.name);
                    }
                });

                var probe_filters = [];
                $scope.probes.forEach(function (p) {
                    if (p.query) {
                        probe_filters.push(p.id);
                    }
                });

                $scope.image_sets = ImageSet.query(
                    {
                        'species': species_filters,
                        'magnification': mag_filters,
                        'development_stage': dev_stage_filters,
                        'probe': probe_filters
                    }
                );

                $scope.image_sets.$promise.then(function (data) {
                    $scope.retrieving_data = false;
                }, function (error) {
                    $scope.retrieving_data = false;
                });
            };
        }
    ]
);

app.controller(
    'ImageSetDetailController',
    [
        '$scope',
        '$q',
        '$routeParams',
        '$window',
        'ImageSet',
        'Image',
        'Subregion',
        'AnatomyProbeMap',
        'Classify',
        'TrainModel',
        function ($scope, $q, $routeParams, $window, ImageSet, Image,
                  Subregion, AnatomyProbeMap, Classify, TrainModel) {
            $scope.images = [];
            $scope.selected_image = null;
            $scope.selected_classification = null;
            $scope.mode = 'train';  // can be 'train', or 'classify'

            // drw-poly vars
            $scope.enabled = false;
            $scope.regions = {
                'svg': []
            };
            $scope.poly_height = 997;
            $scope.poly_width = 997;

            $scope.image_set = ImageSet.get({'image_set_id': $routeParams.image_set_id});

            $scope.image_set.$promise.then(function(data) {
                $scope.images = Image.query({'image_set': data.id});
                var anatomy_promises = [];

                data.probes.forEach(function(probe) {
                    anatomy_promises.push(AnatomyProbeMap.query(
                        {
                            'probe': probe.probe
                        }).$promise
                    );
                });

                $q.all(anatomy_promises).then(function(results) {
                    $scope.anatomies = [];

                    results.forEach(function(anatomy_probe_map) {
                        anatomy_probe_map.forEach(function(anatomy_probe) {
                            $scope.anatomies.push(
                                {
                                    'id': anatomy_probe.anatomy,
                                    'name': anatomy_probe.anatomy_name
                                }
                            );
                        });
                    });
                }, function(error) {
                    // Error callback where reason is the value of the first rejected promise
                    $window.alert(JSON.stringify(error, null, 4));
                });
            });

            $scope.image_selected = function(img) {
                $scope.selected_image = img;
                if (!img.image_orig_sha1) {
                    var save_response = Image.get(
                        {
                            'id': img.id
                        },
                        {}
                    );

                    save_response.$promise.then(function(data) {
                        $scope.selected_image = data;
                        $scope.select_classification($scope.selected_classification);
                    }, function (error) {
                        // TODO: figure out how to turn retrieving off for experiment
                        $window.alert(JSON.stringify(error, null, 4))
                    });
                } else {
                    $scope.select_classification($scope.selected_classification);
                }
            };

            $scope.select_classification = function(classification) {
                $scope.selected_classification = classification;

                if ($scope.selected_classification === null) {
                    return false;
                }

                var existing_sub_regions = Subregion.query(
                    {
                        'image': $scope.selected_image.id,
                        'anatomy': classification.id
                    }
                );

                var new_regions = [];
                var new_region_points =[];

                existing_sub_regions.$promise.then(function(data) {
                    data.forEach(function(region) {
                        // empty array for our new region
                        new_region_points = [];

                        region.points.forEach(function(p) {
                            new_region_points.push(
                                [
                                    p.x,
                                    p.y
                                ]
                            );
                        });

                        new_regions.push(new_region_points);
                    });

                    if (new_regions.length > 0 || $scope.image_set.trainedmodel !== null) {
                        $scope.regions.svg = new_regions;
                        $scope.enabled = false;
                    } else {
                        $scope.regions.svg = [];
                        $scope.enabled = true;
                    }
                });
            };

            $scope.set_mode = function (mode) {
                $scope.mode = mode;
                $scope.regions.svg = [];

                if (mode === 'classify') {
                    $scope.enabled = true;
                } else if (mode === 'train') {
                    if ($scope.selected_classification !== null) {
                        $scope.select_classification($scope.selected_classification);
                    }
                } else {
                    $scope.enabled = false;
                }
            };

            $scope.post_regions = function () {
                // will post all the regions for this classification in bulk,
                // since there cannot be any existing regions for the image / class combo.
                var regions = [];

                if ($scope.regions.svg.length === 0) {
                    $window.alert('There are no regions drawn, please segment something first.');
                } else if ($scope.selected_classification === null) {
                    $window.alert('There is no label associated with the active polygon, please choose a label first.');
                } else {
                    $scope.regions.svg.forEach(function(p) {
                        var region = {};
                        var region_points = [];

                        //Get points
                        for (var i = 0; i < p.length; i++) {
                            region_points.push(
                                {
                                    "x": p[i][0],
                                    "y": p[i][1],
                                    "order": i
                                }
                            );
                        }

                        region.anatomy = $scope.selected_classification.id;
                        region.image = $scope.selected_image.id;
                        region.points = region_points;

                        regions.push(region)
                    });

                    // How to get results of post to conditionally get ready for next
                    var post_region_response = Subregion.save(regions);

                    var new_regions = [];
                    var new_region_points =[];

                    post_region_response.$promise.then(function(data) {
                        data.forEach(function(region) {
                            // empty array for our new region
                            new_region_points = [];

                            region.points.forEach(function(p) {
                                new_region_points.push(
                                    [
                                        p.x,
                                        p.y
                                    ]
                                );
                            });

                            new_regions.push(new_region_points);
                        });

                        if (new_regions.length > 0) {
                            $scope.regions.svg = new_regions;
                            $scope.enabled = false;
                        }
                    }, function (error) {
                        $window.alert(JSON.stringify(error.data, null, 4))
                    });
                }
            };

            $scope.train_model = function () {
                TrainModel.save(
                    {
                        'imageset': $scope.image_set.id
                    }
                );
            };

            $scope.classify_region = function () {
                var classify_promises = [];

                $scope.regions.svg.forEach(function (region) {
                    var payload = {};
                    var points = [];

                    //Get points
                    for (var i = 0; i < region.length; i++) {
                        points.push(
                            {
                                "x": region[i][0],
                                "y": region[i][1],
                                "order": i
                            }
                        );
                    }
                    payload.image_id = $scope.selected_image.id;
                    payload.points = points;

                    // How to get results of post to conditionally get ready for next
                    classify_promises.push(Classify.save(payload).$promise);
                });

                $q.all(classify_promises).then(function (results) {
                    console.log(results);
                    $window.alert(JSON.stringify(results, null, 4));
                });
            }
        }
    ]
);
<|endoftext|>


<commit_before>// @flow

import { css } from 'glamor';
import React, { Component } from 'react';
import {
  envPresetDefaults,
  pluginConfigs,
  presetPluginConfigs
} from './PluginConfig';
import PresetLoadingAnimation from './PresetLoadingAnimation';
import Svg from './Svg';
import { colors, media } from './styles';

import type {
  EnvConfig,
  PluginConfig,
  PluginState,
  PluginStateMap
} from './types';

type ToggleEnvPresetSetting = (name: string, value: any) => void;
type ToggleExpanded = (isExpanded: boolean) => void;
type ToggleSetting = (name: string, isEnabled: boolean) => void;

type Props = {
  builtIns: boolean,
  className: string,
  debugEnvPreset: boolean,
  envConfig: EnvConfig,
  envPresetState: PluginState,
  isExpanded: boolean,
  lineWrap: boolean,
  onEnvPresetSettingChange: ToggleEnvPresetSetting,
  onIsExpandedChange: ToggleExpanded,
  onSettingChange: ToggleSetting,
  pluginState: PluginStateMap,
  presetState: PluginStateMap,
  runtimePolyfillConfig: PluginConfig,
  runtimePolyfillState: PluginState
};

const ReplOptions = (props: Props) =>
  <div className={`${styles.wrapper} ${props.className}`}>
    {props.isExpanded
      ? <ExpandedContainer {...props} />
      : <CollapsedContainer {...props} />}

;

export default ReplOptions;

// The choice of Component over PureComponent is intentional here.
// It simplifies the re-use of PluginState objects,
// Without requiring gratuitous use of Object-spread.
class ExpandedContainer extends Component {
  props: Props;

  static defaultProps = {
    className: ''
  };

  render() {
    const {
      builtIns,
      debugEnvPreset,
      envConfig,
      envPresetState,
      lineWrap,
      onIsExpandedChange,
      onSettingChange,
      pluginState,
      presetState,
      runtimePolyfillConfig,
      runtimePolyfillState
    } = this.props;

    const disableEnvSettings =
      !envPresetState.isLoaded || !envConfig.isEnvPresetEnabled;

    return (

Settings

          <PluginToggle
            config={runtimePolyfillConfig}
            label="Evaluate"
            onSettingChange={onSettingChange}
            state={runtimePolyfillState}
          />

            <input
              checked={lineWrap}
              onChange={this._onLineWrappingChange}
              className={styles.inputCheckboxLeft}
              type="checkbox"
            />
            Line Wrap

          {pluginConfigs.map(config =>
            <PluginToggle
              config={config}
              key={config.package}
              onSettingChange={onSettingChange}
              state={pluginState[config.package]}
            />
          )}

Presets

          {presetPluginConfigs.map(config =>
            <PluginToggle
              config={config}
              key={config.package}
              onSettingChange={onSettingChange}
              state={presetState[config.package]}
            />
          )}

        <div className={`${styles.section} ${styles.sectionEnv}`}>
          <label
            className={`${styles.sectionHeader} ${styles.sectionEnvHeader}`}
          >
            {envPresetState.isLoading
              ? <PresetLoadingAnimation />
              : 'Env Preset'}

            <input
              checked={envConfig.isEnvPresetEnabled}
              type="checkbox"
              onChange={this._onEnvPresetEnabledChange}
            />

            <label
              className={`${styles.envPresetColumnLabel} ${styles.highlight}`}
            >
              Browser

            <textarea
              disabled={disableEnvSettings}
              className={styles.envPresetInput}
              onChange={this._onBrowsersChange}
              placeholder={envPresetDefaults.browsers.placeholder}
              value={envConfig.browsers}
            />

            <span className={`${styles.envPresetLabel} ${styles.highlight}`}>
              Electron

            <input
              className={`${styles.envPresetNumber} ${styles.envPresetInput}`}
              disabled={
                !envPresetState.isLoaded ||
                !envConfig.isEnvPresetEnabled ||
                !envConfig.isElectronEnabled
              }
              type="number"
              min={envPresetDefaults.electron.min}
              max={999}
              step={envPresetDefaults.electron.step}
              onChange={this._onElectronChange}
              value={envConfig.electron}
            />
            <input
              checked={envConfig.isElectronEnabled}
              className={styles.envPresetCheckbox}
              disabled={disableEnvSettings}
              onChange={this._onIsElectronEnabledChange}
              type="checkbox"
            />

            <span className={`${styles.envPresetLabel} ${styles.highlight}`}>
              Node

            <input
              className={`${styles.envPresetNumber} ${styles.envPresetInput}`}
              disabled={
                !envPresetState.isLoaded ||
                !envConfig.isEnvPresetEnabled ||
                !envConfig.isNodeEnabled
              }
              type="number"
              min={envPresetDefaults.node.min}
              max={999}
              step={envPresetDefaults.node.step}
              onChange={this._onNodeChange}
              value={envConfig.node}
            />
            <input
              checked={envConfig.isNodeEnabled}
              className={styles.envPresetCheckbox}
              disabled={disableEnvSettings}
              onChange={this._onIsNodeEnabledChange}
              type="checkbox"
            />

            <input
              checked={builtIns}
              className={styles.inputCheckboxLeft}
              disabled={runtimePolyfillState.isEnabled || disableEnvSettings}
              onChange={this._onBuiltInsChange}
              type="checkbox"
            />
            Built-ins

            <input
              checked={debugEnvPreset}
              className={styles.inputCheckboxLeft}
              disabled={disableEnvSettings}
              onChange={this._onDebugChange}
              type="checkbox"
            />
            Debug

        <div
          className={`${styles.closeButton} ${nestedCloseButton}`}
          onClick={() => onIsExpandedChange(false)}
        >
          <Svg
            className={styles.closeButtonIcon}
            path="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z"
          />

    );
  }

  _onBrowsersChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('browsers', event.target.value);
  };

  _onEnvPresetEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'isEnvPresetEnabled',
      event.target.checked
    );
  };

  _onBuiltInsChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('builtIns', event.target.checked);
  };

  _onDebugChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('debugEnvPreset', event.target.checked);
  };

  _onElectronChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'electron',
      parseFloat(event.target.value)
    );
  };

  _onIsElectronEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'isElectronEnabled',
      event.target.checked
    );
  };

  _onIsNodeEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('isNodeEnabled', event.target.checked);
  };

  _onLineWrappingChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('lineWrap', event.target.checked);
  };

  _onNodeChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('node', parseFloat(event.target.value));
  };
}

const CollapsedContainer = ({ onIsExpandedChange }) =>

    <div
      className={`${styles.closeButton} ${nestedCloseButton}`}
      onClick={() => onIsExpandedChange(true)}
    >
      <Svg
        className={styles.closeButtonIcon}
        path="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"
      />

;

type PluginToggleProps = {
  config: PluginConfig,
  label?: string,
  state: PluginState,
  onSettingChange: ToggleSetting
};

const PluginToggle = ({
  config,
  label,
  state,
  onSettingChange
}: PluginToggleProps) =>

    <input
      checked={state.isEnabled && !state.didError}
      className={styles.inputCheckboxLeft}
      disabled={state.isLoading || state.didError}
      onChange={(event: SyntheticInputEvent) =>
        onSettingChange(config.package, event.target.checked)}
      type="checkbox"
    />
    {state.isLoading ? <PresetLoadingAnimation /> : label || config.label}
  ;

// Defined separately from styles due to nesting.
const nestedCloseButton = css({});

const styles = {
  wrapper: css({
    position: 'relative',
    overflow: 'visible',
    zIndex: 6,
    backgroundColor: colors.inverseBackground,
    color: colors.inverseForegroundLight,
    transition: 'transform 0.25s ease-in-out',

    [media.large]: {
      height: '100%' // Safari fix for scrolling/overflow
    }
  }),
  collapsedContainer: css({
    backgroundColor: colors.inverseBackground,

    [media.large]: {
      width: '0.5rem',
      height: '100%'
    },

    [media.mediumAndDown]: {
      height: '0.5rem',
      width: '100%'
    },

    [`& .${nestedCloseButton}`]: {
      [media.mediumAndDown]: {
        transition: 'top 0.25s ease-in-out',
        top: '-0.5rem'
      },

      [media.large]: {
        transition: 'left 0.25s ease-in-out',
        left: '-0.5rem'
      }
    },

    '&:hover': {
      [`& .${nestedCloseButton}`]: {
        [media.mediumAndDown]: {
          top: 0
        },

        [media.large]: {
          left: 0
        }
      }
    }
  }),
  expandedContainer: css({
    minWidth: '150px',
    display: 'flex',
    overflow: 'auto',
    boxSshadow:
      'rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.24) 0px 1px 4px',

    [media.large]: {
      flexDirection: 'column',
      height: '100%',

      [`& .${nestedCloseButton}`]: {
        right: '-1.5rem'
      }
    },

    [media.mediumAndDown]: {
      flexDirection: 'row',
      flexWrap: 'wrap',
      overflow: 'auto',

      [`& .${nestedCloseButton}`]: {
        bottom: '-1.5rem'
      }
    }
  }),
  closeButton: css({
    position: 'absolute',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    cursor: 'pointer',
    backgroundColor: colors.inverseBackground,
    color: colors.inverseForegroundLight,

    [media.large]: {
      height: '4rem',
      width: '2rem',
      top: 'calc(50% - 2rem)',
      borderTopRightRadius: '4rem',
      borderBottomRightRadius: '4rem'
    },

    [media.mediumAndDown]: {
      height: '2rem',
      width: '4rem',
      left: 'calc(50% - 2rem)',
      borderBottomLeftRadius: '4rem',
      borderBottomRightRadius: '4rem'
    }
  }),
  closeButtonIcon: css({
    width: '1.5rem',
    height: '1.5rem',

    [media.mediumAndDown]: {
      transform: 'rotate(90deg)'
    }
  }),
  section: css({
    display: 'flex',
    flexDirection: 'column',
    overflow: 'auto',
    flex: '0 0 auto',
    maxHeight: '100%',
    padding: '1rem',
    zIndex: 7,

    [media.mediumAndDown]: {
      flex: '1 0 100px',
      maxHeight: '100%',
      overflow: 'auto'
    }
  }),
  sectionEnv: css({
    borderBottom: 'none',
    borderRight: 'none',

    [media.mediumAndDown]: {
      flex: '1 0 150px'
    }
  }),
  inputCheckboxLeft: css({
    marginRight: '0.5rem'
  }),
  highlight: css({
    textTransform: 'uppercase',
    fontSize: '0.8rem',
    fontWeight: 'bold',
    color: colors.inverseForeground
  }),
  sectionHeader: css({
    flex: '0 0 2rem',
    fontSize: '1.25rem',
    fontWeight: 'bold',
    color: colors.inverseForegroundLight
  }),
  sectionEnvHeader: css({
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between'
  }),
  settingsLabel: css({
    flex: '0 0 2rem',
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    margin: '0 -1rem',
    padding: '0 1rem',

    '&:hover': {
      backgroundColor: colors.inverseBackgroundDark
    }
  }),
  envPresetColumn: css({
    display: 'flex',
    flexDirection: 'column',
    margin: '0.5rem 0',
    flex: '0 0 auto'
  }),
  envPresetColumnLabel: css({
    margin: '0.5rem 0'
  }),
  envPresetRow: css({
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    flex: '0 0 auto',
    margin: '0.5rem 0'
  }),
  envPresetNumber: css({
    flex: '0 0 2.5rem',
    maxWidth: '2.5rem'
  }),
  envPresetCheckbox: css({
    flex: '0 0 auto',
    marginLeft: '0.5rem'
  }),
  envPresetLabel: css({
    flex: 1
  }),
  envPresetInput: css({
    WebkitAppearance: 'none',
    border: 'none',
    borderRadius: '0.125rem',

    '&:disabled': {
      opacity: 0.5
    }
  })
};
<commit_msg>CSS transition for hover colors in sidebar<commit_after>// @flow

import { css } from 'glamor';
import React, { Component } from 'react';
import {
  envPresetDefaults,
  pluginConfigs,
  presetPluginConfigs
} from './PluginConfig';
import PresetLoadingAnimation from './PresetLoadingAnimation';
import Svg from './Svg';
import { colors, media } from './styles';

import type {
  EnvConfig,
  PluginConfig,
  PluginState,
  PluginStateMap
} from './types';

type ToggleEnvPresetSetting = (name: string, value: any) => void;
type ToggleExpanded = (isExpanded: boolean) => void;
type ToggleSetting = (name: string, isEnabled: boolean) => void;

type Props = {
  builtIns: boolean,
  className: string,
  debugEnvPreset: boolean,
  envConfig: EnvConfig,
  envPresetState: PluginState,
  isExpanded: boolean,
  lineWrap: boolean,
  onEnvPresetSettingChange: ToggleEnvPresetSetting,
  onIsExpandedChange: ToggleExpanded,
  onSettingChange: ToggleSetting,
  pluginState: PluginStateMap,
  presetState: PluginStateMap,
  runtimePolyfillConfig: PluginConfig,
  runtimePolyfillState: PluginState
};

const ReplOptions = (props: Props) =>
  <div className={`${styles.wrapper} ${props.className}`}>
    {props.isExpanded
      ? <ExpandedContainer {...props} />
      : <CollapsedContainer {...props} />}

;

export default ReplOptions;

// The choice of Component over PureComponent is intentional here.
// It simplifies the re-use of PluginState objects,
// Without requiring gratuitous use of Object-spread.
class ExpandedContainer extends Component {
  props: Props;

  static defaultProps = {
    className: ''
  };

  render() {
    const {
      builtIns,
      debugEnvPreset,
      envConfig,
      envPresetState,
      lineWrap,
      onIsExpandedChange,
      onSettingChange,
      pluginState,
      presetState,
      runtimePolyfillConfig,
      runtimePolyfillState
    } = this.props;

    const disableEnvSettings =
      !envPresetState.isLoaded || !envConfig.isEnvPresetEnabled;

    return (

Settings

          <PluginToggle
            config={runtimePolyfillConfig}
            label="Evaluate"
            onSettingChange={onSettingChange}
            state={runtimePolyfillState}
          />

            <input
              checked={lineWrap}
              onChange={this._onLineWrappingChange}
              className={styles.inputCheckboxLeft}
              type="checkbox"
            />
            Line Wrap

          {pluginConfigs.map(config =>
            <PluginToggle
              config={config}
              key={config.package}
              onSettingChange={onSettingChange}
              state={pluginState[config.package]}
            />
          )}

Presets

          {presetPluginConfigs.map(config =>
            <PluginToggle
              config={config}
              key={config.package}
              onSettingChange={onSettingChange}
              state={presetState[config.package]}
            />
          )}

        <div className={`${styles.section} ${styles.sectionEnv}`}>
          <label
            className={`${styles.sectionHeader} ${styles.sectionEnvHeader}`}
          >
            {envPresetState.isLoading
              ? <PresetLoadingAnimation />
              : 'Env Preset'}

            <input
              checked={envConfig.isEnvPresetEnabled}
              type="checkbox"
              onChange={this._onEnvPresetEnabledChange}
            />

            <label
              className={`${styles.envPresetColumnLabel} ${styles.highlight}`}
            >
              Browser

            <textarea
              disabled={disableEnvSettings}
              className={styles.envPresetInput}
              onChange={this._onBrowsersChange}
              placeholder={envPresetDefaults.browsers.placeholder}
              value={envConfig.browsers}
            />

            <span className={`${styles.envPresetLabel} ${styles.highlight}`}>
              Electron

            <input
              className={`${styles.envPresetNumber} ${styles.envPresetInput}`}
              disabled={
                !envPresetState.isLoaded ||
                !envConfig.isEnvPresetEnabled ||
                !envConfig.isElectronEnabled
              }
              type="number"
              min={envPresetDefaults.electron.min}
              max={999}
              step={envPresetDefaults.electron.step}
              onChange={this._onElectronChange}
              value={envConfig.electron}
            />
            <input
              checked={envConfig.isElectronEnabled}
              className={styles.envPresetCheckbox}
              disabled={disableEnvSettings}
              onChange={this._onIsElectronEnabledChange}
              type="checkbox"
            />

            <span className={`${styles.envPresetLabel} ${styles.highlight}`}>
              Node

            <input
              className={`${styles.envPresetNumber} ${styles.envPresetInput}`}
              disabled={
                !envPresetState.isLoaded ||
                !envConfig.isEnvPresetEnabled ||
                !envConfig.isNodeEnabled
              }
              type="number"
              min={envPresetDefaults.node.min}
              max={999}
              step={envPresetDefaults.node.step}
              onChange={this._onNodeChange}
              value={envConfig.node}
            />
            <input
              checked={envConfig.isNodeEnabled}
              className={styles.envPresetCheckbox}
              disabled={disableEnvSettings}
              onChange={this._onIsNodeEnabledChange}
              type="checkbox"
            />

            <input
              checked={builtIns}
              className={styles.inputCheckboxLeft}
              disabled={runtimePolyfillState.isEnabled || disableEnvSettings}
              onChange={this._onBuiltInsChange}
              type="checkbox"
            />
            Built-ins

            <input
              checked={debugEnvPreset}
              className={styles.inputCheckboxLeft}
              disabled={disableEnvSettings}
              onChange={this._onDebugChange}
              type="checkbox"
            />
            Debug

        <div
          className={`${styles.closeButton} ${nestedCloseButton}`}
          onClick={() => onIsExpandedChange(false)}
        >
          <Svg
            className={styles.closeButtonIcon}
            path="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z"
          />

    );
  }

  _onBrowsersChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('browsers', event.target.value);
  };

  _onEnvPresetEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'isEnvPresetEnabled',
      event.target.checked
    );
  };

  _onBuiltInsChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('builtIns', event.target.checked);
  };

  _onDebugChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('debugEnvPreset', event.target.checked);
  };

  _onElectronChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'electron',
      parseFloat(event.target.value)
    );
  };

  _onIsElectronEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange(
      'isElectronEnabled',
      event.target.checked
    );
  };

  _onIsNodeEnabledChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('isNodeEnabled', event.target.checked);
  };

  _onLineWrappingChange = (event: SyntheticInputEvent) => {
    this.props.onSettingChange('lineWrap', event.target.checked);
  };

  _onNodeChange = (event: SyntheticInputEvent) => {
    this.props.onEnvPresetSettingChange('node', parseFloat(event.target.value));
  };
}

const CollapsedContainer = ({ onIsExpandedChange }) =>

    <div
      className={`${styles.closeButton} ${nestedCloseButton}`}
      onClick={() => onIsExpandedChange(true)}
    >
      <Svg
        className={styles.closeButtonIcon}
        path="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"
      />

;

type PluginToggleProps = {
  config: PluginConfig,
  label?: string,
  state: PluginState,
  onSettingChange: ToggleSetting
};

const PluginToggle = ({
  config,
  label,
  state,
  onSettingChange
}: PluginToggleProps) =>

    <input
      checked={state.isEnabled && !state.didError}
      className={styles.inputCheckboxLeft}
      disabled={state.isLoading || state.didError}
      onChange={(event: SyntheticInputEvent) =>
        onSettingChange(config.package, event.target.checked)}
      type="checkbox"
    />
    {state.isLoading ? <PresetLoadingAnimation /> : label || config.label}
  ;

// Defined separately from styles due to nesting.
const nestedCloseButton = css({});

const styles = {
  wrapper: css({
    position: 'relative',
    overflow: 'visible',
    zIndex: 6,
    backgroundColor: colors.inverseBackground,
    color: colors.inverseForegroundLight,
    transition: 'transform 0.25s ease-in-out',

    [media.large]: {
      height: '100%' // Safari fix for scrolling/overflow
    }
  }),
  collapsedContainer: css({
    backgroundColor: colors.inverseBackground,

    [media.large]: {
      width: '0.5rem',
      height: '100%'
    },

    [media.mediumAndDown]: {
      height: '0.5rem',
      width: '100%'
    },

    [`& .${nestedCloseButton}`]: {
      [media.mediumAndDown]: {
        transition: 'top 0.25s ease-in-out',
        top: '-0.5rem'
      },

      [media.large]: {
        transition: 'left 0.25s ease-in-out',
        left: '-0.5rem'
      }
    },

    '&:hover': {
      [`& .${nestedCloseButton}`]: {
        [media.mediumAndDown]: {
          top: 0
        },

        [media.large]: {
          left: 0
        }
      }
    }
  }),
  expandedContainer: css({
    minWidth: '150px',
    display: 'flex',
    overflow: 'auto',
    boxSshadow:
      'rgba(0, 0, 0, 0.12) 0px 1px 6px, rgba(0, 0, 0, 0.24) 0px 1px 4px',

    [media.large]: {
      flexDirection: 'column',
      height: '100%',

      [`& .${nestedCloseButton}`]: {
        right: '-1.5rem'
      }
    },

    [media.mediumAndDown]: {
      flexDirection: 'row',
      flexWrap: 'wrap',
      overflow: 'auto',

      [`& .${nestedCloseButton}`]: {
        bottom: '-1.5rem'
      }
    }
  }),
  closeButton: css({
    position: 'absolute',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    cursor: 'pointer',
    backgroundColor: colors.inverseBackground,
    color: colors.inverseForegroundLight,

    [media.large]: {
      height: '4rem',
      width: '2rem',
      top: 'calc(50% - 2rem)',
      borderTopRightRadius: '4rem',
      borderBottomRightRadius: '4rem'
    },

    [media.mediumAndDown]: {
      height: '2rem',
      width: '4rem',
      left: 'calc(50% - 2rem)',
      borderBottomLeftRadius: '4rem',
      borderBottomRightRadius: '4rem'
    }
  }),
  closeButtonIcon: css({
    width: '1.5rem',
    height: '1.5rem',

    [media.mediumAndDown]: {
      transform: 'rotate(90deg)'
    }
  }),
  section: css({
    display: 'flex',
    flexDirection: 'column',
    overflow: 'auto',
    flex: '0 0 auto',
    maxHeight: '100%',
    padding: '1rem',
    zIndex: 7,

    [media.mediumAndDown]: {
      flex: '1 0 100px',
      maxHeight: '100%',
      overflow: 'auto'
    }
  }),
  sectionEnv: css({
    borderBottom: 'none',
    borderRight: 'none',

    [media.mediumAndDown]: {
      flex: '1 0 150px'
    }
  }),
  inputCheckboxLeft: css({
    marginRight: '0.5rem'
  }),
  highlight: css({
    textTransform: 'uppercase',
    fontSize: '0.8rem',
    fontWeight: 'bold',
    color: colors.inverseForeground
  }),
  sectionHeader: css({
    flex: '0 0 2rem',
    fontSize: '1.25rem',
    fontWeight: 'bold',
    color: colors.inverseForegroundLight
  }),
  sectionEnvHeader: css({
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between'
  }),
  settingsLabel: css({
    flex: '0 0 2rem',
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    margin: '0 -1rem',
    padding: '0 1rem',
    transition: 'background-color 250ms ease-in-out, color 250ms ease-in-out',

    '&:hover': {
      backgroundColor: colors.inverseBackgroundDark,
      color: colors.inverseForeground
    }
  }),
  envPresetColumn: css({
    display: 'flex',
    flexDirection: 'column',
    margin: '0.5rem 0',
    flex: '0 0 auto'
  }),
  envPresetColumnLabel: css({
    margin: '0.5rem 0'
  }),
  envPresetRow: css({
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    flex: '0 0 auto',
    margin: '0.5rem 0'
  }),
  envPresetNumber: css({
    flex: '0 0 2.5rem',
    maxWidth: '2.5rem'
  }),
  envPresetCheckbox: css({
    flex: '0 0 auto',
    marginLeft: '0.5rem'
  }),
  envPresetLabel: css({
    flex: 1
  }),
  envPresetInput: css({
    WebkitAppearance: 'none',
    border: 'none',
    borderRadius: '0.125rem',

    '&:disabled': {
      opacity: 0.5
    }
  })
};
<|endoftext|>


<commit_before>var webpackConfig = require("./webpack.config");
Object.assign(webpackConfig, {
    debug: true,
    devtool: "inline-source-map"
});

webpackConfig.externals.push("react/lib/ExecutionEnvironment");
webpackConfig.externals.push("react/lib/ReactContext");
webpackConfig.externals.push("react/addons");
webpackConfig.externals.push("jsdom");

module.exports = function(config) {
    config.set({
        basePath: "",
        frameworks: [ "jasmine" ],
        files: [
            { pattern: "src/**/*.ts", watched: false, included: false, served: false },
            { pattern: "tests/**/*.ts", watched: false, included: false, served: false },
            "tests/test-index.js"
        ],
        exclude: [],
        preprocessors: {
            "tests/test-index.js": [ "webpack", "sourcemap" ]
        },
        webpack: webpackConfig,
        webpackServer: { noInfo: true },
        reporters: [ "progress", "kjhtml", "coverage" ],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: [ "Chrome" ],
        singleRun: false,
        concurrency: Infinity,
        coverageReporter: {
            dir: "./dist/testresults",
            reporters: [
                { type: "json", subdir: ".", file: "coverage.json" },
                { type: "text" }
            ]
        }
    })
};
<commit_msg>Review: push multiple elements with single push<commit_after>var webpackConfig = require("./webpack.config");
Object.assign(webpackConfig, {
    debug: true,
    devtool: "inline-source-map",
    externals: webpackConfig.externals.concat([
        "react/lib/ExecutionEnvironment",
        "react/lib/ReactContext",
        "react/addons",
        "jsdom"
    ])
});

module.exports = function(config) {
    config.set({
        basePath: "",
        frameworks: [ "jasmine" ],
        files: [
            { pattern: "src/**/*.ts", watched: true, included: false, served: false },
            { pattern: "tests/**/*.ts", watched: true, included: false, served: false },
            "tests/test-index.js"
        ],
        exclude: [],
        preprocessors: {
            "tests/test-index.js": [ "webpack", "sourcemap" ]
        },
        webpack: webpackConfig,
        webpackServer: { noInfo: true },
        reporters: [ "progress", "kjhtml", "coverage" ],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: [ "Chrome" ],
        singleRun: false,
        concurrency: Infinity,
        coverageReporter: {
            dir: "./dist/testresults",
            reporters: [
                { type: "json", subdir: ".", file: "coverage.json" },
                { type: "text" }
            ]
        }
    })
};
<|endoftext|>


<commit_before>module.exports = (app) => {
  return (req, res, next) => {
    res.render('admin/page/dashboard/index.html');
  };
};
<commit_msg>no message<commit_after>module.exports = () => (
  (req, res) => {
    res.render('admin/page/dashboard/index.html');
  }
);
<|endoftext|>


<commit_before>Version = { id: '88232bb' };
<commit_msg>Bump up version<commit_after>Version = { id: 'ba8a3cb' };
<|endoftext|>


<commit_before>(function (ns) {

    var singleton = null;

    var SYSTEM_CONTEXT_TEMPLATE = {
        "type": "object",
        "kind": "any",
        "info": {
            "coords": { "type": "object", "kind": "float3", "source": "uniform" },
            "cameraPosition": { "type": "object", "kind": "float3", "source": "uniform" },
            "viewMatrix": { "type": "object", "kind": "matrix4", "source": "uniform" },

            "MAX_POINTLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "pointLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "pointLightAttenuation": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "pointLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "pointLightPosition": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },

            "MAX_DIRECTIONALLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "directionalLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "directionalLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "directionalLightDirection": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },

            "MAX_SPOTLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "spotLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "spotLightAttenuation": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightPosition": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightDirection": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightCosFalloffAngle": {
                "type": "array", "elements": { "type": "number" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightCosSoftFalloffAngle": {
                "type": "array", "elements": { "type": "number" }, "staticSize": 5,
                "source": "uniform"
            }
        }
    };

    function createSystemConfiguration(context) {
        var result = SYSTEM_CONTEXT_TEMPLATE;
        var ext = context.getExtensionByName(ns.GLContext.EXTENSIONS.STANDARD_DERIVATES);
        if (ext) {
            result.info.fwidth = { type: Shade.TYPES.FUNCTION };
            result.info.dFdx = { type: Shade.TYPES.FUNCTION };
            result.info.dFdy = { type: Shade.TYPES.FUNCTION };
        }
        return result;
    }

    ns.getJSSystemConfiguration = function (context) {
        if (!singleton) {
            singleton = createSystemConfiguration(context);
        }
        return singleton;
    };

}(XML3D.webgl));

<commit_msg>Added space transformation matrices to js config.<commit_after>(function (ns) {

    var singleton = null;

    var SYSTEM_CONTEXT_TEMPLATE = {
        "type": "object",
        "kind": "any",
        "info": {
            "coords": { "type": "object", "kind": "float3", "source": "uniform" },
            "cameraPosition": { "type": "object", "kind": "float3", "source": "uniform" },
            "viewMatrix": { "type": "object", "kind": "matrix4", "source": "uniform" },
            "modelMatrix": { "type": "object", "kind": "matrix4", "source": "uniform" },
            "modelViewMatrix": { "type": "object", "kind": "matrix4", "source": "uniform" },
            "modelViewProjectionMatrix": { "type": "object", "kind": "matrix4", "source": "uniform" },
            "modelMatrixN": { "type": "object", "kind": "matrix3", "source": "uniform" },
            "modelViewMatrixN": { "type": "object", "kind": "matrix3", "source": "uniform" },

            "MAX_POINTLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "pointLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "pointLightAttenuation": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "pointLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "pointLightPosition": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },

            "MAX_DIRECTIONALLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "directionalLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "directionalLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "directionalLightDirection": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },

            "MAX_SPOTLIGHTS": { "type": "int", "source": "constant", "staticValue": 5 },
            "spotLightOn": { "type": "array", "elements": { "type": "boolean" }, "staticSize": 5, "source": "uniform"},
            "spotLightAttenuation": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightIntensity": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightPosition": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightDirection": {
                "type": "array", "elements": { "type": "object", "kind": "float3" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightCosFalloffAngle": {
                "type": "array", "elements": { "type": "number" }, "staticSize": 5,
                "source": "uniform"
            },
            "spotLightCosSoftFalloffAngle": {
                "type": "array", "elements": { "type": "number" }, "staticSize": 5,
                "source": "uniform"
            }
        }
    };

    function createSystemConfiguration(context) {
        var result = SYSTEM_CONTEXT_TEMPLATE;
        var ext = context.getExtensionByName(ns.GLContext.EXTENSIONS.STANDARD_DERIVATES);
        if (ext) {
            result.info.fwidth = { type: Shade.TYPES.FUNCTION };
            result.info.dFdx = { type: Shade.TYPES.FUNCTION };
            result.info.dFdy = { type: Shade.TYPES.FUNCTION };
        }
        return result;
    }

    ns.getJSSystemConfiguration = function (context) {
        if (!singleton) {
            singleton = createSystemConfiguration(context);
        }
        return singleton;
    };

}(XML3D.webgl));

<|endoftext|>


<commit_before>'use strict';

function eat_purple_creature(){
    core_audio_start({
      'id': 'boop',
    });

    document.getElementById('score').innerHTML = parseInt(
      document.getElementById('score').innerHTML,
      10
    ) + 1;

    // If there is no space available for more holes, stop.
    var holes_per_point = core_storage_data['holes-per-point'];
    if(document.getElementById('score').innerHTML >=
      Math.floor(398 / (parseInt(holes_per_point, 10) + 1)) + 1){
        stop();
        return;
    }

    // Pick a button with color_empty and make it the new purple creature.
    var id = -1;
    do{
        id = core_random_integer({
          'max': 400,
        });
    }while(document.getElementById(id).style.backgroundColor != color_empty);
    document.getElementById(id).style.backgroundColor = color_purple;

    var loop_counter = holes_per_point - 1;
    // If more than 0 holes should be created.
    if(loop_counter >= 0){
        // Add new holes.
        do{
            while(document.getElementById(id).style.backgroundColor != color_empty){
                id = core_random_integer({
                  'max': 400,
                });
            }
            document.getElementById(id).style.backgroundColor = color_obstacle;
        }while(loop_counter--);
    }
}

function move_player(){
    // Check if game is still running, based on game mode and if frames/score are over max.
    var frames = parseFloat(document.getElementById('frames').innerHTML);
    var end_game = core_storage_data['game-mode'] === 1
      ? frames <= 0
        && core_storage_data['max'] > 0
      : core_storage_data['max'] != 0
        && parseInt(document.getElementById('score').innerHTML, 10) >= core_storage_data['max'];

    // If game is not running, stop().
    if(end_game){
        stop();
        return;
    }

    // Add or subtract 1 from frames depending on game mode.
    document.getElementById('frames').innerHTML = (frames +
        ((core_storage_data['game-mode'] === 1
      && core_storage_data['max'] > 0) ? -1 : 1));

    var check_color = 0;
    var dx = 0;
    var dy = 0;

    // If player is moving up.
    if(player['movement_direction'] === 0){
        // If player is not at the top of the screen.
        if(player['y'] - 1 >= 0){
            // Fetch color of space directly above the player.
            check_color = document.getElementById((player['y'] - 1) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue, else collision.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Decrease player Y position.
                player['y'] -= 1;
                dy += 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the top of the screen and can wrap in the Y-direction.
        }else if(core_storage_data['wrap'] == 2
          || core_storage_data['wrap'] == 3){
            // Fetch color of space at the bottom of the screen.
            check_color = document.getElementById((player['y'] + 19) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature()
                }

                // Set player Y position to bottom of the screen.
                player['y'] = 19;
                dy -= 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving right.
    }else if(player['movement_direction'] === 1){
        // If player is not at the right edge of the screen.
        if(player['x'] + 1 <= 19){
            // Fetch color of space to the right of the player.
            check_color = document.getElementById(player['y'] * 20 + player['x'] + 1).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Increase player X position.
                player['x'] += 1;
                dx -= 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the right edge of the screen and can wrap in the X-direction.
        }else if(core_storage_data['wrap'] == 1
          || core_storage_data['wrap'] == 2){
            // Fetch color of space at the left of the screen.
            check_color = document.getElementById(player['y'] * 20 + player['x'] - 19).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Set player X position to left side of the screen.
                player['x'] -= 19;
                dx += 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving down.
    }else if(player['movement_direction'] === 2){
        // If player is not at the bottom of the screen.
        if(player['y'] + 1 <= 19){
            // Fetch color of space directory below the player.
            check_color = document.getElementById((player['y'] + 1) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Increase player Y position.
                player['y'] += 1;
                dy -= 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the bottom edge of the screen and can wrap in the U-direction.
        }else if(core_storage_data['wrap'] == 2
          || core_storage_data['wrap'] == 3){
            // Fetch color of space at the top of the screen.
            check_color = document.getElementById((player['y'] - 19) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Set player Y position to top of the screen.
                player['y'] = 0;
                dy += 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving left.
    }else if(player['movement_direction'] === 3){
        if(player['x'] - 1 >= 0){
            // Fetch color of space to the left of the player.
            check_color = document.getElementById(player['y'] * 20 + player['x'] - 1).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Decrease player x position.
                player['x'] -= 1;
                dx += 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the left edge of the screen and can wrap in the X-direction.
        }else if(core_storage_data['wrap'] == 1
          || core_storage_data['wrap'] == 2){
            // Fetch color of space at the right side of the screen.
            check_color = document.getElementById(player['y'] * 20 + player['x'] + 19).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === color_purple){
                    eat_purple_creature();
                }

                // Set player x position to right side of the screen.
                player['x'] += 19;
                dx -= 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }
    }

    // If a collision with an obstacle or edge was detected.
    if(end_game){
        // If game ends oncollision...
        if(core_storage_data['oncollision'] == 1){
            stop();

        // ...else if score decreases.
        }else if(core_storage_data['oncollision'] === 2){
            document.getElementById('score').innerHTML =
              parseInt(
                document.getElementById('score').innerHTML,
                10
              ) - 1;
        }
    }

    // If player x or y position has changed.
    if(dx !== 0
      || dy !== 0){
        // Reset old player position to color_empty.
        document.getElementById((player['y'] + dy) * 20 + player['x'] + dx).style.backgroundColor = color_empty;
    }

    // Set color of new player position to player['color'].
    document.getElementById(player['y'] * 20 + player['x']).style.backgroundColor = player['color'];
}

function repo_escape(){
    stop();
}

function repo_init(){
    core_repo_init({
      'audios': {
        'boop': {
          'duration': .1,
        },
      },
      'keybinds': {
        65: {
          'todo': function(){
              if(player['movement_direction'] !== 1 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 3;
              }
          },
        },
        68: {
          'todo': function(){
              if(player['movement_direction'] !== 3 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 1;
              }
          },
        },
        72: {
          'todo': function(){
              stop();
              start();
          },
        },
        83: {
          'todo': function(){
              if(player['movement_direction'] !== 0 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 2;
              }
          },
        },
        87: {
          'todo': function(){
              if(player['movement_direction'] !== 2 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 0;
              }
          },
        },
      },
      'storage': {
        'game-mode': 0,
        'holes-at-start': 0,
        'holes-per-point': 1,
        'max': 0,
        'ms-per-move': 125,
        'oncollision': 1,
        'turn-angle': 0,
        'wrap': 0,
      },
      'storage-menu': '

<input id=holes-at-start>Holes at Start
<input id=holes-per-point>Holes/Point
<input id=max>Max <select id=game-mode><option value=1>Frames</option><option value=0>Points</option></select>
<input id=ms-per-move>ms/Move
<select id=oncollision><option value=1>End Game</option><option value=0>Nothing</option><option value=2>Score-1</option></select>OnCollision
<select id=turn-angle><option value=0>90</option><option value=1><=180</option></select>° Turn Angle
<select id=wrap><option value=0>No</option><option value=1>X</option><option value=2>X&Y</option><option value=3>Y</option></select>Wrap
',
      'title': 'Snakish.htm',
    });

    // Create buttons for game-div.
    var output = '';

    for(var loop_counter = 0; loop_counter < 400; loop_counter++){
        if(loop_counter % 20 === 0 && loop_counter !== 0){
            output += '
';
        }

        var color = color_empty;
        if(loop_counter == 21){
            color = player['color'];

        }else if(loop_counter == 378){
            color = color_purple;
        }

        output +=
          '<input class=gridbutton disabled id=' + loop_counter
          + ' style="background:' + color
          + '" type=button>';
    }
    document.getElementById('game-div').innerHTML = output;

    stop();

    document.getElementById('start-button').onclick = start;
}

function start(){
    core_storage_save();

    // Reset buttons to empty with player and purple creature in initial positions.
    var loop_counter = 399;
    do{
        document.getElementById(loop_counter).style.backgroundColor = color_empty;
    }while(loop_counter--);
    document.getElementById(21).style.backgroundColor = player['color'];
    document.getElementById(378).style.backgroundColor = color_purple;

    document.getElementById('start-button').value = 'End [ESC]';
    document.getElementById('start-button').onclick = stop;
    document.getElementById('score').innerHTML = '0';

    // Reset player
    player['movement_direction'] = 1; // 0==Up, 1==Right, 2==Down, 3==Left
    player['x'] = 1;
    player['y'] = 1;

    // Create initial holes, if any.
    if(core_storage_data['holes-at-start'] > 0){
        var id = -1;
        loop_counter = core_storage_data['holes-at-start'] - 1;
        do{
            do{
                id = core_random_integer({
                  'max': 400,
                });
            }while(document.getElementById(id).style.backgroundColor !== color_empty);
            document.getElementById(id).style.backgroundColor = color_obstacle;
        }while(loop_counter--);
    }

    // Setup display or not display of max frames or max points.
    if(core_storage_data['game-mode'] === 1){
        document.getElementById('frames').innerHTML = core_storage_data['max'];
        document.getElementById('frames-max').innerHTML = core_storage_data['max'];
        document.getElementById('score-max').innerHTML = '';
        document.getElementById('frames-max-span').style.display =
          document.getElementById('max').value > 0
            ? 'inline'
            : 'none';

    }else{
        document.getElementById('frames').innerHTML = 0;
        document.getElementById('frames-max-span').style.display = 'none';
        document.getElementById('score-max').innerHTML = core_storage_data['max'] > 0
          ? ' / ' + core_storage_data['max']
          : '';
    }

    // Validate milliseconds per player movement and create interval.
    interval = window.setInterval(
      move_player,
      core_storage_data['ms-per-move'] > 0
        ? core_storage_data['ms-per-move']
        : 125
    );
}

function stop(){
    window.clearInterval(interval);
    document.getElementById('start-button').value = 'Start [H]';
    document.getElementById('start-button').onclick = start;
}

var color_empty = 'rgb(42, 42, 42)';
var color_obstacle = 'rgb(0, 0, 0)';
var color_purple = 'rgb(102, 51, 102)';
var interval = 0;
var player = {
  'color': 'rgb(32, 102, 32)',
  'movement_direction': 1,// 0==Up, 1==Right, 2==Down, 3==Left
  'x': 1,
  'y': 1,
};
<commit_msg>added global color usage<commit_after>'use strict';

function eat_purple_creature(){
    core_audio_start({
      'id': 'boop',
    });

    document.getElementById('score').innerHTML = parseInt(
      document.getElementById('score').innerHTML,
      10
    ) + 1;

    // If there is no space available for more holes, stop.
    var holes_per_point = core_storage_data['holes-per-point'];
    if(document.getElementById('score').innerHTML >=
      Math.floor(398 / (parseInt(holes_per_point, 10) + 1)) + 1){
        stop();
        return;
    }

    // Pick a button with color_empty and make it the new purple creature.
    var id = -1;
    do{
        id = core_random_integer({
          'max': 400,
        });
    }while(document.getElementById(id).style.backgroundColor != color_empty);
    document.getElementById(id).style.backgroundColor = core_storage_data['color-negative'];

    var loop_counter = holes_per_point - 1;
    // If more than 0 holes should be created.
    if(loop_counter >= 0){
        // Add new holes.
        do{
            while(document.getElementById(id).style.backgroundColor != color_empty){
                id = core_random_integer({
                  'max': 400,
                });
            }
            document.getElementById(id).style.backgroundColor = color_obstacle;
        }while(loop_counter--);
    }
}

function move_player(){
    // Check if game is still running, based on game mode and if frames/score are over max.
    var frames = parseFloat(document.getElementById('frames').innerHTML);
    var end_game = core_storage_data['game-mode'] === 1
      ? frames <= 0
        && core_storage_data['max'] > 0
      : core_storage_data['max'] != 0
        && parseInt(document.getElementById('score').innerHTML, 10) >= core_storage_data['max'];

    // If game is not running, stop().
    if(end_game){
        stop();
        return;
    }

    // Add or subtract 1 from frames depending on game mode.
    document.getElementById('frames').innerHTML = (frames +
        ((core_storage_data['game-mode'] === 1
      && core_storage_data['max'] > 0) ? -1 : 1));

    var check_color = 0;
    var dx = 0;
    var dy = 0;

    // If player is moving up.
    if(player['movement_direction'] === 0){
        // If player is not at the top of the screen.
        if(player['y'] - 1 >= 0){
            // Fetch color of space directly above the player.
            check_color = document.getElementById((player['y'] - 1) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue, else collision.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Decrease player Y position.
                player['y'] -= 1;
                dy += 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the top of the screen and can wrap in the Y-direction.
        }else if(core_storage_data['wrap'] == 2
          || core_storage_data['wrap'] == 3){
            // Fetch color of space at the bottom of the screen.
            check_color = document.getElementById((player['y'] + 19) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Set player Y position to bottom of the screen.
                player['y'] = 19;
                dy -= 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving right.
    }else if(player['movement_direction'] === 1){
        // If player is not at the right edge of the screen.
        if(player['x'] + 1 <= 19){
            // Fetch color of space to the right of the player.
            check_color = document.getElementById(player['y'] * 20 + player['x'] + 1).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Increase player X position.
                player['x'] += 1;
                dx -= 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the right edge of the screen and can wrap in the X-direction.
        }else if(core_storage_data['wrap'] == 1
          || core_storage_data['wrap'] == 2){
            // Fetch color of space at the left of the screen.
            check_color = document.getElementById(player['y'] * 20 + player['x'] - 19).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Set player X position to left side of the screen.
                player['x'] -= 19;
                dx += 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving down.
    }else if(player['movement_direction'] === 2){
        // If player is not at the bottom of the screen.
        if(player['y'] + 1 <= 19){
            // Fetch color of space directory below the player.
            check_color = document.getElementById((player['y'] + 1) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Increase player Y position.
                player['y'] += 1;
                dy -= 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the bottom edge of the screen and can wrap in the U-direction.
        }else if(core_storage_data['wrap'] == 2
          || core_storage_data['wrap'] == 3){
            // Fetch color of space at the top of the screen.
            check_color = document.getElementById((player['y'] - 19) * 20 + player['x']).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Set player Y position to top of the screen.
                player['y'] = 0;
                dy += 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }

    // If player is moving left.
    }else if(player['movement_direction'] === 3){
        if(player['x'] - 1 >= 0){
            // Fetch color of space to the left of the player.
            check_color = document.getElementById(player['y'] * 20 + player['x'] - 1).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Decrease player x position.
                player['x'] -= 1;
                dx += 1;

            // Collision!
            }else{
                end_game = true;
            }

        // If player is at the left edge of the screen and can wrap in the X-direction.
        }else if(core_storage_data['wrap'] == 1
          || core_storage_data['wrap'] == 2){
            // Fetch color of space at the right side of the screen.
            check_color = document.getElementById(player['y'] * 20 + player['x'] + 19).style.backgroundColor;

            // If the space is not an obstacle continue.
            if(check_color !== color_obstacle){
                // If color of space is purple, eat the creature.
                if(check_color === core_storage_data['color-negative']){
                    eat_purple_creature();
                }

                // Set player x position to right side of the screen.
                player['x'] += 19;
                dx -= 19;

            // Collision!
            }else{
                end_game = true;
            }

        // Collision!
        }else{
            end_game = true;
        }
    }

    // If a collision with an obstacle or edge was detected.
    if(end_game){
        // If game ends oncollision...
        if(core_storage_data['oncollision'] == 1){
            stop();

        // ...else if score decreases.
        }else if(core_storage_data['oncollision'] === 2){
            document.getElementById('score').innerHTML =
              parseInt(
                document.getElementById('score').innerHTML,
                10
              ) - 1;
        }
    }

    // If player x or y position has changed.
    if(dx !== 0
      || dy !== 0){
        // Reset old player position to color_empty.
        document.getElementById((player['y'] + dy) * 20 + player['x'] + dx).style.backgroundColor = color_empty;
    }

    // Set color of new player position to core_storage_data['color-positive'].
    document.getElementById(player['y'] * 20 + player['x']).style.backgroundColor = core_storage_data['color-positive'];
}

function repo_escape(){
    stop();
}

function repo_init(){
    core_repo_init({
      'audios': {
        'boop': {
          'duration': .1,
        },
      },
      'keybinds': {
        65: {
          'todo': function(){
              if(player['movement_direction'] !== 1 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 3;
              }
          },
        },
        68: {
          'todo': function(){
              if(player['movement_direction'] !== 3 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 1;
              }
          },
        },
        72: {
          'todo': function(){
              stop();
              start();
          },
        },
        83: {
          'todo': function(){
              if(player['movement_direction'] !== 0 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 2;
              }
          },
        },
        87: {
          'todo': function(){
              if(player['movement_direction'] !== 2 || core_storage_data['turn-angle'] == 1){
                  player['movement_direction'] = 0;
              }
          },
        },
      },
      'storage': {
        'game-mode': 0,
        'holes-at-start': 0,
        'holes-per-point': 1,
        'max': 0,
        'ms-per-move': 125,
        'oncollision': 1,
        'turn-angle': 0,
        'wrap': 0,
      },
      'storage-menu': '

<input id=holes-at-start>Holes at Start
<input id=holes-per-point>Holes/Point
<input id=max>Max <select id=game-mode><option value=1>Frames</option><option value=0>Points</option></select>
<input id=ms-per-move>ms/Move
<select id=oncollision><option value=1>End Game</option><option value=0>Nothing</option><option value=2>Score-1</option></select>OnCollision
<select id=turn-angle><option value=0>90</option><option value=1><=180</option></select>° Turn Angle
<select id=wrap><option value=0>No</option><option value=1>X</option><option value=2>X&Y</option><option value=3>Y</option></select>Wrap
',
      'title': 'Snakish.htm',
    });

    // Create buttons for game-div.
    var output = '';

    for(var loop_counter = 0; loop_counter < 400; loop_counter++){
        if(loop_counter % 20 === 0 && loop_counter !== 0){
            output += '
';
        }

        var color = color_empty;
        if(loop_counter == 21){
            color = core_storage_data['color-positive'];

        }else if(loop_counter == 378){
            color = core_storage_data['color-negative'];
        }

        output +=
          '<input class=gridbutton disabled id=' + loop_counter
          + ' style="background:' + color
          + '" type=button>';
    }
    document.getElementById('game-div').innerHTML = output;

    stop();

    document.getElementById('start-button').onclick = start;
}

function start(){
    core_storage_save();

    // Reset buttons to empty with player and purple creature in initial positions.
    var loop_counter = 399;
    do{
        document.getElementById(loop_counter).style.backgroundColor = color_empty;
    }while(loop_counter--);
    document.getElementById(21).style.backgroundColor = core_storage_data['color-positive'];
    document.getElementById(378).style.backgroundColor = core_storage_data['color-negative'];

    document.getElementById('start-button').value = 'End [ESC]';
    document.getElementById('start-button').onclick = stop;
    document.getElementById('score').innerHTML = '0';

    // Reset player
    player['movement_direction'] = 1; // 0==Up, 1==Right, 2==Down, 3==Left
    player['x'] = 1;
    player['y'] = 1;

    // Create initial holes, if any.
    if(core_storage_data['holes-at-start'] > 0){
        var id = -1;
        loop_counter = core_storage_data['holes-at-start'] - 1;
        do{
            do{
                id = core_random_integer({
                  'max': 400,
                });
            }while(document.getElementById(id).style.backgroundColor !== color_empty);
            document.getElementById(id).style.backgroundColor = color_obstacle;
        }while(loop_counter--);
    }

    // Setup display or not display of max frames or max points.
    if(core_storage_data['game-mode'] === 1){
        document.getElementById('frames').innerHTML = core_storage_data['max'];
        document.getElementById('frames-max').innerHTML = core_storage_data['max'];
        document.getElementById('score-max').innerHTML = '';
        document.getElementById('frames-max-span').style.display =
          document.getElementById('max').value > 0
            ? 'inline'
            : 'none';

    }else{
        document.getElementById('frames').innerHTML = 0;
        document.getElementById('frames-max-span').style.display = 'none';
        document.getElementById('score-max').innerHTML = core_storage_data['max'] > 0
          ? ' / ' + core_storage_data['max']
          : '';
    }

    // Validate milliseconds per player movement and create interval.
    interval = window.setInterval(
      move_player,
      core_storage_data['ms-per-move'] > 0
        ? core_storage_data['ms-per-move']
        : 125
    );
}

function stop(){
    window.clearInterval(interval);
    document.getElementById('start-button').value = 'Start [H]';
    document.getElementById('start-button').onclick = start;
}

var color_empty = 'rgb(42, 42, 42)';
var color_obstacle = 'rgb(0, 0, 0)';
var interval = 0;
var player = {
  'movement_direction': 1,// 0==Up, 1==Right, 2==Down, 3==Left
  'x': 1,
  'y': 1,
};
<|endoftext|>