<commit_before>import React, { useState, useEffect } from 'react';
import { PropTypes as T } from 'prop-types';

import _ from 'lodash';

import { formatThousands } from '../../utils/format';
import config from '../../config';

import Header, { LoadingHeader, ErrorHeader } from '../../components/header';
import LoadingMessage from '../../components/loading-message';
import InfoMessage from '../../components/info-message';
import LocationCard from '../../components/location-card';
import CountryMap from './map';

const defaultLocations = {
  locationFetched: false,
  locationFetching: false,
  locationError: null,
  locations: null,
};

const defaultCountry = {
  countryFetched: false,
  countryFetching: false,
  countryError: null,
  country: null,
};

export default function Country(props) {
  const id = props.match.params.name;
  const [
    { locationFetched, locationFetching, locationError, locations },
    setLocations,
  ] = useState(defaultLocations);
  const [
    { countryFetched, countryFetching, countryError, country },
    setCountry,
  ] = useState(defaultCountry);

  useEffect(() => {
    const fetchLocations = id => {
      setLocations(state => ({
        ...state,
        locationFetching: true,
        locationError: null,
      }));
      let limit = 10000;
      fetch(`${config.api}/locations?limit=${limit}&country=${id}`)
        .then(response => {
          if (response.status >= 400) {
            throw new Error('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setLocations(state => ({
              ...state,
              fetched: true,
              locationFetching: false,
              locations: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setLocations(state => ({
              ...state,
              locationFetched: true,
              locationFetching: false,
              locationError: e,
            }));
          }
        );
    };

    const fetchCountry = id => {
      setCountry(state => ({
        ...state,
        countryFetching: true,
        countryError: null,
      }));
      let limit = 1;
      fetch(`${config.api}/countries?limit=${limit}&country=${id}`)
        .then(response => {
          if (response.status >= 400) {
            throw new Error('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setCountry(state => ({
              ...state,
              countryFetched: true,
              countryFetching: false,
              country: json.results[0],
            }));
          },
          e => {
            console.log('e', e);
            setCountry(state => ({
              ...state,
              countryFetched: true,
              countryFetching: false,
              countryError: e,
            }));
          }
        );
    };

    fetchLocations(id);
    fetchCountry(id);

    return () => {
      setLocations(defaultLocations);
      setCountry(defaultCountry);
    };
  }, []);

  function onDownloadClick(data, e) {
    e && e.preventDefault();
    props._openDownloadModal(data);
  }

  // gets sources from locations and uses set to create an array with no duplicates
  const sourceList = locations
    ? Array.from(
        new Set(locations.map(loc => loc.sources[0]).map(JSON.stringify))
      ).map(JSON.parse)
    : null;

  let locationGroups = _(locations).sortBy('city').groupBy('city').value();
  console.log('sourceList', sourceList);
  console.log('locationGroups', Object.entries(locationGroups));

  return (
    <>
      {(countryError || !country) && <ErrorHeader />}
      {countryFetching && <LoadingHeader />}
      {country && locations && (

           1 ? 'locations' : 'location',
              },
              {
                number: formatThousands(country.count),
                label: 'measurements',
              },
              {
                number: sourceList.length,
                label: sourceList.length > 1 ? 'sources' : 'source',
              },
            ]}
            action={{
              api: config.apiDocs,
              download: () =>
                onDownloadClick(null, {
                  country: id,
                }),
            }}
          />

            <CountryMap />
            {locationFetching && <LoadingMessage />}
            {locationError && <InfoMessage standardMessage />}

              {Object.entries(locationGroups).map(([city, cityLocations]) => (

                        {city}{' '}

                          {locations.length}{' '}
                          {locations.length > 1 ? 'locations' : 'location'}

                        <a
                          href="#"
                          className="location-download-button"
                          title={`Download ${city} data`}
                          onClick={() =>
                            onDownloadClick(null, {
                              country: id,
                              area: city,
                            })
                          }
                        >
                          Download

                        {cityLocations.map(loc => (

                            <LocationCard
                              onDownloadClick={() =>
                                props._openDownloadModal({
                                  country: id,
                                  area: city,
                                  location: loc.name,
                                })
                              }
                              id={loc.id}
                              name={loc.name}
                              city={loc.city}
                              countryData={{ name: country.name }}
                              sourcesData={sourceList}
                              totalMeasurements={loc.measurements}
                              parametersList={loc.parameters}
                              lastUpdate={loc.lastUpdated}
                              collectionStart={loc.firstUpdated}
                              compact
                            />

                        ))}

              ))}

      )}
    </>
  );
}

Country.propTypes = {
  match: T.object,

  _openDownloadModal: T.func,

  countries: T.array,
  sources: T.array,
  parameters: T.array,

  latestMeasurements: T.shape({
    fetching: T.bool,
    fetched: T.bool,
    error: T.string,
    data: T.object,
  }),

  locations: T.shape({
    fetching: T.bool,
    fetched: T.bool,
    error: T.string,
    data: T.object,
  }),
};
<commit_msg>adds in modal<commit_after>import React, { useState, useEffect } from 'react';
import { PropTypes as T } from 'prop-types';
import { connect } from 'react-redux';
import _ from 'lodash';

import { formatThousands } from '../../utils/format';
import config from '../../config';
import { openDownloadModal } from '../../actions/action-creators';

import Header, { LoadingHeader, ErrorHeader } from '../../components/header';
import LoadingMessage from '../../components/loading-message';
import InfoMessage from '../../components/info-message';
import LocationCard from '../../components/location-card';
import CountryMap from './map';

const defaultLocations = {
  locationFetched: false,
  locationFetching: false,
  locationError: null,
  locations: null,
};

const defaultCountry = {
  countryFetched: false,
  countryFetching: false,
  countryError: null,
  country: null,
};

function Country(props) {
  const id = props.match.params.name;
  const [
    { locationFetched, locationFetching, locationError, locations },
    setLocations,
  ] = useState(defaultLocations);
  const [
    { countryFetched, countryFetching, countryError, country },
    setCountry,
  ] = useState(defaultCountry);

  useEffect(() => {
    const fetchLocations = id => {
      setLocations(state => ({
        ...state,
        locationFetching: true,
        locationError: null,
      }));
      let limit = 10000;
      fetch(`${config.api}/locations?limit=${limit}&country=${id}`)
        .then(response => {
          if (response.status >= 400) {
            throw new Error('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setLocations(state => ({
              ...state,
              fetched: true,
              locationFetching: false,
              locations: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setLocations(state => ({
              ...state,
              locationFetched: true,
              locationFetching: false,
              locationError: e,
            }));
          }
        );
    };

    const fetchCountry = id => {
      setCountry(state => ({
        ...state,
        countryFetching: true,
        countryError: null,
      }));
      let limit = 1;
      fetch(`${config.api}/countries?limit=${limit}&country=${id}`)
        .then(response => {
          if (response.status >= 400) {
            throw new Error('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setCountry(state => ({
              ...state,
              countryFetched: true,
              countryFetching: false,
              country: json.results[0],
            }));
          },
          e => {
            console.log('e', e);
            setCountry(state => ({
              ...state,
              countryFetched: true,
              countryFetching: false,
              countryError: e,
            }));
          }
        );
    };

    fetchLocations(id);
    fetchCountry(id);

    return () => {
      setLocations(defaultLocations);
      setCountry(defaultCountry);
    };
  }, []);

  function onDownloadClick(data) {
    // e && e.preventDefault();
    props._openDownloadModal(data);
  }

  // gets sources from locations and uses set to create an array with no duplicates
  const sourceList = locations
    ? Array.from(
        new Set(locations.map(loc => loc.sources[0]).map(JSON.stringify))
      ).map(JSON.parse)
    : null;

  let locationGroups = _(locations).sortBy('city').groupBy('city').value();

  return (
    <>
      {(countryError || !country) && <ErrorHeader />}
      {countryFetching && <LoadingHeader />}
      {country && locations && (

           1 ? 'locations' : 'location',
              },
              {
                number: formatThousands(country.count),
                label: 'measurements',
              },
              {
                number: sourceList.length,
                label: sourceList.length > 1 ? 'sources' : 'source',
              },
            ]}
            action={{
              api: config.apiDocs,
              download: () =>
                onDownloadClick({
                  country: id,
                }),
            }}
          />

            <CountryMap />
            {locationFetching && <LoadingMessage />}
            {locationError && <InfoMessage standardMessage />}

              {Object.entries(locationGroups).map(([city, cityLocations]) => (

                        {city}{' '}

                          {locations.length}{' '}
                          {locations.length > 1 ? 'locations' : 'location'}

                        <a
                          href="#"
                          className="location-download-button"
                          title={`Download ${city} data`}
                          onClick={() =>
                            onDownloadClick({
                              country: id,
                              area: city,
                            })
                          }
                        >
                          Download

                        {cityLocations.map(loc => (

                            <LocationCard
                              onDownloadClick={() =>
                                props._openDownloadModal({
                                  country: id,
                                  area: city,
                                  location: loc.name,
                                })
                              }
                              id={loc.id}
                              name={loc.name}
                              city={loc.city}
                              countryData={{ name: country.name }}
                              sourcesData={sourceList}
                              totalMeasurements={loc.measurements}
                              parametersList={loc.parameters}
                              lastUpdate={loc.lastUpdated}
                              collectionStart={loc.firstUpdated}
                              compact
                            />

                        ))}

              ))}

      )}
    </>
  );
}

