text:
Project to display English libraries data in a data dashboard. Currently published at [https://england.librarydata.uk](https://england.librarydata.uk).

## What is it?

The Libraries Taskforce have been working on an English libraries dataset to bring together a list of all libraries from library authorities in England.  This includes tracking closures, changes of library type, number of libraries, locations of libraries, and contact details.

[Public Libraries News](http://www.publiclibrariesnews.com) is the UK leading source for libraries news.  This includes regular updates about changes, local news by authority, ideas, national news, and international news.

This project aims at bringing these things together, along with latest tweets and other data - into a larger set of visualisations.

## Supporting technology

| Technology | Description |
| ---------- | ----------- |
| Web | The site is coded using front-end web technologies: HTML/CSS/JavaScript |
| Google apps scripts | Data is refreshed from Public Libraries News and Twitter by using Google apps scripts set to run regularly. |
| PostGIS database | A PostGIS database was used for the majority of the geospatial analysis. |

## Functionality

### Data dashboard

The dashboard is split into cards, providing different areas of functionality.

#### 1. Areas

The dashboard provides either data on all library services, or for specific areas (library authorities).  Using the drop down control in this card will filter the data to show for the specified library service.

#### 2. Twitter card

On selecting a library service if there is a matching tweet from the twitter data then this will be displayed.

#### 3. Library details

If no library service selected, all libraries in England are listed to select.  If a particular service is selected then only the libraries for that service are shown.

On selecting a library, details displayed are:

- email and website (as buttons)
- library type
- closed/replaced/new details (if applicable)
- notes on the library
- deprivation deciles for the catchment area the library is located in.

#### 4. Library counts and types

If no library service is selected, this polar area chart shows the library types in England.  These are either:

- Authority: A local authority library.  Shown in green.
- Community: A community run library, with some support from the local authority.  Shown in dark blue.
- Commissioned: A library not run by the local authority but commissioned by them.  Shown in light blue.
- Independent: A library outside of local authority provision completely.  Shown in very dark grey.
- Closed:  Either permanently or temporarily closed libraries.  Shown in red.

This card also shows the total number of libraries as at July 2016, with an indicator of the difference in number since April 2010.  In then does the same for libraries that are marked as part of statutory provision.

If a library service is selected then all of the details are filtered to the libraries in that service.

#### 5. Library distances

The distance line graph is designed to show the distance (straight line - not route of travel) to the nearest library for members of the poulation.  The x axis plots the distance, starting at 0 and going to the furthest distance.  The y axis plots the number of people estimated to be that distance from a library.

When no library service is selected this shows data for England.  When a library service is selected it

The data currently works within authority boundaries and does not take into account cross-authority boundary distance.  For example, an area of an authority may have the nearest library as one that is a different authority, this is not accounted for.

#### 6. News and changes

When a library service is selected the dashboard checks if there are associated Public Libraries News stories for that authority within the last 3 months, and shows them in this card if so.

#### 7. Deprivation stats

Deprivation stats are shown for the authority.  This is an average deprivation level of the LSOAs (Lower Super Output Areas - for which deprivation indicators are released).  LSOAs generally consist of around 1500 people.  It is not always that useful to average them over the authority.  For example, one authority may have many areas with very high deprivation, but an equal number with very low deprivation.  Another authority may have most areas with relatively mid-level deprivation.  Yet both of these situations will amount to the same average.  So take it with that understanding!

The deprivation stats are given as average deciles.  Each LSOA is given a decile (1-10) value - with 1 being within the tenth most deprived areas of the country, and 10 being within the tenth least deprived areas.

It's important not to equate least deprived with something like 'most wealthy'.  These are depriation measures so areas that have the loweest levels of deprivation are not necessary those we know of as affluent or wealthy areas.

### 8.  Nearest

Enter a postcode and select from the drop down to find the nearest library to that location.  Upon finding a location a mini map will zoom to show the route and provide some basic walking, cycling, and driving instructions.

To give a freedom to select what types of library you are interested in seeing as your local, you can untick different library types.

### Map

Map published at [https://england.librarydata.uk/map](https://england.librarydata.uk/map).

## File descriptions

A summary of some of the key files and directories in this repository.

| Folder | File | Description |
| ------ | ---- | ----------- |
| / | LICENSE | The licence for this project. MIT. |
| / | web.config | For hosting on IIS systems. |
| / | create-db.md | Step by step instructions of creating the database. |
| / | bower.json | Package manager configuration file.  Includes which packages get installed. |
| / | index.html | The home page (daashboard) |
| / | map.html | The map page |
| / | thedata.html | LIsting of data page  |
| /css/ | site.css | The stylesheet for the web site. |
| /js/ | config.js | Bits of configuration for the site |
| /js/ | libraries.js | A set of common functions used to load in and manipulate the library data |
| /js/ | dashboard.js | Javascript loaded with the dashboard page |
| /js/ | map.js | Javascript loaded with the map page |
| /js/ | tables.js | Javascript loaded with the data page |
| /images/ | dashboard.png | Image that gets displayed when linking on Twitter |

## Build

The project uses bower and node for dependency management.  It also requires the bower npm resolver package to be installed.

Set up bower requirements if necessary:

```
npm install -g bower
npm install -g bower-npm-resolver
```

And then in this project, run:

```
bower install
```

## Deploy

Once the project is built it should be able to be hosted on any web hosting environment.  Simply copy the files over.

## Third party licences

### Technology and code licences

| Name | Description | Link | Licence |
| ---- | ----------- | ---- | ------- |
| Leaflet | Lightweight JavaScript interactive map framework | [Leaflet](http://leafletjs.com/) | [Open Source](https://github.com/Leaflet/Leaflet/blob/master/LICENSE) |
| Bootstrap | HTML, CSS, and JS framework for developing responsive, mobile first projects on the web | [Bootstrap](http://getbootstrap.com/) | [MIT](https://github.com/twbs/bootstrap/blob/master/LICENSE) |
| Font Awesome |  |  |  |
| jQuery | Required by Bootstrap and used for general JavaScript shortcuts | [jQuery](https://jquery.com/) | [MIT](https://github.com/twbs/bootstrap/blob/master/LICENSE) |
| Moment JS |  |  |  |

### Data Licenses

| Data | Description | Licence |
| ---- | ----------- | ------- |
| Core Basic Dataset | The libraries taskforce core basic dataset, as collated from returns submitted by each (150) library authroity in England. | Open Government Licence |
| Public Libraries News | Data scraped from [PLN](http://www.publiclibrariesnews.com). |  |
| Map tiles | The map tiles used in any instances of web maps in the project. | © Mapbox and © Open Street Map contributor data. |
| OS Open Data | Includes code point open and boundary line. |  |
| ONS Open Data | Includes population estimates and indices of deprivation.  |  |

## Licence

Original code licensed under the [MIT Licence](LICENSE)


text:
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_WEB_IDB_CURSOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_WEB_IDB_CURSOR_H_

#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h"
#include "third_party/blink/renderer/modules/modules_export.h"

namespace blink {

class MODULES_EXPORT WebIDBCursor {
 public:
  virtual ~WebIDBCursor() = default;

  // Used to implement IDBCursor.advance().
  virtual void Advance(uint32_t count, WebIDBCallbacks*) = 0;

  // Used to implement IDBCursor.continue() and IDBCursor.continuePrimaryKey().
  //
  // The key and primary key are null when they are not supplied by the
  // application. When both arguments are null, the cursor advances by one
  // entry.
  //
  // The keys pointed to by IDBKey* are only guaranteed to be alive for
  // the duration of the call.
  virtual void CursorContinue(const IDBKey*,
                              const IDBKey* primary_key,
                              WebIDBCallbacks*) = 0;

  // Called after a cursor request's success handler is executed.
  //
  // This is only used by the cursor prefetching logic, and does not result in
  // an IPC.
  virtual void PostSuccessHandlerCallback() = 0;

 protected:
  WebIDBCursor() = default;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_WEB_IDB_CURSOR_H_

redpajama_set_name: RedPajamaGithub


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Larger Fungi of South Australia (Adelaide) 58 (1997)

#### Original name
Lactarius mea Grgur.

### Remarks
null


text:
import {Injectable} from '@angular/core';
import {Http} from "@angular/http";
import {GlobalService} from '../../global.service';
@Injectable()
export class EditTableStoresService {
  constructor(private http: Http, private globalService: GlobalService) {

  }

  getPOIs(): Promise<any> {
    return new Promise((resolve, reject) => {
      this.http.get('https://followit-backend.herokuapp.com/api/getallpoi')
        .subscribe(response => {
          resolve(response.json())
        });
    });
  }

  sendUpdatedPOI(data: Array<Object>, temp: Array<Object>): Promise<any> {
    return new Promise((resolve, reject) => {
      var newIDs = [];
      data.forEach(
        function(element) {
          newIDs.push(element["poiID"]);
        });
      temp["elements"]["nodes"].forEach(
        function(element) {
          var idToRemove = [];
          element['data']["poiID"].forEach(
            function(id) {
              if ($.inArray(id, newIDs) < 0) {
                idToRemove.push(id);
              }
            });
          idToRemove.forEach(
            function(id) {
              element['data']["poiID"].splice($.inArray(id, element['data']["poiID"]), 1);
            });

        });

      this.globalService.sendUpdatedGraph(temp).then(() => {
        var pois = {};
        pois["pois"] = data;
        this.http.post('https://followit-backend.herokuapp.com/api/updatePOIs', pois)
          .subscribe(response => {
            resolve("OK")
          });
      });

    });

  }
}


text:
"""Tests for haas.rest.

This contains a somewhat awkward mix of unittest style classes and tests that
use pytest fixtures and decorators. The latter are newer,and make it workable
to use stuff like `parametrize`.
"""

from haas import rest, config

from abc import ABCMeta, abstractmethod
import unittest
import json

from schema import Schema, Optional

# We don't directly use this, but unless we import it, the coverage tool
# complains and doesn't give us a report.
import pytest

from haas.test_common import config_testsuite

@pytest.fixture(autouse=True)
def configure():
    config_testsuite()
    config.load_extensions()

class HttpTest(unittest.TestCase):
    """class based version of client, for the older tests."""

    def setUp(self):
        self.client = rest.app.test_client()

@pytest.fixture()
def client():
    return rest.app.test_client()

class HttpEquivalenceTest(object):
    """A test that ensures a particlar call to the api behaves the same over
    http and when called as a function. Subclasses must override `api_call`
    and `request`, and may also be interested in `api_setup` and
    `api_teardown`.
    """

    __metaclass__ = ABCMeta

    @abstractmethod
    def api_call(self):
        """Invoke the api call directly."""

    @abstractmethod
    def request(self):
        """Invoke the API cal via HTTP. returning the response.

        When this method is invoked, `self.client` will be an instance of
        `flask.testing.FlaskClient`, and should be used to make the request.
        Its return value is the response, and should be returned as-is.
        """

    def api_setup(self):
        """Setup routine to be run before each call to the api.

        This is conceptually similar to python's unittest setUp()
        method, but with each call to `api_call`, rather than the
        whole test.

        By default this is a noop; subclasses should override this if
        they need specific environments.
        """

    def api_teardown(self):
        """like `api_setup`, but tears things down after the call."""

    def test_equivalence(self):
        """Calling `api_call` directly should be the same as via http."""

        # First invoke the call over http. This should never raise exceptions.
        self.api_setup()
        resp = self.request()
        body = resp.get_data()
        self.api_teardown()

        # Now call it directly.
        try:
            self.api_setup()
            ret = self.api_call()

            # Flask has a few different things a function can return; we need
            # to handle each of them.
            if ret is None:
                ret_body, ret_status = '', 200
            elif type(ret) is tuple:
                ret_body, ret_status = ret
            else:
                ret_body, ret_status = ret, 200

            assert resp.status_code == ret_status
            if ret_body == '':
                assert body == ''
            else:
                assert json.loads(body) == json.loads(ret_body)
        except rest.APIError as e:
            assert resp.status_code == e.status_code
            assert json.loads(body) == {'type': e.__class__.__name__,
                                        'msg': e.message,
                                        }
        finally:
            self.api_teardown()

class TestUrlArgs(HttpEquivalenceTest, HttpTest):
    """Test that arguments supplied in the url are passed correctly."""
    # The use of HTTPEquivalenceTest here is a bit weird; We're not actually
    # calling the api function from `api_call`. This is actually probably a
    # fairly common way to want to use the superclass; we should think about
    # whether the documented usage is necessarily the right idea.

    def setUp(self):
        HttpTest.setUp(self)

        @rest.rest_call('GET', '/func/<foo>/<bar>', Schema({
            'foo': basestring,
            'bar': basestring,
        }))
        def func(foo, bar):
            return json.dumps([foo, bar])

    def api_call(self):
        return json.dumps(['alice', 'bob'])

    def request(self):
        return self.client.get('/func/alice/bob')

class TestBodyArgs(HttpEquivalenceTest, HttpTest):
    """Test that arguments supplied in the body are passed correctly."""

    def setUp(self):
        HttpTest.setUp(self)

        @rest.rest_call('POST', '/func/foo', Schema({
            'bar': basestring,
            'baz': basestring,
        }))
        def foo(bar, baz):
            return json.dumps([bar, baz])

    def api_call(self):
        return json.dumps(['bonnie', 'clyde'])

    def request(self):
        return self.client.post('/func/foo',
                                data=json.dumps({'bar': 'bonnie',
                                                 'baz': 'clyde'}))

class TestRestCallSchema(HttpEquivalenceTest, HttpTest):
    """Test using non-trivial schema (i.e. not just strings)."""

    def setUp(self):
        HttpTest.setUp(self)

        @rest.rest_call('POST', '/product', schema=Schema({
            'x': int,
            'y': int,
            Optional('z'): int,
        }))
        def product(x, y, z=1):
            return json.dumps(x * y * z)

    def api_call(self):
        return json.dumps(14)

    def request(self):
        return self.client.post('/product',
                                data=json.dumps({'x': 2, 'y': 7}))

class TestEquiv_basic_APIError(HttpEquivalenceTest, HttpTest):
    """Basic test to make sure the APIError handling code is excercised."""

    def setUp(self):
        HttpTest.setUp(self)

        @rest.rest_call('GET', '/some_error', Schema({}))
        def some_error():
            self.api_call()

    def api_call(self):
        raise rest.APIError("Basic test of the APIError code.")

    def request(self):
        return self.client.get('/some_error')

class TestNoneReturnValue(HttpTest):
    """Test returning None from API calls.

    Flask itself doesn't allow this, but we've been doing it for a long time
    so our wrapper supports it. This test verifies that it actually works.
    """

    def setUp(self):
        HttpTest.setUp(self)

        @rest.rest_call('GET', '/nothing', Schema({}))
        def api_call():
            return None

    def test_none_return(self):
        resp = self.client.get('/nothing')
        assert resp.status_code == 200
        assert resp.get_data() == ''

@pytest.fixture()
def validation_setup():
    # There's a mix of PUT and POST in these; mixing it up may give us
    # better coverage. The particulars of which calls get which methods are
    # arbitrary.

    # We have four kinds of calls we want to validate here:

    # 1. No arguments in the URL or body (no_args)
    @rest.rest_call('POST', '/no/args', Schema({}))
    def no_args():
        pass

    # 2. Argument in the URL and not in the body (url_args)
    @rest.rest_call('POST', '/url/args/<arg1>/<arg2>', Schema({
        'arg1': basestring,
        'arg2': basestring,
    }))
    def url_args(arg1, arg2):
        return json.dumps([arg1, arg2])

    # 3. Arguments in both the URL and body (mixed_args)
    @rest.rest_call('PUT', '/mixed/args/<arg1>', Schema({
        'arg1': basestring,
        'arg2': basestring,
    }))
    def mixed_args(arg1, arg2):
        return json.dumps([arg1, arg2])

    # 4. Arguments in body and not in the URL.
    @rest.rest_call('POST', '/body/args', Schema({
        'arg1': basestring,
        'arg2': basestring,
    }))
    def body_args(arg1, arg2):
        return json.dumps([arg1, arg2])

    # Let's also make sure we're testing something with a schema that isn't
    # just basestring:
    @rest.rest_call('PUT', '/non-string-schema', schema=Schema({
        "the_value": int,
    }))
    def non_string_schema(the_value):
        return json.dumps(the_value)

def _do_request(client, method, path, data):
    """Make a request to the endpoint with `data` in the body.

    `client` is a flask test client

    `method` is the request method

    `path` is the path of the request

    `data` should be a string -- the server will expect valid json, but
    we want to write test cases with invalid input as well.
    """
    client.post('/give-me-an-e', data=data)
    # Annoyingly, the client doesn't give us a way to supply an arbitrary
    # HTTP method, so we hack around it by using getattr to get the right
    # function:
    return getattr(client, method.lower())(path, data=data)

@pytest.mark.parametrize('args', [
    # Legal cases:
    {'request': {'method': 'POST', 'path': '/no/args', 'data': ''},
     'expected': {'status': 200, 'body_json': None}},

    {'request': {'method': 'POST',
                 'path': '/url/args/hello/goodbye',
                 'data': ''},
     'expected': {'status': 200,
                  'body_json': ['hello', 'goodbye']}},

    {'request': {'method': 'PUT',
                 'path': '/mixed/args/hello',
                 'data': json.dumps({'arg2': 'goodbye'})},
     'expected': {'status': 200,
                  'body_json': ['hello', 'goodbye']}},

    {'request': {'method': 'POST',
                 'path': '/body/args',
                 'data': json.dumps({'arg1': 'hello',
                                     'arg2': 'goodbye'})},
     'expected': {'status': 200,
                  'body_json': ['hello', 'goodbye']}},

    {'request': {'method': 'PUT',
                 'path': '/non-string-schema',
                 'data': json.dumps({'the_value': 42})},
     'expected': {'status': 200,
                  'body_json': 42}},

    # Illegal JSON in the body:
    {'request': {'method': 'POST',
                 'path': '/body/args',
                 'data': 'xploit'},
     'expected': {'status': 400,
                  'body_json': None}},

    # Arguments in the body for a function that expects no arguments
    {'request': {'method': 'POST', 'path': '/no/args', 'data': json.dumps({'arg1': 'foo'})},
     'expected': {'status': 400, 'body_json': None}},

    # Empty body (for a function that expects body args). Note that this should
    # hit the same exact code paths as the illegal JSON test, but it's
    # conceptually different:
    {'request': {'method': 'POST',
                 'path': '/body/args',
                 'data': ''},
     'expected': {'status': 400,
                  'body_json': None}},

    # Missing arg2:
    {'request': {'method': 'POST',
                 'path': '/body/args',
                 'data': json.dumps({'arg1': 'hello'})},
     'expected': {'status': 400,
                  'body_json': None}},
    # Extra arg (arg3):
    {'request': {'method': 'POST',
                 'path': '/body/args',
                 'data': json.dumps({'arg1': 'hello',
                                     'arg2': 'goodbye',
                                     'arg3': '????'})},
     'expected': {'status': 400,
                  'body_json': None}},

    # Same argument passed via URL and body. Note that from the client side
    # this isn't semantically meaningful, since arguments in the URL don't have
    # names; this is just testing the logic that parses these into python
    # function arguments:
    {'request': {'method': 'PUT',
                 # The mixed_args function calls the 'hello' segment of it's
                 # path "arg1":
                 'path': '/mixed/args/hello',
                 'data': json.dumps({'arg1': 'howdy',
                                     'arg2': 'goodbye'})},
     'expected': {'status': 400,
                  'body_json': None}},

    # Invalid arg types:
    {'request': {'method': 'PUT',
                 'path': '/mixed/args/hello',
                 'data': json.dumps({'arg2': 3232})},
     'expected': {'status': 400,
                  'body_json': None}},

    {'request': {'method': 'PUT',
                 'path': '/non-string-schema',
                 'data': json.dumps({'the_value': 'Not an integer!'})},
     'expected': {'status': 400, 'body_json': None}},

])
def test_validation_status(client, validation_setup, args):
    """Check that the request returns an expected response.

    `client` and `validation_setup` come from the fixtures defined above.

    `args` is a dictionary with two keys:

        * `request`, a specification of the request
        * `expected` a specification of the expected response.

    `request` has three fields, `method`, `path`, and `data`, corresponding
    to the arguments to `_do_request` by the same names.

    `expected` has two fields:

        * `status`, the expected status code.
        * `body_json`, which is either a decoded JSON object or `None`.
           If it is None, no requirements are imposed on the body of the
           request. Otherwise, it must be equal to the decoded body of the
           response.

    """
    # Annoyingly, the client doesn't give us a way to supply an arbitrary
    # HTTP method, so we hack around it by using getattr to get the right
    # function:
    resp = _do_request(client, **args['request'])
    assert resp.status_code == args['expected']['status']
    if args['expected']['body_json'] is not None:
        assert json.loads(resp.get_data()) == args['expected']['body_json']

class TestCallOnce(HttpTest):
    """Verify that the request handler invokes the API *exactly* once.

    This is a regression test; A previous refactoring introduced a bug where
    the api function was called twice.
    """

    def setUp(self):
        HttpTest.setUp(self)
        self.num_calls = 0

    def test_call_once(self):
        # We define an API call that increments a counter each time the
        # function is called, then invoke it via HTTP. Finally, we verify that
        # the counter is equal to 1, indicating that the function was called
        # the correct number of times.

        @rest.rest_call('POST', '/increment', Schema({}))
        def increment():
            """Increment a counter each time this function is called."""
            self.num_calls += 1

        self.client.post('/increment')
        assert self.num_calls == 1


text:
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.firebase.appcheck.interop;

import androidx.annotation.NonNull;
import com.google.firebase.appcheck.AppCheckTokenResult;

/**
 * Listener that is triggered when the {@link AppCheckTokenResult} changes. To be used when you need
 * the {@link AppCheckTokenResult} to remain valid at all times.
 */
public interface AppCheckTokenListener {

  /**
   * This method gets invoked on the UI thread on changes to the token state. Does not trigger on
   * token expiry.
   */
  void onAppCheckTokenChanged(@NonNull AppCheckTokenResult appCheckTokenResult);
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title>doh.robot Dialog A11Y Test</title>

		<style>
			@import "../../../util/doh/robot/robot.css";
		</style>

		<!-- required: dojo.js -->
		<script type="text/javascript" src="../../../dojo/dojo.js"
			djConfig="isDebug: true"></script>

		<!-- functions to help test -->
		<script type="text/javascript" src="../helpers.js"></script>

		<script type="text/javascript">
			dojo.require("dijit.robotx");

			dojo.addOnLoad(function(){
				doh.robot.initRobot('../test_Dialog.html');

				doh.register("dijit.Dialog mouse tests (cancel)",[
					{
						name: "open dialog",
						timeout: 4000,
						runTest: function(){
							var d = new doh.Deferred();

							// Open the dialog
							doh.robot.mouseMoveAt("dialog1button", 1000);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
								doh.is("name", dojo.global.dijit._curFocus.id, "focus is on the first field");
							}), 1000);

							return d;
						}
					},

					{
						name: "test that other controls on page can't be clicked",
						timeout: 4000,
						runTest: function(){
							var d = new doh.Deferred();

							doh.robot.mouseMoveAt("plainInput", 500);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.t(isVisible("dialog1"), "dialog 1 still visible");
								doh.isNot("plainInput", dojo.global.dijit._curFocus && dojo.global.dijit._curFocus.id, "plain input wasn't focused");
							}), 1000);

							return d;
						}
					},

					{
						name: "open date drop down",
						timeout: 4000,
						runTest: function(){
							var d = new doh.Deferred();

							doh.robot.mouseMoveAt("date", 500);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.is("date", dojo.global.dijit._curFocus.id, "focus is on the date field");
								doh.is(1, dojo.query(".dijitCalendarContainer").length, "calendar is being shown");
							}), 1000);

							return d;
						}
					},

					{
						name: "close date drop down",
						timeout: 4000,
						runTest: function(){
							var d = new doh.Deferred();

							doh.robot.mouseMove(10, 10, 500);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.is(0, dojo.query(".dijitCalendarContainer").length, "calendar has disappeared");
								doh.t(isVisible("dialog1"), "dialog 1 wasn't closed");
							}), 1000);

							return d;
						}
					},

					{
						name: "cancel dialog",
						timeout: 4000,
						runTest: function(){
							var d = new doh.Deferred();

							var button = dojo.query("#dialog1 .dijitDialogCloseIcon")[0];
							doh.robot.mouseMoveAt(button, 500);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.t(isHidden("dialog1"), "dialog 1 was closed");
								doh.is("dialog1button", dojo.global.dijit._curFocus.id, "focus returned to button");
							}), 1000);

							return d;
						}
					}
				]);

				doh.register("dijit.Dialog mouse tests (submit)",[
					{
						name: "submit some data",
						timeout: 15000,
						setUp: function(){
							dijit.byId("dialog1").reset();
						},
						runTest: function(){
							var d = new doh.Deferred();

							// Setup handler to catch submitted data
							var data;
							dojo.connect(dijit.byId("dialog1"), "execute", function(vals){
								data = vals;
							});

							// Open the dialog
							doh.robot.mouseMoveAt("dialog1button", 500);
							doh.robot.mouseClick({left: true}, 1000);

							// Enter some info
							doh.robot.mouseMoveAt("name", 2000);
							doh.robot.mouseClick({left: true}, 1000);
							doh.robot.typeKeys("Ted", 500);

							doh.robot.mouseMoveAt("loc", 500);
							doh.robot.mouseClick({left: true}, 1000);
							doh.robot.typeKeys("America", 500);

							// Submit
							doh.robot.mouseMoveAt("ok", 500);
							doh.robot.mouseClick({left: true}, 1000);

							doh.robot.sequence(d.getTestCallback(function(){
								doh.t(isHidden("dialog1"), "dialog 1 was closed on submit");
								doh.t(data, "got submit data");
								doh.is("Ted", data.name, "Name");
								doh.is("America", data.loc, "Location");
							}), 1000);

							return d;
						}
					}
				]);

				doh.run();
			});
		</script>
	</head>
</html>


text:
module ArticlesHelper
    def article_params
      params.require(:article).permit(:title, :body)
    end
end


text:
var mongoose = require('mongoose');
var autoIncrement = require('mongoose-auto-increment');

// init plugin for auto-incrementing _id field
autoIncrement.initialize(mongoose.connection);

// Represents a point in time when the data for was collected
var Snapshot = new mongoose.Schema({
  time: {
    type: Date,
    required: true
  }, // Date when the snapshot is gathered
  new_items: {
    type: Number,
    min: 0
  } // number of new items collected for that snapshot
});

// automatically create auto increment on _id field
Snapshot.plugin(autoIncrement.plugin, 'Snapshot');

module.exports = mongoose.model('Snapshot', Snapshot);