Country.propTypes = {
  match: T.object,

  _openDownloadModal: T.func,

  countries: T.array,
  sources: T.array,
  parameters: T.array,

  latestMeasurements: T.shape({
    fetching: T.bool,
    fetched: T.bool,
    error: T.string,
    data: T.object,
  }),

  locations: T.shape({
    fetching: T.bool,
    fetched: T.bool,
    error: T.string,
    data: T.object,
  }),
};

// /////////////////////////////////////////////////////////////////// //
// Connect functions

function selector(state) {
  return {};
}

function dispatcher(dispatch) {
  return {
    _openDownloadModal: (...args) => dispatch(openDownloadModal(...args)),
  };
}

export default connect(selector, dispatcher)(Country);
<|endoftext|>


<commit_before>(function(env) {
    "use strict";
    env.ddg_spice_ruby_gems = function(api_result) {

        if (!api_result || api_result.length === 0) {
            return Spice.failed("ruby_gems");
        }

        // Get the original query.
        var script = $('[src*="/js/spice/ruby_gems/"]')[0];
        var source = $(script).attr("src");
        var query = source.match(/ruby_gems\/([^\/]*)/)[1];

        // Display the instant answer.
        Spice.add({
            id: "ruby_gems",
            name: "Software",
            data: api_result,
            meta: {
                sourceUrl: 'http://rubygems.org/search?utf8=%E2%9C%93&query=' + encodeURIComponent(query),
                sourceName: 'RubyGems',
                sourceIconUrl: 'http://rubygems.org/favicon.ico',
                total: api_result.length,
                itemType: "gems",
            },
            templates:{
                group: 'text',
                detail: false,
                item_detail: false,
                variants: {
                    tile: 'basic1',
                    tileTitle: '1line',
                    tileFooter: '2line',
                    tileSnippet: 'large'
                },
                options: {
                    footer: Spice.ruby_gems.footer
                }
            },
            normalize : function(item){
                var licenses = [];

                if (item.licenses) {
                    var keys = Object.keys(item.licenses);

                    for (var i = 0; i < keys.length; i++) {
                        licenses.push(item.licenses[keys[i]]);
                    };
                }

                return{
                    title: item.name + ' ' + item.version,
                    subtitle: item.authors,
                    url: item.project_uri,
                    description: item.info,
                    licenses: licenses.join(', '),
                    downloads: item.downloads
                }
            }
        });
    }
}(this));
<commit_msg>ruby_gems - commas in large number, helps<commit_after>(function(env) {
    "use strict";
    env.ddg_spice_ruby_gems = function(api_result) {

        if (!api_result || api_result.length === 0) {
            return Spice.failed("ruby_gems");
        }

        // Get the original query.
        var script = $('[src*="/js/spice/ruby_gems/"]')[0];
        var source = $(script).attr("src");
        var query = source.match(/ruby_gems\/([^\/]*)/)[1];

        // Display the instant answer.
        Spice.add({
            id: "ruby_gems",
            name: "Software",
            data: api_result,
            meta: {
                sourceUrl: 'http://rubygems.org/search?utf8=%E2%9C%93&query=' + encodeURIComponent(query),
                sourceName: 'RubyGems',
                sourceIconUrl: 'http://rubygems.org/favicon.ico',
                total: api_result.length,
                itemType: "gems",
            },
            templates:{
                group: 'text',
                detail: false,
                item_detail: false,
                variants: {
                    tile: 'basic1',
                    tileTitle: '1line',
                    tileFooter: '2line',
                    tileSnippet: 'large'
                },
                options: {
                    footer: Spice.ruby_gems.footer
                }
            },
            normalize : function(item){
                var licenses = [];

                if (item.licenses) {
                    var keys = Object.keys(item.licenses);

                    for (var i = 0; i < keys.length; i++) {
                        licenses.push(item.licenses[keys[i]]);
                    };
                }

                return{
                    title: item.name + ' ' + item.version,
                    subtitle: item.authors,
                    url: item.project_uri,
                    description: item.info,
                    licenses: licenses.join(', '),
                    // turns 11872454 to 11,872,454
                    downloads: item.downloads.toLocaleString()
                }
            }
        });
    }
}(this));
<|endoftext|>


<commit_before>define([
  'extensions/collections/matrix'
],
function (MatrixCollection) {
  var VisitorsRealtimeCollection = MatrixCollection.extend({

    apiName: "realtime",

    queryParams: function () {
      return {
        sort_by: "_timestamp:descending",
        limit: this.options.numTwoMinPeriodsToQuery || 722
      };
    },

    updateInterval: 120 * 1000,

    initialize: function (models, options) {
      MatrixCollection.prototype.initialize.apply(this, arguments);

      if (isClient) {
        clearInterval(this.timer);
        this.timer = setInterval(
          _.bind(this.fetch, this), this.updateInterval
        );
      }
    },

    parse: function (response) {

      return {
        id: 'realtime',
        title: 'Realtime',
        values: response.data.reverse()
      };

    },

    fetch: function (options) {
      options = _.extend({
        headers: {
          "cache-control": "max-age=120"
        }
      }, options);
      MatrixCollection.prototype.fetch.call(this, options);
    }
  });

  return VisitorsRealtimeCollection;
});
<commit_msg>Improve readability of hard-coded number<commit_after>define([
  'extensions/collections/matrix'
],
function (MatrixCollection) {
  var VisitorsRealtimeCollection = MatrixCollection.extend({

    apiName: "realtime",

    queryParams: function () {
      return {
        sort_by: "_timestamp:descending",
        limit: this.options.numTwoMinPeriodsToQuery || (((60/2) * 24) + 2)
      };
    },

    updateInterval: 120 * 1000,

    initialize: function (models, options) {
      MatrixCollection.prototype.initialize.apply(this, arguments);

      if (isClient) {
        clearInterval(this.timer);
        this.timer = setInterval(
          _.bind(this.fetch, this), this.updateInterval
        );
      }
    },

    parse: function (response) {

      return {
        id: 'realtime',
        title: 'Realtime',
        values: response.data.reverse()
      };

    },

    fetch: function (options) {
      options = _.extend({
        headers: {
          "cache-control": "max-age=120"
        }
      }, options);
      MatrixCollection.prototype.fetch.call(this, options);
    }
  });

  return VisitorsRealtimeCollection;
});
<|endoftext|>


<commit_before>export default [
    {
        "code": "AR",
        "languages": [
            {
                "code": "es-AR",
                "name": "Española"
            }
        ],
        "name": "Argentina"
    },
    {
        "code": "AT",
        "languages": [
            {
                "code": "de-AT",
                "name": "Deutsch"
            }
        ],
        "name": "Austria"
    },
    {
        "code": "BE",
        "languages": [
            {
                "code": "nl-BE",
                "name": "Nederlands"
            }
        ],
        "name": "Belgium"
    },
    {
        "code": "BG",
        "languages": [
            {
                "code": "bg-BG",
                "name": "Bulgarian"
            }
        ],
        "name": "Bulgaria"
    },
    {
        "code": "BR",
        "languages": [
            {
                "code": "pt-BR",
                "name": "Português"
            }
        ],
        "name": "Brazil"
    },
    {
        "code": "CA",
        "languages": [
            {
                "code": "en-CA",
                "name": "English"
            },
            {
                "code": "fr-CA",
                "name": "Le Français"
            }
        ],
        "name": "Canada"
    },
    {
        "code": "CL",
        "languages": [
            {
                "code": "es-CL",
                "name": "Española"
            }
        ],
        "name": "Chile"
    },
    {
        "code": "CN",
        "languages": [
            {
                "code": "zh-CN",
                "name": "汉语/漢語"
            }
        ],
        "name": "China"
    },
    {
        "code": "CR",
        "languages": [
            {
                "code": "hr-CR",
                "name": "Hrvatski"
            }
        ],
        "name": "Croatia"
    },
    {
        "code": "CZ",
        "languages": [
            {
                "code": "cs-CZ",
                "name": "čeština"
            }
        ],
        "name": "Czech Republic"
    },
    {
        "code": "DK",
        "languages": [
            {
                "code": "da-DK",
                "name": "Dansk"
            }
        ],
        "name": "Denmark"
    },
    {
        "code": "EE",
        "languages": [
            {
                "code": "et-EE",
                "name": "eesti keel"
            }
        ],
        "name": "Estonia"
    },
    {
        "code": "ET",
        "languages": [
            {
                "code": "am-ET",
                "name": "æmˈhærɪk"
            }
        ],
        "name": "Ethiopia"
    },
    {
        "code": "FI",
        "languages": [
            {
                "code": "fi-FI",
                "name": "Suomi"
            }
        ],
        "name": "Finland"
    },
    {
        "code": "FR",
        "languages": [
            {
                "code": "fr-FR",
                "name": "Le Français"
            }
        ],
        "name": "France"
    },
    {
        "code": "DE",
        "languages": [
            {
                "code": "de-DE",
                "name": "Deutsch"
            }
        ],
        "name": "Germany"
    },
    {
        "code": "GR",
        "languages": [
            {
                "code": "el-GR",
                "name": "ελληνικά"
            }
        ],
        "name": "Greece"
    },
    {
        "code": "HK",
        "languages": [
            {
                "code": "code",
                "name": "汉语/漢語"
            }
        ],
        "name": "Hong Kong"
    },
    {
        "code": "HU",
        "languages": [
            {
                "code": "hu-HU",
                "name": "Magyar"
            }
        ],
        "name": "Hungary"
    },
    {
        "code": "IS",
        "languages": [
            {
                "code": "is-IS",
                "name": "Icelandic"
            }
        ],
        "name": "Iceland"
    },
    {
        "code": "IN",
        "languages": [
            {
                "code": "en-IN",
                "name": "English"
            },
            {
                "code": "mr-IN",
                "name": "मराठी"
            },
            {
                "code": "hi-IN",
                "name": "हिंदी"
            }
        ],
        "name": "India"
    },
    {
        "code": "ID",
        "languages": [
            {
                "code": "id-ID",
                "name": "Bahasa Indonesia"
            }
        ],
        "name": "Indonesia"
    },
    {
        "code": "IL",
        "languages": [
            {
                "code": "he-IL",
                "name": "עִברִית"
            }
        ],
        "name": "Israel"
    },
    {
        "code": "IT",
        "languages": [
            {
                "code": "it-IT",
                "name": "Italiano"
            }
        ],
        "name": "Italy"
    },
    {
        "code": "JP",
        "languages": [
            {
                "code": "ja-JP",
                "name": "日本語"
            }
        ],
        "name": "Japan"
    },
    {
        "code": "JO",
        "languages": [
            {
                "code": "ar-JO",
                "name": "العربية"
            }
        ],
        "name": "Jordan"
    },
    {
        "code": "LV",
        "languages": [
            {
                "code": "lv-LV",
                "name": "Latvijas"
            }
        ],
        "name": "Latvia"
    },
    {
        "code": "LT",
        "languages": [
            {
                "code": "lt-LT",
                "name": "Lietuvos"
            }
        ],
        "name": "Lithuania"
    },
    {
        "code": "MK",
        "languages": [
            {
                "code": "mk-MK",
                "name": "Македонски"
            }
        ],
        "name": "Macedonia"
    },
    {
        "code": "MY",
        "languages": [
            {
                "code": "ms-MY",
                "name": "Malay"
            }
        ],
        "name": "Malaysia"
    },
    {
        "code": "MX",
        "languages": [
            {
                "code": "es-mx",
                "name": "Española"
            }
        ],
        "name": "Mexico"
    },
    {
        "code": "NL",
        "languages": [
            {
                "code": "nl-NL",
                "name": "Nederlands"
            }
        ],
        "name": "Netherlands"
    },
    {
        "code": "NZ",
        "languages": [
            {
                "code": "en-NZ",
                "name": "English"
            }
        ],
        "name": "New Zealand"
    },
    {
        "code": "NG",
        "languages": [
            {
                "code": "en-NG",
                "name": "English"
            }
        ],
        "name": "Nigeria"
    },
    {
        "code": "NO",
        "languages": [
            {
                "code": "no-NO",
                "name": "Norsk"
            }
        ],
        "name": "Norway"
    },
    {
        "code": "PK",
        "languages": [
            {
                "code": "ur-PK",
                "name": "اردو"
            }
        ],
        "name": "Pakistan"
    },
    {
        "code": "PS",
        "languages": [
            {
                "code": "ar-PS",
                "name": "العربية"
            }
        ],
        "name": "Palestine"
    },
    {
        "code": "PE",
        "languages": [
            {
                "code": "es-PE",
                "name": "Española"
            }
        ],
        "name": "Peru"
    },
    {
        "code": "PH",
        "languages": [
            {
                "code": "en-PH",
                "name": "English"
            }
        ],
        "name": "Philippines"
    },
    {
        "code": "PL",
        "languages": [
            {
                "code": "pl-PL",
                "name": "Język polski"
            }
        ],
        "name": "Poland"
    },
    {
        "code": "PT",
        "languages": [
            {
                "code": "pt-PT",
                "name": "Português"
            }
        ],
        "name": "Portugal"
    },
    {
        "code": "RO",
        "languages": [
            {
                "code": "ro-RO",
                "name": "Română"
            }
        ],
        "name": "Romania"
    },
    {
        "code": "RU",
        "languages": [
            {
                "code": "ru-RU",
                "name": "русский"
            }
        ],
        "name": "Russia"
    },
    {
        "code": "SN",
        "languages": [
            {
                "code": "fr-SN",
                "name": "Le Français"
            }
        ],
        "name": "Senegal"
    },
    {
        "code": "RS",
        "languages": [
            {
                "code": "sr-SP",
                "name": "Cрпски"
            }
        ],
        "name": "Serbia"
    },
    {
        "code": "SG",
        "languages": [
            {
                "code": "en-SG",
                "name": "English"
            }
        ],
        "name": "Singapore"
    },
    {
        "code": "SK",
        "languages": [
            {
                "code": "sk-SK",
                "name": "Slovenský"
            }
        ],
        "name": "Slovakia"
    },
    {
        "code": "SI",
        "languages": [
            {
                "code": "sl-SI",
                "name": "Slovenski"
            }
        ],
        "name": "Slovenia"
    },
    {
        "code": "KR",
        "languages": [
            {
                "code": "ko-KR",
                "name": "한국어/조선말"
            }
        ],
        "name": "South Korea"
    },
    {
        "code": "ES",
        "languages": [
            {
                "code": "ca-ES",
                "name": "Català"
            },
            {
                "code": "es-es",
                "name": "Española"
            }
        ],
        "name": "Spain"
    },
    {
        "code": "SE",
        "languages": [
            {
                "code": "sv-SE",
                "name": "Svenska"
            }
        ],
        "name": "Sweden"
    },
    {
        "code": "CH",
        "languages": [
            {
                "code": "fr-CH",
                "name": "Le Français"
            },
            {
                "code": "de-CH",
                "name": "Deutsch"
            }
        ],
        "name": "Switzerland"
    },
    {
        "code": "TH",
        "languages": [
            {
                "code": "th-TH",
                "name": "ไทย"
            }
        ],
        "name": "Thailand"
    },
    {
        "code": "TR",
        "languages": [
            {
                "code": "tr-TR",
                "name": "Türk"
            }
        ],
        "name": "Turkey"
    },
    {
        "code": "UG",
        "languages": [
            {
                "code": "en-UG",
                "name": "English"
            },
            {
                "code": "lg-UG",
                "name": "Oluganda"
            },
            {
                "code": "rk-UG",
                "name": "Runyankore"
            }
        ],
        "name": "Uganda"
    },
    {
        "code": "UA",
        "languages": [
            {
                "code": "uk-UA",
                "name": "український"
            },
            {
                "code": "ru-UA",
                "name": "русский"
            }
        ],
        "name": "Ukraine"
    },
    {
        "code": "AE",
        "languages": [
            {
                "code": "en-AE",
                "name": "English"
            },
            {
                "code": "ar-AE",
                "name": "العربية"
            }
        ],
        "name": "United Arab Emirates"
    },
    {
        "code": "GB",
        "languages": [
            {
                "code": "en-GB",
                "name": "English"
            }
        ],
        "name": "United Kingdom"
    },
    {
        "code": "US",
        "languages": [
            {
                "code": "en-US",
                "name": "English"
            }
        ],
        "name": "USA"
    },
    {
        "code": "VN",
        "languages": [
            {
                "code": "vi-VN",
                "name": "tiếng việt"
            }
        ],
        "name": "Vietnam"
    }
];
<commit_msg>Add more missing languages to flag-picker<commit_after>export default [
    {
        "code": "AR",
        "languages": [
            {
                "code": "es-AR",
                "name": "Española"
            }
        ],
        "name": "Argentina"
    },
    {
        "code": "AT",
        "languages": [
            {
                "code": "de-AT",
                "name": "Deutsch"
            }
        ],
        "name": "Austria"
    },
    {
        "code": "AU",
        "languages": [
            {
                "code": "en-AU",
                "name": "English"
            }
        ],
        "name": "Australia"
    },
    {
        "code": "BE",
        "languages": [
            {
                "code": "nl-BE",
                "name": "Nederlands"
            }
        ],
        "name": "Belgium"
    },
    {
        "code": "BG",
        "languages": [
            {
                "code": "bg-BG",
                "name": "Bulgarian"
            }
        ],
        "name": "Bulgaria"
    },
    {
        "code": "BR",
        "languages": [
            {
                "code": "pt-BR",
                "name": "Português"
            }
        ],
        "name": "Brazil"
    },
    {
        "code": "CA",
        "languages": [
            {
                "code": "en-CA",
                "name": "English"
            },
            {
                "code": "fr-CA",
                "name": "Le Français"
            }
        ],
        "name": "Canada"
    },
    {
        "code": "CL",
        "languages": [
            {
                "code": "es-CL",
                "name": "Española"
            }
        ],
        "name": "Chile"
    },
    {
        "code": "CN",
        "languages": [
            {
                "code": "zh-CN",
                "name": "汉语/漢語"
            }
        ],
        "name": "China"
    },
    {
        "code": "CR",
        "languages": [
            {
                "code": "hr-CR",
                "name": "Hrvatski"
            }
        ],
        "name": "Croatia"
    },
    {
        "code": "CZ",
        "languages": [
            {
                "code": "cs-CZ",
                "name": "čeština"
            }
        ],
        "name": "Czech Republic"
    },
    {
        "code": "DK",
        "languages": [
            {
                "code": "da-DK",
                "name": "Dansk"
            }
        ],
        "name": "Denmark"
    },
    {
        "code": "EE",
        "languages": [
            {
                "code": "et-EE",
                "name": "eesti keel"
            }
        ],
        "name": "Estonia"
    },
    {
        "code": "ET",
        "languages": [
            {
                "code": "am-ET",
                "name": "æmˈhærɪk"
            }
        ],
        "name": "Ethiopia"
    },
    {
        "code": "FI",
        "languages": [
            {
                "code": "fi-FI",
                "name": "Suomi"
            }
        ],
        "name": "Finland"
    },
    {
        "code": "FR",
        "languages": [
            {
                "code": "fr-FR",
                "name": "Le Français"
            }
        ],
        "name": "France"
    },
    {
        "code": "DE",
        "languages": [
            {
                "code": "de-DE",
                "name": "Deutsch"
            }
        ],
        "name": "Germany"
    },
    {
        "code": "GR",
        "languages": [
            {
                "code": "el-GR",
                "name": "ελληνικά"
            }
        ],
        "name": "Greece"
    },
    {
        "code": "HK",
        "languages": [
            {
                "code": "code",
                "name": "汉语/漢語"
            }
        ],
        "name": "Hong Kong"
    },
    {
        "code": "HU",
        "languages": [
            {
                "code": "hu-HU",
                "name": "Magyar"
            }
        ],
        "name": "Hungary"
    },
    {
        "code": "IS",
        "languages": [
            {
                "code": "is-IS",
                "name": "Icelandic"
            }
        ],
        "name": "Iceland"
    },
    {
        "code": "IN",
        "languages": [
            {
                "code": "en-IN",
                "name": "English"
            },
            {
                "code": "mr-IN",
                "name": "मराठी"
            },
            {
                "code": "hi-IN",
                "name": "हिंदी"
            }
        ],
        "name": "India"
    },
    {
        "code": "ID",
        "languages": [
            {
                "code": "id-ID",
                "name": "Bahasa Indonesia"
            }
        ],
        "name": "Indonesia"
    },
    {
        "code": "IL",
        "languages": [
            {
                "code": "he-IL",
                "name": "עִברִית"
            }
        ],
        "name": "Israel"
    },
    {
        "code": "IT",
        "languages": [
            {
                "code": "it-IT",
                "name": "Italiano"
            }
        ],
        "name": "Italy"
    },
    {
        "code": "JP",
        "languages": [
            {
                "code": "ja-JP",
                "name": "日本語"
            }
        ],
        "name": "Japan"
    },
    {
        "code": "JO",
        "languages": [
            {
                "code": "ar-JO",
                "name": "العربية"
            }
        ],
        "name": "Jordan"
    },
    {
        "code": "LV",
        "languages": [
            {
                "code": "lv-LV",
                "name": "Latvijas"
            }
        ],
        "name": "Latvia"
    },
    {
        "code": "LT",
        "languages": [
            {
                "code": "lt-LT",
                "name": "Lietuvos"
            }
        ],
        "name": "Lithuania"
    },
    {
        "code": "MK",
        "languages": [
            {
                "code": "mk-MK",
                "name": "Македонски"
            }
        ],
        "name": "Macedonia"
    },
    {
        "code": "MY",
        "languages": [
            {
                "code": "ms-MY",
                "name": "Malay"
            }
        ],
        "name": "Malaysia"
    },
    {
        "code": "MX",
        "languages": [
            {
                "code": "es-mx",
                "name": "Española"
            }
        ],
        "name": "Mexico"
    },
    {
        "code": "NL",
        "languages": [
            {
                "code": "nl-NL",
                "name": "Nederlands"
            }
        ],
        "name": "Netherlands"
    },
    {
        "code": "NZ",
        "languages": [
            {
                "code": "en-NZ",
                "name": "English"
            }
        ],
        "name": "New Zealand"
    },
    {
        "code": "NG",
        "languages": [
            {
                "code": "en-NG",
                "name": "English"
            }
        ],
        "name": "Nigeria"
    },
    {
        "code": "NO",
        "languages": [
            {
                "code": "no-NO",
                "name": "Norsk"
            }
        ],
        "name": "Norway"
    },
    {
        "code": "PK",
        "languages": [
            {
                "code": "en-PK",
                "name": "English"
            },
            {
                "code": "ur-PK",
                "name": "اردو"
            }
        ],
        "name": "Pakistan"
    },
    {
        "code": "PS",
        "languages": [
            {
                "code": "ar-PS",
                "name": "العربية"
            }
        ],
        "name": "Palestine"
    },
    {
        "code": "PE",
        "languages": [
            {
                "code": "es-PE",
                "name": "Española"
            }
        ],
        "name": "Peru"
    },
    {
        "code": "PH",
        "languages": [
            {
                "code": "en-PH",
                "name": "English"
            }
        ],
        "name": "Philippines"
    },
    {
        "code": "PL",
        "languages": [
            {
                "code": "pl-PL",
                "name": "Język polski"
            }
        ],
        "name": "Poland"
    },
    {
        "code": "PT",
        "languages": [
            {
                "code": "pt-PT",
                "name": "Português"
            }
        ],
        "name": "Portugal"
    },
    {
        "code": "RO",
        "languages": [
            {
                "code": "ro-RO",
                "name": "Română"
            }
        ],
        "name": "Romania"
    },
    {
        "code": "RU",
        "languages": [
            {
                "code": "ru-RU",
                "name": "русский"
            }
        ],
        "name": "Russia"
    },
    {
        "code": "SN",
        "languages": [
            {
                "code": "fr-SN",
                "name": "Le Français"
            }
        ],
        "name": "Senegal"
    },
    {
        "code": "RS",
        "languages": [
            {
                "code": "sr-SP",
                "name": "Cрпски"
            }
        ],
        "name": "Serbia"
    },
    {
        "code": "SG",
        "languages": [
            {
                "code": "en-SG",
                "name": "English"
            }
        ],
        "name": "Singapore"
    },
    {
        "code": "SK",
        "languages": [
            {
                "code": "sk-SK",
                "name": "Slovenský"
            }
        ],
        "name": "Slovakia"
    },
    {
        "code": "SI",
        "languages": [
            {
                "code": "sl-SI",
                "name": "Slovenski"
            }
        ],
        "name": "Slovenia"
    },
    {
        "code": "KR",
        "languages": [
            {
                "code": "ko-KR",
                "name": "한국어/조선말"
            }
        ],
        "name": "South Korea"
    },
    {
        "code": "ES",
        "languages": [
            {
                "code": "ca-ES",
                "name": "Català"
            },
            {
                "code": "es-ES",
                "name": "Española"
            }
        ],
        "name": "Spain"
    },
    {
        "code": "SE",
        "languages": [
            {
                "code": "sv-SE",
                "name": "Svenska"
            }
        ],
        "name": "Sweden"
    },
    {
        "code": "CH",
        "languages": [
            {
                "code": "fr-CH",
                "name": "Le Français"
            },
            {
                "code": "de-CH",
                "name": "Deutsch"
            }
        ],
        "name": "Switzerland"
    },
    {
        "code": "TH",
        "languages": [
            {
                "code": "th-TH",
                "name": "ไทย"
            }
        ],
        "name": "Thailand"
    },
    {
        "code": "TR",
        "languages": [
            {
                "code": "tr-TR",
                "name": "Türk"
            }
        ],
        "name": "Turkey"
    },
    {
        "code": "UG",
        "languages": [
            {
                "code": "en-UG",
                "name": "English"
            },
            {
                "code": "lg-UG",
                "name": "Oluganda"
            },
            {
                "code": "rk-UG",
                "name": "Runyankore"
            }
        ],
        "name": "Uganda"
    },
    {
        "code": "UA",
        "languages": [
            {
                "code": "uk-UA",
                "name": "український"
            },
            {
                "code": "ru-UA",
                "name": "русский"
            }
        ],
        "name": "Ukraine"
    },
    {
        "code": "AE",
        "languages": [
            {
                "code": "en-AE",
                "name": "English"
            },
            {
                "code": "ar-AE",
                "name": "العربية"
            }
        ],
        "name": "United Arab Emirates"
    },
    {
        "code": "GB",
        "languages": [
            {
                "code": "en-GB",
                "name": "English"
            }
        ],
        "name": "United Kingdom"
    },
    {
        "code": "US",
        "languages": [
            {
                "code": "en-US",
                "name": "English"
            }
        ],
        "name": "USA"
    },
    {
        "code": "VN",
        "languages": [
            {
                "code": "vi-VN",
                "name": "tiếng việt"
            }
        ],
        "name": "Vietnam"
    }
];
<|endoftext|>


<commit_before>/***
 * Contains basic SlickGrid editors.
 * @module Editors
 * @namespace Slick
 */

(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "Editors": {
        "Text": TextEditor,
        "Integer": IntegerEditor,
		"Float": FloatEditor,
        "Date": DateEditor,
        "YesNoSelect": YesNoSelectEditor,
        "Checkbox": CheckboxEditor,
        "PercentComplete": PercentCompleteEditor,
        "LongText": LongTextEditor
      }
    }
  });

  function TextEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />")
          .appendTo(args.container)
          .bind("keydown.nav", function (e) {
            if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
              e.stopImmediatePropagation();
            }
          })
          .focus()
          .select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.getValue = function () {
      return $input.val();
    };

    this.setValue = function (val) {
      $input.val(val);
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field] || "";
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function IntegerEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");

      $input.bind("keydown.nav", function (e) {
        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
          e.stopImmediatePropagation();
        }
      });

      $input.appendTo(args.container);
      $input.focus().select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return parseInt($input.val(), 10) || 0;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (isNaN($input.val())) {
        return {
          valid: false,
          msg: "Please enter a valid integer"
        };
      }

      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function FloatEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");

      $input.bind("keydown.nav", function (e) {
        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
          e.stopImmediatePropagation();
        }
      });

      $input.appendTo(args.container);
      $input.focus().select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

	function getDecimalPlaces() {
		// returns the number of fixed decimal places or null
		var rtn = args.column.editorFixedDecimalPlaces;
		if (typeof rtn == 'undefined') {
			rtn = FloatEditor.DefaultDecimalPlaces;
		}
		return (!rtn && rtn!==0 ? null : rtn);
	}

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];

	  var decPlaces = getDecimalPlaces();
	  if (decPlaces !== null
	  && (defaultValue || defaultValue===0)
	  && defaultValue.toFixed) {
		defaultValue = defaultValue.toFixed(decPlaces);
	  }

      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
	  var rtn = parseFloat($input.val()) || 0;

	  var decPlaces = getDecimalPlaces();
	  if (decPlaces !== null
	  && (rtn || rtn===0)
	  && rtn.toFixed) {
		rtn = parseFloat(rtn.toFixed(decPlaces));
	  }

      return rtn;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (isNaN($input.val())) {
        return {
          valid: false,
          msg: "Please enter a valid number"
        };
      }

      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  FloatEditor.DefaultDecimalPlaces = null;

  function DateEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;
    var calendarOpen = false;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");
      $input.appendTo(args.container);
      $input.focus().select();
      $input.datepicker({
        showOn: "button",
        buttonImageOnly: true,
        buttonImage: "../images/calendar.gif",
        beforeShow: function () {
          calendarOpen = true
        },
        onClose: function () {
          calendarOpen = false
        }
      });
      $input.width($input.width() - 18);
    };

    this.destroy = function () {
      $.datepicker.dpDiv.stop(true, true);
      $input.datepicker("hide");
      $input.datepicker("destroy");
      $input.remove();
    };

    this.show = function () {
      if (calendarOpen) {
        $.datepicker.dpDiv.stop(true, true).show();
      }
    };

    this.hide = function () {
      if (calendarOpen) {
        $.datepicker.dpDiv.stop(true, true).hide();
      }
    };

    this.position = function (position) {
      if (!calendarOpen) {
        return;
      }
      $.datepicker.dpDiv
          .css("top", position.top + 30)
          .css("left", position.left);
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function YesNoSelectEditor(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");
      $select.appendTo(args.container);
      $select.focus();
    };

    this.destroy = function () {
      $select.remove();
    };

    this.focus = function () {
      $select.focus();
    };

    this.loadValue = function (item) {
      $select.val((defaultValue = item[args.column.field]) ? "yes" : "no");
      $select.select();
    };

    this.serializeValue = function () {
      return ($select.val() == "yes");
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return ($select.val() != defaultValue);
    };

    this.validate = function () {
      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function CheckboxEditor(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus>");
      $select.appendTo(args.container);
      $select.focus();
    };

    this.destroy = function () {
      $select.remove();
    };

    this.focus = function () {
      $select.focus();
    };

    this.loadValue = function (item) {
      defaultValue = !!item[args.column.field];
      if (defaultValue) {
        $select.prop('checked', true);
      } else {
        $select.prop('checked', false);
      }
    };

    this.serializeValue = function () {
      return $select.prop('checked');
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (this.serializeValue() !== defaultValue);
    };

    this.validate = function () {
      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function PercentCompleteEditor(args) {
    var $input, $picker;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-percentcomplete' />");
      $input.width($(args.container).innerWidth() - 25);
      $input.appendTo(args.container);

      $picker = $("
").appendTo(args.container);
      $picker.append("

");

      $picker.find(".editor-percentcomplete-buttons").append("<button val=0>Not started</button>
<button val=50>In Progress</button>
<button val=100>Complete</button>");

      $input.focus().select();

      $picker.find(".editor-percentcomplete-slider").slider({
        orientation: "vertical",
        range: "min",
        value: defaultValue,
        slide: function (event, ui) {
          $input.val(ui.value)
        }
      });

      $picker.find(".editor-percentcomplete-buttons button").bind("click", function (e) {
        $input.val($(this).attr("val"));
        $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
      })
    };

    this.destroy = function () {
      $input.remove();
      $picker.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      $input.val(defaultValue = item[args.column.field]);
      $input.select();
    };

    this.serializeValue = function () {
      return parseInt($input.val(), 10) || 0;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
    };

    this.validate = function () {
      if (isNaN(parseInt($input.val(), 10))) {
        return {
          valid: false,
          msg: "Please enter a valid positive number"
        };
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  /*
   * An example of a "detached" editor.
   * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.
   * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
   */
  function LongTextEditor(args) {
    var $input, $wrapper;
    var defaultValue;
    var scope = this;

    this.init = function () {
      var $container = $("body");

      $wrapper = $("
")
          .appendTo($container);

      $input = $("<TEXTAREA hidefocus rows=5 style='backround:white;width:250px;height:80px;border:0;outline:0'>")
          .appendTo($wrapper);

      $("
<BUTTON>Save</BUTTON><BUTTON>Cancel</BUTTON>
")
          .appendTo($wrapper);

      $wrapper.find("button:first").bind("click", this.save);
      $wrapper.find("button:last").bind("click", this.cancel);
      $input.bind("keydown", this.handleKeyDown);

      scope.position(args.position);
      $input.focus().select();
    };

    this.handleKeyDown = function (e) {
      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
        scope.save();
      } else if (e.which == $.ui.keyCode.ESCAPE) {
        e.preventDefault();
        scope.cancel();
      } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
        e.preventDefault();
        args.grid.navigatePrev();
      } else if (e.which == $.ui.keyCode.TAB) {
        e.preventDefault();
        args.grid.navigateNext();
      }
    };

    this.save = function () {
      args.commitChanges();
    };

    this.cancel = function () {
      $input.val(defaultValue);
      args.cancelChanges();
    };

    this.hide = function () {
      $wrapper.hide();
    };

    this.show = function () {
      $wrapper.show();
    };

    this.position = function (position) {
      $wrapper
          .css("top", position.top - 5)
          .css("left", position.left - 5)
    };

    this.destroy = function () {
      $wrapper.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      $input.val(defaultValue = item[args.column.field]);
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }
})(jQuery);
<commit_msg>Improve datepicker editor<commit_after>/***
 * Contains basic SlickGrid editors.
 * @module Editors
 * @namespace Slick
 */

(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "Editors": {
        "Text": TextEditor,
        "Integer": IntegerEditor,
		"Float": FloatEditor,
        "Date": DateEditor,
        "YesNoSelect": YesNoSelectEditor,
        "Checkbox": CheckboxEditor,
        "PercentComplete": PercentCompleteEditor,
        "LongText": LongTextEditor
      }
    }
  });

  function TextEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />")
          .appendTo(args.container)
          .bind("keydown.nav", function (e) {
            if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
              e.stopImmediatePropagation();
            }
          })
          .focus()
          .select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.getValue = function () {
      return $input.val();
    };

    this.setValue = function (val) {
      $input.val(val);
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field] || "";
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function IntegerEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");

      $input.bind("keydown.nav", function (e) {
        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
          e.stopImmediatePropagation();
        }
      });

      $input.appendTo(args.container);
      $input.focus().select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return parseInt($input.val(), 10) || 0;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (isNaN($input.val())) {
        return {
          valid: false,
          msg: "Please enter a valid integer"
        };
      }

      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function FloatEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");

      $input.bind("keydown.nav", function (e) {
        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
          e.stopImmediatePropagation();
        }
      });

      $input.appendTo(args.container);
      $input.focus().select();
    };

    this.destroy = function () {
      $input.remove();
    };

    this.focus = function () {
      $input.focus();
    };

	function getDecimalPlaces() {
		// returns the number of fixed decimal places or null
		var rtn = args.column.editorFixedDecimalPlaces;
		if (typeof rtn == 'undefined') {
			rtn = FloatEditor.DefaultDecimalPlaces;
		}
		return (!rtn && rtn!==0 ? null : rtn);
	}

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];

	  var decPlaces = getDecimalPlaces();
	  if (decPlaces !== null
	  && (defaultValue || defaultValue===0)
	  && defaultValue.toFixed) {
		defaultValue = defaultValue.toFixed(decPlaces);
	  }

      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
	  var rtn = parseFloat($input.val()) || 0;

	  var decPlaces = getDecimalPlaces();
	  if (decPlaces !== null
	  && (rtn || rtn===0)
	  && rtn.toFixed) {
		rtn = parseFloat(rtn.toFixed(decPlaces));
	  }

      return rtn;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (isNaN($input.val())) {
        return {
          valid: false,
          msg: "Please enter a valid number"
        };
      }

      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  FloatEditor.DefaultDecimalPlaces = null;

  function DateEditor(args) {
    var $input;
    var defaultValue;
    var scope = this;
    var calendarOpen = false;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-text' />");
      $input.appendTo(args.container);
      $input.focus().select();
      $input.datepicker({
        showOn: "button",
        buttonImageOnly: true,
        beforeShow: function () {
          calendarOpen = true
        },
        onClose: function () {
          calendarOpen = false
        }
      });
      $input.width($input.width() - 18);
    };

    this.destroy = function () {
      $.datepicker.dpDiv.stop(true, true);
      $input.datepicker("hide");
      $input.datepicker("destroy");
      $input.remove();
    };

    this.show = function () {
      if (calendarOpen) {
        $.datepicker.dpDiv.stop(true, true).show();
      }
    };

    this.hide = function () {
      if (calendarOpen) {
        $.datepicker.dpDiv.stop(true, true).hide();
      }
    };

    this.position = function (position) {
      if (!calendarOpen) {
        return;
      }
      $.datepicker.dpDiv
          .css("top", position.top + 30)
          .css("left", position.left);
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      defaultValue = item[args.column.field];
      $input.val(defaultValue);
      $input[0].defaultValue = defaultValue;
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function YesNoSelectEditor(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");
      $select.appendTo(args.container);
      $select.focus();
    };

    this.destroy = function () {
      $select.remove();
    };

    this.focus = function () {
      $select.focus();
    };

    this.loadValue = function (item) {
      $select.val((defaultValue = item[args.column.field]) ? "yes" : "no");
      $select.select();
    };

    this.serializeValue = function () {
      return ($select.val() == "yes");
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return ($select.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function CheckboxEditor(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus>");
      $select.appendTo(args.container);
      $select.focus();
    };

    this.destroy = function () {
      $select.remove();
    };

    this.focus = function () {
      $select.focus();
    };

    this.loadValue = function (item) {
      defaultValue = !!item[args.column.field];
      if (defaultValue) {
        $select.prop('checked', true);
      } else {
        $select.prop('checked', false);
      }
    };

    this.serializeValue = function () {
      return $select.prop('checked');
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (this.serializeValue() !== defaultValue);
    };

    this.validate = function () {
      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  function PercentCompleteEditor(args) {
    var $input, $picker;
    var defaultValue;
    var scope = this;

    this.init = function () {
      $input = $("<INPUT type=text class='editor-percentcomplete' />");
      $input.width($(args.container).innerWidth() - 25);
      $input.appendTo(args.container);

      $picker = $("
").appendTo(args.container);
      $picker.append("

");

      $picker.find(".editor-percentcomplete-buttons").append("<button val=0>Not started</button>
<button val=50>In Progress</button>
<button val=100>Complete</button>");

      $input.focus().select();

      $picker.find(".editor-percentcomplete-slider").slider({
        orientation: "vertical",
        range: "min",
        value: defaultValue,
        slide: function (event, ui) {
          $input.val(ui.value)
        }
      });

      $picker.find(".editor-percentcomplete-buttons button").bind("click", function (e) {
        $input.val($(this).attr("val"));
        $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
      })
    };

    this.destroy = function () {
      $input.remove();
      $picker.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      $input.val(defaultValue = item[args.column.field]);
      $input.select();
    };

    this.serializeValue = function () {
      return parseInt($input.val(), 10) || 0;
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
    };

    this.validate = function () {
      if (isNaN(parseInt($input.val(), 10))) {
        return {
          valid: false,
          msg: "Please enter a valid positive number"
        };
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }

  /*
   * An example of a "detached" editor.
   * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.
   * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
   */
  function LongTextEditor(args) {
    var $input, $wrapper;
    var defaultValue;
    var scope = this;

    this.init = function () {
      var $container = $("body");

      $wrapper = $("
")
          .appendTo($container);

      $input = $("<TEXTAREA hidefocus rows=5 style='backround:white;width:250px;height:80px;border:0;outline:0'>")
          .appendTo($wrapper);

      $("
<BUTTON>Save</BUTTON><BUTTON>Cancel</BUTTON>
")
          .appendTo($wrapper);

      $wrapper.find("button:first").bind("click", this.save);
      $wrapper.find("button:last").bind("click", this.cancel);
      $input.bind("keydown", this.handleKeyDown);

      scope.position(args.position);
      $input.focus().select();
    };

    this.handleKeyDown = function (e) {
      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
        scope.save();
      } else if (e.which == $.ui.keyCode.ESCAPE) {
        e.preventDefault();
        scope.cancel();
      } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
        e.preventDefault();
        args.grid.navigatePrev();
      } else if (e.which == $.ui.keyCode.TAB) {
        e.preventDefault();
        args.grid.navigateNext();
      }
    };

    this.save = function () {
      args.commitChanges();
    };

    this.cancel = function () {
      $input.val(defaultValue);
      args.cancelChanges();
    };

    this.hide = function () {
      $wrapper.hide();
    };

    this.show = function () {
      $wrapper.show();
    };

    this.position = function (position) {
      $wrapper
          .css("top", position.top - 5)
          .css("left", position.left - 5)
    };

    this.destroy = function () {
      $wrapper.remove();
    };

    this.focus = function () {
      $input.focus();
    };

    this.loadValue = function (item) {
      $input.val(defaultValue = item[args.column.field]);
      $input.select();
    };

    this.serializeValue = function () {
      return $input.val();
    };

    this.applyValue = function (item, state) {
      item[args.column.field] = state;
    };

    this.isValueChanged = function () {
      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
    };

    this.validate = function () {
      if (args.column.validator) {
        var validationResults = args.column.validator($input.val());
        if (!validationResults.valid) {
          return validationResults;
        }
      }

      return {
        valid: true,
        msg: null
      };
    };

    this.init();
  }
})(jQuery);
<|endoftext|>


<commit_before>/*
 * prefixes.js - Add/remove and view alternative prefixes
 *
 * Contributed by Ovyerus
 */

const fs = require('fs');
const utils = require(`${__baseDir}/modules/utils.js`);

exports.loadAsSubcommands = true;

exports.commands = [
    'add',
    'remove'
];

exports.main = {
    desc: 'View the various prefixes used by the bot and edit them.',
    fullDesc: 'Prefixes command. If no arguments are supplied or are not the correct ones, it just displays the available prefixes. Adding and removing prefixes are only allowed by the bot owners(s)',
    usage: '[<add|remove> <prefix>]',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            let prefixes = JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`));
            let embed = {
                title: 'Current Prefixes',
                description: `Displaying **${prefixes.length + 2}** prefixes.`,
                fields: [
                    {name: 'Internal Prefixes', value: `\`${bot.config.mainPrefix}\`\n\`@mention\``}
                ]
            };

            if (prefixes.length > 0) {
                embed.fields.push({name: 'External Prefixes', value: []});
                prefixes.forEach(prefix => embed.fields[1].value.push(prefix.endsWith(' ') ? `\`${prefix}\u200b\`` : `\`${prefix}\``));
                embed.fields[1].value = embed.fields[1].value.join('\n');
            }

            ctx.msg.channel.createMessage({embed}).then(resolve).catch(reject);
        });
    }
};

exports.add = {
    desc: 'Add a prefix.',
    usage: '<prefix>',
    adminOnly: true,
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0) {
                ctx.msg.channel.createMessage('Please give me a prefix to add.').then(resolve).catch(reject);
            } else {
                let prefix = ctx.args.join(' ');
                let newPrefixes = JSON.stringify(JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`)).concat(prefix));
                fs.writeFile(`${__baseDir}/data/prefixes.json`, newPrefixes, err => {
                    if (err) {
                        reject(err);
                    } else {
                        ctx.msg.channel.createMessage(`Added prefix \`${prefix}\``).then(resolve).catch(reject);
                    }
                });
            }
        });
    }
};

exports.remove = {
    desc: 'Remove a prefix.',
    usage: '<prefix>',
    adminOnly: true,
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0) {
                ctx.msg.channel.createMessage('Please give me a prefix to remove.').then(resolve).catch(reject);
            } else {
                let prefix = ctx.args.join(' ');
                let prefixes = JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`));
                let newPrefixes = prefixes.filter(p => p !== prefix);
                console.log(newPrefixes)

                if (newPrefixes.equals(prefixes)) {
                    ctx.msg.channel.createMessage("That prefix doesn't exist or can't be removed.");
                } else {
                    fs.writeFile(`${__baseDir}/data/prefixes.json`, JSON.stringify(newPrefixes), err => {
                        if (err) {
                            reject(err);
                        } else {
                            ctx.msg.channel.createMessage(`Removed prefixes \`${prefix}\``).then(resolve).catch(reject);
                        }
                    });
                }
            }
        });
    }
};

Array.prototype.equals = array => {
    if (!array || this.length !== array.length) return false;

    for (var i = 0, l=this.length; i < l; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i])) {
                return false;
            }
        } else if (this[i] !== array[i]) {
            return false;
        }
    }

    return true;
};

Object.defineProperty(Array.prototype, 'equals', {enumerable: false});<commit_msg>ESLint<commit_after>/*
 * prefixes.js - Add/remove and view alternative prefixes
 *
 * Contributed by Ovyerus
 */

const fs = require('fs');

exports.loadAsSubcommands = true;

exports.commands = [
    'add',
    'remove'
];

exports.main = {
    desc: 'View the various prefixes used by the bot and edit them.',
    fullDesc: 'Prefixes command. If no arguments are supplied or are not the correct ones, it just displays the available prefixes. Adding and removing prefixes are only allowed by the bot owners(s)',
    usage: '[<add|remove> <prefix>]',
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            let prefixes = JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`));
            let embed = {
                title: 'Current Prefixes',
                description: `Displaying **${prefixes.length + 2}** prefixes.`,
                fields: [
                    {name: 'Internal Prefixes', value: `\`${bot.config.mainPrefix}\`\n\`@mention\``}
                ]
            };

            if (prefixes.length > 0) {
                embed.fields.push({name: 'External Prefixes', value: []});
                prefixes.forEach(prefix => embed.fields[1].value.push(prefix.endsWith(' ') ? `\`${prefix}\u200b\`` : `\`${prefix}\``));
                embed.fields[1].value = embed.fields[1].value.join('\n');
            }

            ctx.msg.channel.createMessage({embed}).then(resolve).catch(reject);
        });
    }
};

exports.add = {
    desc: 'Add a prefix.',
    usage: '<prefix>',
    adminOnly: true,
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0) {
                ctx.msg.channel.createMessage('Please give me a prefix to add.').then(resolve).catch(reject);
            } else {
                let prefix = ctx.args.join(' ');
                let newPrefixes = JSON.stringify(JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`)).concat(prefix));
                fs.writeFile(`${__baseDir}/data/prefixes.json`, newPrefixes, err => {
                    if (err) {
                        reject(err);
                    } else {
                        ctx.msg.channel.createMessage(`Added prefix \`${prefix}\``).then(resolve).catch(reject);
                    }
                });
            }
        });
    }
};

exports.remove = {
    desc: 'Remove a prefix.',
    usage: '<prefix>',
    adminOnly: true,
    main(bot, ctx) {
        return new Promise((resolve, reject) => {
            if (ctx.args.length === 0) {
                ctx.msg.channel.createMessage('Please give me a prefix to remove.').then(resolve).catch(reject);
            } else {
                let prefix = ctx.args.join(' ');
                let prefixes = JSON.parse(fs.readFileSync(`${__baseDir}/data/prefixes.json`));
                let newPrefixes = prefixes.filter(p => p !== prefix);
                console.log(newPrefixes);

                if (newPrefixes.equals(prefixes)) {
                    ctx.msg.channel.createMessage("That prefix doesn't exist or can't be removed.");
                } else {
                    fs.writeFile(`${__baseDir}/data/prefixes.json`, JSON.stringify(newPrefixes), err => {
                        if (err) {
                            reject(err);
                        } else {
                            ctx.msg.channel.createMessage(`Removed prefixes \`${prefix}\``).then(resolve).catch(reject);
                        }
                    });
                }
            }
        });
    }
};

Array.prototype.equals = array => {
    if (!array || this.length !== array.length) return false;

    for (var i = 0, l=this.length; i < l; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i])) {
                return false;
            }
        } else if (this[i] !== array[i]) {
            return false;
        }
    }

    return true;
};

Object.defineProperty(Array.prototype, 'equals', {enumerable: false});<|endoftext|>


<commit_before>
App.ValidatedInputComponent = Ember.TextField.extend({

  classNameBindings: [ 'showError:error', 'required' ],
  attributeBindings: [ 'type' ],

  isValid: Ember.computed.empty('errors'),
  isInvalid: Ember.computed.notEmpty('errors'),
  submit: 'submit',

  focusOut: function () {
    this.set('showError', this.get('isInvalid'));
  },

  keyUp: function () {
    if (this.get('isValid')) this.set('showError', false);
  },

  keyDown: function (e) {
    if (e.keyCode === 13) {
      e.preventDefault();
      this.sendAction('submit');
    }
  },

  observeErrors: function () {
    if ( !this.get('parentModel') ) return;
    this.get('parentModel').addObserver('errors.' + this.get('name'), this, this.syncErrors);
  }.on('didInsertElement'),

  required: function () {
    if ( !this.get('parentModel') ) return;
    var v = this.get('parentModel.validations');
    return v[this.get('name')] && v[this.get('name')].presence;
  }.property('name', 'parentModel.validations'),

  syncErrors: function () {
    this.set('errors', this.get('parentModel.errors.' + this.get('name')));
  }

});
<commit_msg>Issue #556 - tightened up form styles; label click triggers checkbox selection<commit_after>
App.ValidatedInputComponent = Ember.TextField.extend({

  classNameBindings: [ 'showError:error', 'required' ],
  attributeBindings: [ 'type' ],

  isValid: Ember.computed.empty('errors'),
  isInvalid: Ember.computed.notEmpty('errors'),
  submit: 'submit',
  type: 'text',

  focusOut: function () {
    this.set('showError', this.get('isInvalid'));
  },

  keyUp: function () {
    if (this.get('isValid')) this.set('showError', false);
  },

  keyDown: function (e) {
    if (e.keyCode === 13) {
      e.preventDefault();
      this.sendAction('submit');
    }
  },

  observeErrors: function () {
    if ( !this.get('parentModel') ) return;
    this.get('parentModel').addObserver('errors.' + this.get('name'), this, this.syncErrors);
  }.on('didInsertElement'),

  required: function () {
    if ( !this.get('parentModel') ) return;
    var v = this.get('parentModel.validations');
    return v[this.get('name')] && v[this.get('name')].presence;
  }.property('name', 'parentModel.validations'),

  syncErrors: function () {
    this.set('errors', this.get('parentModel.errors.' + this.get('name')));
  }

});
<|endoftext|>


<commit_before>openerp.base_dashboard = function(openerp){

QWeb.add_template('/base_dashboard/static/src/xml/base_dashboard.xml');

openerp.base.form.Board = openerp.base.form.Widget.extend({
    init: function(view, node) {

        this._super(view, node);
        this.template = "Board";
    },
    start: function() {
        this._super.apply(this, arguments);
        this.$element.html(QWeb.render(this.template));
    },

    render: function() {
        var self = this;
        jQuery('body').append(
            jQuery('<div>', {'id': 'dashboard_template'}).load('/base_dashboard/static/src/dashboard_template.html',self.on_loaded).hide()
        )
    },

    on_loaded: function() {
        var children = this.node.children;

        var board = jQuery('#dashboard').dashboard({
            layoutClass:'layout'
        });
        board.init();
        for(var ch = 0; ch < children.length; ch++) {
            var ch_widgets = children[ch].children;
            for(var chld = 0; chld < ch_widgets.length; chld++) {
                var widget_type = ch_widgets[chld].tag;
                var widget = new (openerp.base.form.widgets.get_object(widget_type)) (this.view, ch_widgets[chld], board, chld);
                widget.start();
            }
        }
    }
});

openerp.base.form.Action = openerp.base.form.Widget.extend({
    init: function(view, node, board,child_index) {
        this._super(view, node, board,child_index);
        this.board = board;
        this.child_index = child_index;
    },
    start: function() {
        this._super.apply(this, arguments);
        this.rpc('/base_dashboard/dashboard/load',{
            node_attrs: this.node.attrs
        },
        this.on_load_action);
    },

    on_load_action: function(result) {
        var action = result.action;
        if(action.search_view)
            action.search_view = false;
        action.no_sidebar = true;

        var node_attrs = this.node.attrs;
        var get_column = ['first', 'second', 'third'];
        var board_element = this.board.element.find('[id=column-'+get_column[this.child_index]+']');

        this.board.addWidget({
                    'id': node_attrs.name,
                    'title': node_attrs.string,
                }, board_element);

        var content_id = node_attrs.name+'-widgetcontent';
        this.board.getWidget(node_attrs.name).element.find('.widgetcontent').attr('id',content_id)

        action_manager = new openerp.base.ActionManager(this.session, content_id);
        action_manager.start();
        this.board.getWidget(node_attrs.name).url = action_manager.do_action(action);
    }
})

openerp.base.form.widgets.add('hpaned', 'openerp.base.form.Board');
openerp.base.form.widgets.add('action', 'openerp.base.form.Action');
}<commit_msg>[FIX] Vpaned action.<commit_after>openerp.base_dashboard = function(openerp){

QWeb.add_template('/base_dashboard/static/src/xml/base_dashboard.xml');

openerp.base.form.Board = openerp.base.form.Widget.extend({
    init: function(view, node) {

        this._super(view, node);
        this.template = "Board";
    },
    start: function() {
        this._super.apply(this, arguments);
        this.$element.html(QWeb.render(this.template));
    },

    render: function() {
        var self = this;
        jQuery('body').append(
            jQuery('<div>', {'id': 'dashboard_template'}).load('/base_dashboard/static/src/dashboard_template.html',self.on_loaded).hide()
        )
    },

    on_loaded: function() {
        var children = this.node.children;
        var board = jQuery('#dashboard').dashboard({
            layoutClass:'layout'
        });
        board.init();
        for(var ch = 0; ch < children.length; ch++) {
            var ch_widgets = children[ch].children;
            for(var chld = 0; chld < ch_widgets.length; chld++) {
                var widget_type = ch_widgets[chld].tag;
                var child_index = widget_type == 'action' ? chld : ch;
                var widget = new (openerp.base.form.widgets.get_object(widget_type)) (this.view, ch_widgets[chld], board, child_index);
                widget.start();
            }
        }
    }
});

openerp.base.form.Action = openerp.base.form.Widget.extend({
    init: function(view, node, board, child_index) {
        this._super(view, node, board, child_index);
        this.board = board;
        this.child_index = child_index;
    },
    start: function() {
        this._super.apply(this, arguments);
        this.rpc('/base_dashboard/dashboard/load',{
            node_attrs: this.node.attrs
        },
        this.on_load_action);
    },

    on_load_action: function(result) {
        var action = result.action;
        if(action.search_view)
            action.search_view = false;
        action.no_sidebar = true;

        var node_attrs = this.node.attrs;
        var get_column = ['first', 'second', 'third'];
        var board_element = this.board.element.find('[id=column-'+get_column[this.child_index]+']');

        this.board.addWidget({
                    'id': node_attrs.name,
                    'title': node_attrs.string,
                }, board_element);

        var content_id = node_attrs.name+'-widgetcontent';
        this.board.getWidget(node_attrs.name).element.find('.widgetcontent').attr('id',content_id)

        action_manager = new openerp.base.ActionManager(this.session, content_id);
        action_manager.start();
        this.board.getWidget(node_attrs.name).url = action_manager.do_action(action);
    }
})

openerp.base.form.Vpaned = openerp.base.form.Widget.extend({
    init: function(view, node, board, child_index) {

        this._super(view, node, board, child_index);
        this.board = board;
        this.child_index = child_index;
    },
    start: function() {
        this._super.apply(this, arguments);
        var children = this.node.children;
        for(var chld=0; chld<children.length; chld++) {
            var ch_widget = children[chld].children;
            for(var ch=0; ch<ch_widget.length; ch++) {
                var widget_type = ch_widget[ch].tag;
                var widget = new (openerp.base.form.widgets.get_object(widget_type)) (this.view, ch_widget[ch], this.board, this.child_index);
                widget.start();
            }
        }
    },
})

openerp.base.form.widgets.add('hpaned', 'openerp.base.form.Board');
openerp.base.form.widgets.add('vpaned', 'openerp.base.form.Vpaned');
openerp.base.form.widgets.add('action', 'openerp.base.form.Action');
}<|endoftext|>


<commit_before>/*
 * saucenao.js - grab a image's source using saucenao. Grabs the last message attachment/URL, provided along with the command
 * or providing an attachment using the command as the caption.
 *
 *  Contributed by Capuccino
 */
exports.commands = [
    'saucenao'
];

exports.saucenao = {
    desc: 'Grab an image\'s source using saucenao API.',
    longDesc: 'Gets the image source from sacuenao.',
    usage: '(Image URL [If not provided, it would grab the last message with image attachment\'s URL and sends it to the API])',
    main(bot, ctx) {
        if (!ctx.suffix) {
            //grab the last message with an attachment
            if (!ctx.msg.channel.attachments) {
                ctx.msg.channel.createMessage('Aw, no Image here.');
            } else {
                let imgUrl = ctx.msg.channel.attachments[0].url;
                got(`https://saucenao.com`, {
                    method: 'POST',
                    'Content-Type': 'application/json',
                    body: JSON.stringify({url: imgUrl})
                }).then(res => {
                    //only return the top result
                    let nya = [];
                    nya.push = res.url;
                });
            }
        }
    }
};<commit_msg>use const for nya<commit_after>/*
 * saucenao.js - grab a image's source using saucenao. Grabs the last message attachment/URL, provided along with the command
 * or providing an attachment using the command as the caption.
 *
 *  Contributed by Capuccino
 */
exports.commands = [
    'saucenao'
];

exports.saucenao = {
    desc: 'Grab an image\'s source using saucenao API.',
    longDesc: 'Gets the image source from sacuenao.',
    usage: '(Image URL [If not provided, it would grab the last message with image attachment\'s URL and sends it to the API])',
    main(bot, ctx) {
        if (!ctx.suffix) {
            //grab the last message with an attachment
            if (!ctx.msg.channel.attachments) {
                ctx.msg.channel.createMessage('Aw, no Image here.');
            } else {
                let imgUrl = ctx.msg.channel.attachments[0].url;
                got(`https://saucenao.com`, {
                    method: 'POST',
                    'Content-Type': 'application/json',
                    body: JSON.stringify({url: imgUrl})
                }).then(res => {
                    //only return the top result
                    const nya = [];
                    nya.push = res.url;
                });
            }
        }
    }
};<|endoftext|>