This section details the RESTful interface to the OLD data structure as well as resource search, authentication and authorization, input validation and notable data processing functionality. That is, it explains what kind of effect one can expect from requesting a particular URL (with a particular HTTP method and a particular JSON payload) of an OLD web service.
The OLD exposes a RESTful interface to its data structure. In the context of the OLD, the term RESTful [1] refers to the fact URLs are used consistently to refer to OLD resources and that HTTP methods dictate the action to be performed on the resource. For example, URLs of the form /forms and /forms/id are always routed to the forms controller which provides the interface for the form resources. If the HTTP method is GET and the URL is /forms, the system will return all form resources; the same URL with a POST method will cause the system to create a new form resource (using JSON data passed in the request body). The URL /forms/id with a PUT method will result in an update to the form resource with id=id while a DELETE method on the same URL will cause that resource to be deleted.
This pattern is detailed in the following table.
| HTTP Method | URL | Effect | Parameters |
|---|---|---|---|
| GET | /forms | Read all forms | optional GET params |
| GET | /forms/id | Read form with id=id | |
| GET | /forms/new | Get data for creating a new form | optional GET params |
| GET | /forms/id/edit | Get data for editing form with id=id | optional GET params |
| DELETE | /forms/id | Delete form with id=id | |
| POST | /forms | Create a new form | JSON object |
| PUT | /forms/id | Update form with id=id | JSON object |
The benefit of this consistent interface is that, once you know what resources the OLD exposes, it is clear how to create new ones, retrieve all or one in particular, update one or delete one. The resources of the OLD are listed in the table below.
| Resource (URL) | SEARCH-able | Read-only | Additional actions |
|---|---|---|---|
| applicationsettings | |||
| collections | Yes | Yes | |
| collectionbackups | Yes | Yes | |
| elicitationmethods | |||
| files | Yes | Yes | |
| forms | Yes | Yes | |
| formbackups | Yes | Yes | |
| formsearchs | Yes | ||
| languages | Yes | Yes | |
| orthographies | |||
| pages | |||
| phonologies | |||
| rememberedforms* | Yes | ||
| sources | Yes | ||
| speakers | |||
| syntacticcategories | |||
| tags | |||
| users |
As indicated by the “SEARCH-able” column in the above table, some OLD resources can be searched using a non-standard [2] SEARCH method with the relevant URL. The table below uses the files resources to illustrate the search interface. The details of the search feature (e.g., the format of JSON search parameters) are laid out in the Search section.
Note
POST /resources/search is a synonym for SEARCH /resources; this is to allow for search requests from clients that do not allow specification of non-standard HTTP methods.
| HTTP Method | URL | Effect | Parameters |
|---|---|---|---|
| SEARCH | /files | Search files | JSON object |
| POST | /files/search | Search files | JSON object |
| GET | /files/new_search | Get data for searching files |
Requests to GET /resources/new_search return a JSON object which summarizes the data structure of the relevant resource, thus facilitating query construction.
For the read-only resources (cf. the third column in the resources table), the only standard requests that are valid are GET /resources and GET /resources/id. Since these read-only resources also happen to be searchable, the search-related requests of the table above are valid for them as well.
The core OLD resources (i.e., forms, files and collections) deviate from the RESTful standard in having additional valid URLs associated. For example, the forms resource has a remember action such that POST /forms/remember will result in the system associating the forms referenced in the request body to the user making the request (i.e., the user remembers those forms). Similarly, the files resource has a serve action such that GET /files/serve/id will return the file data for the file with id=id. These additional actions are described in the subsections for the relevant resources/controllers below.
Aside from those described above, the only additional valid URL/method combinations of an OLD web service have to do with authentication and the login controller. These are detailed in the Authentication & authorization section.
All other requests to an OLD web service will result in a response with a sensible HTTP error code and a JSON message in the response body that gives further information on the error.
Requests of the form GET /resources, e.g., GET /forms, return all resources of the type specified in the URL. These requests are routed to the index action of the controller for the resource.
The order of the returned resources may be specified via “orderBy”-prefixed parameters in the URL query string. For example, a request such as GET /forms?orderByModel=Form&orderByAttribute=id&orderByDirection=desc will return all form resources sorted by id in descending order. These ordering parameters are processed in exactly the same way as those passed as an array during resource search requests (see Ordering results).
It is also possible to request that the resources returned be paginated. This is accomplished by passing “page” and “itemsPerPage” parameters in the URL query string. For example, GET /files?page=3&itemsPerPage=50 will return a JSON representation of files 101 through 150. Of course, ordering and pagination parameters may both be supplied in a single request.
Requests of the form GET /resources/id, e.g., GET /collections/43, return a JSON object representation of the resource with the specified id. These requests are routed to the show action of the controller for the resource.
Requests of the form GET /resources/new, e.g., GET /forms/new, return a JSON object containing all of the data necessary to create new resources of the specified type. These requests are routed to the new action of the controller for the relevant resource. For example, when creating a new form resource, it is helpful to know the set of valid grammaticality values, elicitation method names, users, sources, etc. of the system. Therefore, a request to GET /forms/new will return a JSON object of the form listed below, where the values of the attributes are arrays containing the relevant data.
{
"grammaticalities": [ ... ],
"elicitationMethods": [ ... ],
"tags": [ ... ],
"syntacticCategories": [ ... ],
"speakers": [ ... ],
"users": [ ... ],
"sources": [ ... ]
}
This is really just a convenience that saves the trouble of making multiple requests (e.g., to GET /tags, GET /sources, etc.)
Parameters in the query string can be used to alter the content of the response so that only certain datasets are returned. If the URL query string is not empty, then only the attributes of the response object that have non-empty parameters in the query string will be returned. For example, the request GET /forms/new?sources=y&tags=y will result in a response object of the same form as above except that only the sources and tags attributes will have non-empty arrays for values.
If the value of a parameter in the URL query string is a valid ISO 8601 datetime string of the form YYYY-MM-DDTHH:MM:SS, then the value of the corresponding attribute in the response object will be non-empty only so long as the input datetime does not match the most recent datetimeModified value of the specified resources. This permits the requesting of only novel data. For example the request GET /forms/new?sources=2013-02-22T23:28:43 will return nothing but source resources and even these only if there are such that have been updated or created more recently than 2013-02-22T23:28:43.
Some resources have very simple data structures (e.g., tags) and, therefore, requests of the form GET /resources/new on such resources will return an empty JSON object.
Requests of the form GET /resources/id/edit return the resource with the specified id as well as all data required to update that resource. These requests are routed to the edit action of the relevant controller. Such requests can be thought of as a combination of GET /resources/id and GET /resources/new. The JSON object in the response body is of the form
{"resourceName": {...}, "data": {...}}
where the value of the resourceName attribute is the same object as that returned by GET /resources/id and the value of the data attribute is the same as that returned by GET /resources/new. Parameters supplied in the URL query string have the same effect as those supplied to GET /resources/new requests (cf. GET /resources/new).
Requests of the form DELETE /resources/id result in the resource with the specified id being deleted from the database. Such requests are routed to the delete action of the relevant controller. The form and collection resources are special in that they are first saved to a backup table before being deleted; thus these types of resources can be restored after deletion. The response body of a successful deletion request is a JSON object representation of the content of the resource. As mentioned above, only administrators and their enterers may delete form, file and collection resources.
Requests of the form POST /resources result in the creation of a resource of the specified type using the data supplied as a JSON object in the request body. These requests are routed to the create action of the relevant controller. The input data are first validated (as detailed in Input validation). If successful, a JSON object representation of the newly created resource is returned.
Note
All resources receive, upon successful POST and PUT requests, a value for a datetimeModified attribute which is a Coordinated Universal Time (UTC) timestamp. For creation requests on form, file and collection resources, the user who made the request is recorded in the enterer attribute of the resource.
Requests of the form PUT /resources/id result in the updating of the resource of the specified type with the specified id. The data used to update the resource are supplied as a JSON object in the request body. These requests are routed to the update action of the relevant controller. As with the POST requests described above, the input data are validated before the update can occur. If successful, a JSON object representation of the newly updated resource is returned. Upon successful update, the previous versions of form and collection resources are saved to special backup tables of the database (i.e., formbackup and collectionbackup.)
As a general rule, the OLD communicates via JSON. JSON is a widely-used standard for converting certain data types and (nested) data structures to and from strings. Strings, numbers, arrays (lists) and associative arrays (dictionaries) can all be serialized to a JSON string. For example, a Python dictionary, i.e., a set of key/value pairs such as {'transcription': 'dog', 'translations': [{'transcription': 'chien'}]} when converted to JSON would be '{"transcription": "dog", "translations": [{"transcription": "chien"}]}'. In most cases, when an OLD web service requires user input, that input is expected to be JSON in the request body [3].
The OLD provides a powerful search interface to a subset of its resources: collections, collectionbackups, files, forms, formbackups, formsearches, languages, rememberedforms and sources. This interface allows for an unlimited number of filter expressions conjoined via boolean operators into a hierarchical structure of unbounded depth where each filter expression references a resource attribute, a relation and a pattern.
In terms of implementation, search expressions are JSON objects that are mapped to SQLAlchemy query objects which produce SQL queries. In relational database-speak, the OLD search interface permits multi-table queries while taking care of the joins and subqueries automatically. The SQLAQueryBuilder class in lib/SQLAQueryBuilder.py handles the conversion from JSON search expression objects [7] to SQLAlchemy query objects.
Valid search requests (e.g., SEARCH /forms) must contain in the request body a JSON object representing the query. The query object has a ‘query’ attribute whose value is another object which has a mandatory ‘filter’ attribute and an optional ‘orderBy’ attribute. The values of request.body.query.filter and request.body.query.orderBy are both arrays, the former representing the hierarchy of filter expressions conjoined by boolean operators and the latter representing a simple SQL ORDER BY clause:
{
"query": {
"filter": [ ... ],
"orderBy": [ ... ]
}
}
OLD query filters are sets of simple filter expressions configured into a hierarchical structure using negation, conjunction and disjunction. Their syntax is simple and can be described via the following context-free grammar.
filterExpression ::= simpleFilterExpression | complexFilterExpression simpleFilterExpression ::= "[" modelName "," attributeName "," relationName "," pattern "]" | "[" modelName "," attributeName "," attributeModelAttributeName "," relationName "," pattern "]" complexFilterExpression ::= "[", "not" "," filterExpression "]" | "[", "and" "," "[" filterExpression ("," filterExpression)* "]" | "[", "or" "," "[" filterExpression ("," filterExpression)* "]"
That is, a filterExpression is either (1) a simpleFilterExpression or (2) an array whose first element is the string “not” and whose second element is another filterExpression or (3) an array whose first element is one of the strings “and” or “or” and whose second element is an array of one or more filter expressions.
In plain English, a simple filter expression is something like “the transcription contains the character ‘a’”. A simpleFilterExpression is an array with four or five elements. If four, then the first is the name of an OLD model, the second the name of a valid attribute of that model, the third a relation and the fourth a pattern or value. Consider the simple filter expression below (where the forms resources are being searched, i.e., SEARCH /forms).
["Form", "transcription", "like", "%a%"]
This expression is mapped to the SQLAlchemy query object:
query(model.Form).filter(model.Form.transcription.like(u'%a%'))
which generates the SQL that follows.
SELECT * FROM form WHERE transcription LIKE '%a%';
A request to SEARCH /forms with this simpleFilterExpression in the request body would return all form resources whose transcription attribute contains the character “a”.
When a simple filter expression has five elements, the second is assumed to be the name of a relational attribute, i.e., an attribute that references another model, while the third is an attribute of the referenced model. For example, the Form model has an enterer attribute whose value is a User model and a User model has a firstName attribute. Therefore, to find all form resources with enterers whose first name begins with “J” or “S”, we construct the simple filter expression
["Form", "enterer", "firstName", "regex", "^[JS]"]
which maps to the SQLAlchemy query object:
query(model.Form).filter(model.Form.enterer.has(User.firstName.op('regexp')(u'^[JS]')))
The two following simple filter expressions return all forms lacking enterers and all forms having them, respectively.
["Form", "enterer", "=", null]
["Form", "enterer", "!=", null]
Some relational attributes of OLD models reference collections, i.e., lists of zero or more models of a given type. For example, OLD forms can be associated to one or more files, i.e., the Form model has a files attribute whose value is a collection of File objects. Since File objects have id attributes, we can use the filter expression below to retrieve all forms associated to files with one of the following ids: 1, 2, 33, 5.
["Form", "files", "id", "in", [1, 2, 33, 5]]
The four-element filter expression below returns the same result set as the five-element one one above. This is because the OLD knows that the Form model is being queried and that the only relation between the Form and File models is captured by the files attribute of the Form model. [5]
["File", "id", "in", [1, 2, 33, 5]]
The two following simple filter expressions return all forms lacking files and all forms having one or more, respectively.
["Form", "files", "=", null]
["Form", "files", "!=", null]
Complex filter expressions are built from simple filter expressions using “not”, “and” and “or”.
The following complex filter expression uses “not” to return all form resources that do not have “a” in their transcriptions.
["not", ["Form", "transcription", "like", "%a%"]]
Conjoined and disjoined filter expressions are exemplified below.
['and', [['Form', 'transcription', 'like', '%a%'],
['Form', 'elicitor', 'id', '=', 13]]]
['or', [['Form', 'transcription', 'like', '%a%'],
['Form', 'dateElicited', '<', '2012-01-01']]]
Finally, an example of a complex filter expression involving multiple levels of embedding.
['and', [['Translation', 'transcription', 'like', '%1%'],
['not', ['Form', 'morphemeBreak', 'regex', '[28][5-7]']],
['or', [['Form', 'datetimeModified', '<', '2012-03-01T00:00:00'],
['Form', 'datetimeModified', '>', '2012-01-01T00:00:00']]]]]
OLD search requests permit the relations listed below.
Note
Some relations can be referenced by more than one name as indicated in the brackets.
Most of these relations should be self-explanatory. However, the like and regular expression relations merit further discussion.
The “like” relation is simply the SQL LIKE operator. The pattern following the “like” relation may contain the wildcard characters “%” and “_”. The percent sign matches zero or more of any character while the underscore matches exactly one instance of any character. These wildcards are illustrated via some typical use cases below.
Find all forms whose transcription contains “t”:
["Form", "transcription", "like", "%t%"]
Find all forms whose transcription begins with “T”:
["Form", "transcription", "like", "T%"]
Find all forms whose transcription ends with “t”:
["Form", "transcription", "like", "%t"]
Find all forms that contain “k”, followed by any single character, followed by “t”:
["Form", "transcription", "like", "%k_t%"]
Note
As indicated by the above examples, OLD filter expressions are case-sensitive.
The “regexp” (a.k.a. “regex”) relation implements regular expression matching. [8] Regular expressions are tools for specifying complex patterns on strings. As with the “like” relation described above, certain characters and constructions in “regexp” search patterns have special meanings.
By default, regular expressions perform a substring match. That is, an OLD filter expression like the one that follows will return all forms that contain the string “it” anywhere in the value of their transcription attribute.
["Form", "transcription", "regex", "it"]
We can refer to the beginning or end of the string using the anchors “^” and “$”. For example, the following two filter expressions find all forms whose transcription begins with “T” or ends with “s”, respectively.
["Form", "transcription", "regex", "^T"]
["Form", "transcription", "regex", "s$"]
The period ”.” matches any character. For example, the OLD filter expression below will match all forms that have “kat”, “kit”, “kst”, “kqt”, etc. in their transcription values.
["Form", "transcription", "regex", "k.t"]
It is also possible to specify a pattern that matches a limited set of characters using character classes, i.e., sequences of characters enclosed in square brackets. For example, the following OLD filter expression will match all forms whose transcription value contains “k”, followed by a vowel, followed by “t”. (Of course, unicode characters are permitted as well so accented and IPA vowels could be specified here also.)
["Form", "transcription", "regex", "k[aeiou]t"]
If the caret character “^” is the first character in the character class, then the class matches any character except those it contains. For example, the following OLD filter expression will match all forms whose transcriptions contain a “k”, followed by anything but a “q” or another “k”, followed by a “t”.
["Form", "transcription", "regex", "k[^qk]t"]
The vertical bar “|” is the alternation metacharacter. It matches either the string to its left or the string to its right. For example, the following OLD filter expression will return all forms containing a translation that contains either “the cat ran” or “the dog ran”.
["Form", "translations", "transcription", "the (cat|dog) ran"]
Regular expressions also support quantification. That is, it is possible to specify that a pattern zero or one times (using ”?”), zero or more times (using “*”), one or more times (using “+”), exactly n times (using “{n}”), between n and m times (using “{n,m}”) and n or more times (using “{n,}”).
For example, to find all forms whose transcription is a single word with one syllable whose nucleus is transcribed using exactly two vowels, an OLD filter expression like the following might be appropriate.
["Form", "transcription", "regex", "^[ptkmns][aeiou]{2}[ptkmns]$"]
Quantifiers could also be used to filter resources by the length of one of their fields. For example, to find all forms whose transcriptions contain at least five but no more than ten characters, one could use the following OLD filter expression.
["Form", "transcription", "regex", "^.{5,10}$"]
Note
Regular expressions will treat unicode combining characters as separate characters.  Keep this in mind when using regular expression quantifiers to filter based on string length or when using character sets. In the latter case, it is usually safer to use parentheses and the alternation metacharacter than character sets. To illustrate, consider the two examples below. The first OLD filter expression will match “oao”, “oio” and “óo”, which is probably not what was intended. The second filter expression will match “oáo” and “oío”, which is probably what was intended.
["Form", "transcription", "regex", "o[áí]o"]
["Form", "transcription", "regex", "o(á|í)o"]
In making a search request of an OLD web service, it is possible to specify the order in which the results are returned. This is accomplished by specifying an orderBy attribute for the JSON query object that is passed as input in the body of the request. Remember that OLD search requests must contain an object of the following form (where the orderBy attribute is optional).
{"query": {
"filter": [ ... ] ,
"orderBy": [ ... ]}}
The value of the orderBy attribute is an array containing exactly three strings where the first is the name of a model/resource, the second the name of an attribute of the model and the third is a direction, i.e., “asc” or “desc”. For example, the following JSON object passed in the body of a request to SEARCH /forms would return all forms whose transcription begins with “p” ordered by id in descending order.
{"query": {
"filter": ["Form", "transcription", "regex", "^p"],
"orderBy": ["Form", "id", "desc"]}}
This section describes the valid requests that are not covered by the standard RESTful and search interfaces documented in the previous sections. A subset of OLD resources possess such supplemental interfaces. This section is organized by resource.
Form resources represent linguistic forms and are the core of an OLD web service. The non-standard interfaces of form resources are described here.
Requests to GET /forms/history/id are routed to the history action of the forms controller. Such requests return a JSON object representing the history, or previous versions, of the form with the specified id. The id parameter can be the integer id or the Universally Unique Identifier (UUID) of the form. [10] The JSON object returned is of the form
{"form": { ... }, "previousVersions": [ ... ]}
where the value of the “form” attribute is the JSON representation of the form while the value of “previousVersions” is an array of objects representing the previous versions of the form. If the form has been deleted, the value of the “form” attribute will be null and if the form has not been updated or deleted, the value of the “previousVersions” attribute will be an empty array.
Requests to POST /forms/remember are routed to the remember action of the forms controller and cause the forms referenced in the request body to be appended to the rememberedForms collection of the user making the request. The expected input is an object of the form
{"forms": [id1, id2, ... ]}
where id1, id2, etc. are form integer ids.
Requests to PUT /forms/update_morpheme_references regenerates values for the morphemeBreakIDs, morphemeGlossIDs, syntacticCategoryString and breakGlossCategory attributes of all forms in the system. (See the Morphological processing and Form sections for details on these attributes.) The response generated by this request contains a JSON array of ids corresponding to the forms that were updated.
Warning
It should not be necessary to request the regeneration of morpheme references via this request since this should already be accomplished automatically by the call to updateFormsContainingThisFormAsMorpheme on all successful update and create requests on form resources. This interface is, therefore, deprecated (read: use it with caution) and may be removed in future versions of the OLD.
OLD file resources are representations of binary files stored on a filesystem. From a linguist’s point of view, they are the audio/video records of linguistic fieldwork, the images (or audio or video) used as stimuli, PDFs of relevant papers or handouts, etc. – anything that is relevant to a piece or a collection of language data. Multiple file resources can be associated to a given form or collection resource. Thus, for example, a form representing a sentence could be associated to a large audio recording of an elicitation session, a smaller audio recording of just the sentence being uttered, an image used to illustrate a context for a speaker, etc. See the File section for more details on files.
Requests to GET /files/serve/id return the file data of the file resource with the given id, assuming the authenticated user is authorized to access that resource. If the file with the specified id is a subinterval-referencing file, the file data of the parent file is returned; if the file data are hosted externally, an explanatory error message is returned. (See the File for an explanation of subinterval-referencing and externally hosted files.)
Requests to GET /files/serve_reduced/id return the file content of the reduced-size copy of the file which was created by the OLD upon file creation. If there is no reduced-size copy of the file, the OLD returns an error message. These requests handle subinterval-referencing and externally hosted files in the same way as described in the above subsection.
Collections are documents that can reference forms and are useful for creating records of elicitation sessions or for writing papers using data stored on an OLD application. See the Collection section for more details on collections.
Requests to GET /collections/history/id are routed to the history action of the collections controller and return a JSON object representing the history, or previous versions, of the collection with the specified id. The id parameter can be the integer id or the Universally Unique Identifier (UUID) of the collection. [10] The JSON object returned is of the form
{"collection": { ... }, "previousVersions": [ ... ]}
where the value of the “collection” attribute is the JSON representation of the collection while the value of “previousVersions” is an array of objects representing the previous versions of the collection. If the collection has been deleted, the value of the collection attribute will be null and if the collection has not been updated or deleted, the value of the previousVersions attribute will be an empty array.
The application-wide settings for an OLD application are stored as application settings objects. These resources have non-standard interfaces insofar as only administrators are permitted to create, update or delete them. Other types of users can only read them, i.e., request GET /applicationsettings and GET /applicationsettings/id. The application settings resources are also unique in that the most recently created one (i.e., that with the largest id) is designated as the active application settings and is the one that affects the behaviour of the rest of the application. Therefore, application-wide behaviour may be configured either by updating the active application settings resource or by creating a new (and hence active) one. The latter approach is recommended since the previously created application settings resources will provide a history of previous configurations.
User resources represent the users (i.e., administrators, contributors and viewers) of an OLD application. The interface to this resource is non-standard in that only administrators are authorized to create or delete user resources and a user resource can only be updated by administrators and the holder of the user account. See the User section for more details on users.
Each OLD user has a rememberedForms attribute whose value is a collection of zero or more form resources that the user has memorized. Since these collections can grow quite large, they are treated as a resources of their own and are not affected by interactions with user resources. The interface to the remembered forms resources are non-standard in that ...
Requests to GET /rememberedforms/id return the array of forms remembered by the user with the supplied id. Such requests are routed to the show action of the rememberedforms controller. Ordering and pagination parameters may be provided in the query string of this request in exactly the same way as with standard GET /resources requests of conventional resources (cf. GET /resources).
Requests to UPDATE /rememberedforms/id are routed to the update action and set the remembered forms of the user with the supplied id to the set of forms referenced in the JSON array of form ids sent in the request body. This type of request accomplishes creation, updating and deletion of a remembered form “resource”. Only administrators and the user with the supplied id can make licit requests to UPDATE /rememberedforms/id. As with requests to POST /forms/remember, requests to UPDATE /rememberedforms/id should contain a JSON request body of the form {"forms": [16, 28, 385]}.
Note
The remember action of the forms controller has a similar, but more restricted, effect, i.e., requests to POST /forms/remember can add forms to (but not delete them from) the remembered forms collection of the user who makes the request.
Requests to SEARCH /rememberedforms/id return all form resources remembered by the user with the supplied id and which match the JSON search filter passed in the request body. These requests are routed to the search action. Requests to POST /rememberedforms/id/search have the same effect as those to SEARCH /rememberedforms/id.
Note
The same effect can be achieved by conjoining the filter expression ["Memorizer", "id", "=", id] to an existing search on form resources, i.e., a request to SEARCH /forms.
Speakers of endangered languages and their communities often require that the language data gathered by researchers not be made available to the public at large. Therefore, authentication (i.e., a username and password) is required in order to access data on an OLD web service [4].
In addition to authentication, the OLD possesses a role-based system of authorization. The three roles are administrator, contributor and viewer.
Viewers are only able to perform read requests, e.g., view all form resources, retrieve a particular file resource, search the collections resources, etc.
Contributors have read and write access to most resources, with some restrictions. Contributor U1 is not permitted to delete a form, file or collection entered by contributor U2. Only administrators and U1 can delete a form, file or collection entered by U1. In addition, only administrators and user U1 are permitted to update the user resource representing U1.
Administrators have unrestricted access to read and write any resource. Only administrators can create or delete users and only administrators have write access to application settings resources.
Separate from the role-based division of users is a classification into restricted and unrestricted users. While administrators are, by default, always unrestricted, the application settings can specify a subset of contributors and viewers as unrestricted. Only unrestricted users are permitted to access restricted objects, i.e., forms, files or collections tagged with the “restricted” tag. Users not classified as unrestricted (i.e., restricted users) are unable to access restricted objects in any way. Since core objects can be associated to one another (e.g., a form can be associated to multiple files), restricted status can spread from object to object. For example, an unrestricted form becomes restricted as soon as it is associated to a restricted file.
The login controller effects authentication. Its interface is detailed in the following table.
| HTTP Method | URL | Effect | Parameters |
|---|---|---|---|
| POST | /login/authenticate | Attempt to authenticate | JSON object |
| GET | /login/logout | De-authenticate | |
| POST | /login/email_reset_password | Email a newly generated password to the user | JSON object |
POST /login/authenticate attempts authentication using the provided input, i.e., a JSON object on the request body of the form {"username": " ... ", "password": " ... "}. If successful, authenticated status is persisted across requests via a cookie-based session object where the value of session['user'] is the user model of the authenticated user.
A GET /login/logout request removes the 'user' key from the session object associated with the cookie passed in the request. That is, it de-authenticates, or logs out, the user.
A POST /login/email_reset_password request with a JSON object in the request body of the form {"username": " ... "} attempts to create a new, randomly generated password for the user with the provided username and notify the user via email of the change. If the server is unable to send email, the password will not be reset and a JSON error message will be returned in the response.
Note
If an SMTP mail server cannot be used, it is possible (as detailed in the comments of the config file that is generated when paster make-config is run) to configure an OLD application to send email via a specified Gmail account.
For more details on the authentication and authorization scheme of the OLD, please consult the API documentation and/or the source code. Most relevant are the lib/auth.py, controllers/login.py, controllers/forms.py, controllers/files.py and controllers/oldcollections.py modules.
When users attempt to create a new resource or update an existing one, the OLD attempts to validate the input. If validation fails, the status code of the response is set to 400 and a JSON object explaining the issue(s) is returned, i.e., an object of the form {'error': 'error message'} or {'errors': {'field name 1': 'error message 1', 'field name 2': 'error message 2'}}.
Standard validation is validation on user input that is applied by all OLD applications in the same way.
Some representative examples will illustrate. All forms require some string in their transcription field and at least one translation. References to other OLD resources via their ids are validated for existence; e.g., when an elicitor for a form is specified via a user id, then validation ensures that the id corresponds to a user in the database. User-supplied values for date fields must be in mm/dd/yyyy format. Emails must be correctly formatted. Files uploaded must be one of the allowed file types (e.g., .jpg, .wav) of the OLD.
The Pylons controller classes that control the creation and updating of resources ensure that all such validation is passed before these requests can succeed. The validators that encode these validations are written using the FormEncode library and can be found in the lib/schemata.py module of the OLD source. For further information on input validation, consult the Data Structure section, the API documentation and/or the source code.
In addition to the standard validation described above, particular OLD applications can control how, or whether, transcriptions of the object language are validated. The relevant form attributes are transcription, phoneticTranscription, narrowPhoneticTranscription and morphemeBreak. By configuring the OLD application’s settings, adminstrators can control what types of strings are permitted in these fields. This is useful for when groups of researchers want to ensure that, say, all morpheme segmentation strings (i.e., morphemeBreak values) are restricted to sequences of phonemes from the specified inventory plus the specified morpheme delimiters.
The table below shows how object language transcription validation is configured.
| Form attribute | Relevant inventory or orthography | Validation parameter |
|---|---|---|
| transcription | storageOrthography | orthographicValidation |
| phoneticTranscription | broadPhoneticInventory | broadPhoneticValidation |
| narrowPhoneticTranscription | narrowPhoneticInventory | narrowPhoneticValidation |
| morphemeBreak | phonemicInventory* | morphemeBreakValidation |
The validation parameter column lists the attributes of the application settings resource that control whether the form attribute in the first column should be validated against the relevant inventory or orthography. Each of the attributes in the validation parameter column can have one of three possible values: None, Warning or Error. Only if the attribute is set to Error will inventory/orthography-based validation occur.
For example, if the current application settings resource has orthographicValidation set to Error, then input validation will ensure that form transcriptions contain only graphemes (i.e., characters or character sequences) from the storage orthography plus punctuation characters and the space character.
When validation is enabled on the phonetic transcription fields, only graphs from the specified inventory plus the space character are permitted (i.e., no punctuation).
The morphemeBreak attribute’s validation settings are slightly more complex since it is possible to choose between the storage orthography or the phonemic inventory when configuring validation. This is done by setting the morphemeBreakIsOrthographic attribute of the application settings resource to true in the former case and false in the latter. For example, if morphemeBreakIsOrthographic is set to false and morphemeBreakValidation is set to Error, then input to the morphemeBreak field will be rejected if it contains characters outside of the specified phonemic inventory, the specified morpheme delimiters and the space character.
As implied in the above discussion, the application settings resource has morphemeDelimiters and punctuation attributes for specifying sets of valid morpheme delimiters and punctuation, respectively.
Sometimes it is desirable to include foreign words in the object language transcriptions while still permitting validation against inventories and orthographies on these fields. For example, in a system where morphemeBreak validation is enabled and the phonemic inventory is /p/, /t/, /k/, /i/, /a/, /u/, it might be desirable to allow a morphemeBreak value of “ki dog katti” but prohibit “ki dog kotti”. The OLD permits this via the special “foreign word” tag on form resources. When a form is tagged as a foreign word, its transcription values affect validation. So, if the system were to contain a foreign word form with “dog” as its morphemeBreak value, then validation would correctly allow both instances of “dog” in the above two examples while disallowing the latter example because of the illicit “o” in “kotti”. The function updateApplicationSettingsIfFormIsForeignWord is called in the forms controller upon successful create and update requests and is responsible for updating the validators with the foreign word information.
When requests cause resources to be created or updated, the OLD may perform some additional processing that may affect the values of certain attributes of the target resource or even of other resources. The notable data processing functionalities are listed below and are detailed in their own subsections.
Values for four attributes of form resources related to morphological analysis are generated on create and update requests. These are the morphemeBreakIDs, morphemeGlossIDs, syntacticCategoryString and breakGlossCategory attributes. The function compileMorphemicAnalysis in the forms controller is responsible for generating these values.
The values of the morphemeBreakIDs and morphemeGlossIDs attributes are arrays that hold references to other forms that match the morphemes indicated in the user-defined morphemeBreak and morphemeGloss attributes. Each array has one array per word in the relevant field, each word array has one array per morpheme and each morpheme array has one array per match found. Matches are ordered triples where the first element is the id of the match, the second is the morphemeBreak or morphemeGloss value of the match and the third is the syntacticCategory.name of the match or null if no category is specified. As illustration, consider a database containing the following forms.
| id | transcription | morphemeBreak | morphemeGloss | syntacticCategory.name |
|---|---|---|---|---|
| 1 | chien | chien | dog | N |
| 2 | s | s | PL | Agr |
| 3 | s | s | PL | Num |
| 4 | le | le | the | D |
| 5 | cour | cour | run | V |
| 6 | ent | ent | 3.PL | Agr |
| 7 | les chiens courent | le-s chien-s cour-ent | the-PL dog-PL run-3PL | S |
When the form with id 7 is entered, the system will generate the following arrays for the morphemeBreakIDs and morphemeGlossIDs attributes.
morphemeBreakIDs = [
[
[[4, 'the', 'D']],
[[2, 'PL', 'Agr'], [3, 'PL', 'Num']]
],
[
[[1, 'dog', 'N']],
[[2, 'PL', 'Agr'], [3, 'PL', 'Num']]
],
[
[[5, 'run', 'V']],
[[6, '3.PL', 'Agr']]
]
]
morphemeGlossIDs = [
[
[[4, 'le', 'D']],
[[2, 's', 'Agr'], [3, 's', 'Num']]
],
[
[[1, 'chien', 'N']],
[[2, 's', 'Agr'], [3, 's', 'Num']]
],
[
[[5, 'cour', 'V']],
[]
]
]
Note
The morphemeBreakIDs[0][1] value contains two match triples because the second morpheme of the first word in the morphemeBreak line, i.e., “s”, matches two forms, i.e., the forms with ids 2 and 3. Similarly, morphemeGlossIDs[0][1] contains two analogous match triples, the difference in this case being that the morpheme’s phonemic/orthographic representation is listed and not its gloss. In contrast, the morpheme break “ent” matches form 6, hence the single match triple in morphemeBreakIDs[2][1], whereas “3PL” matches nothing, hence the absence of matches in morphemeGlossIDs[2][1].
The purpose of the morphemeBreakIDs and morphemeGlossIDs attributes is that they record the extent to which the morphemic analysis of a given form is in accordance with the lexical items listed in the database. If these values were not generated server-side upon create and update requests, then for any user-facing application to display such information would require many requests and database queries each time a form were displayed. The information in these two attributes is quite valuable in that it can be used to immediately inform users when the lexical items implicit in their morphological analyses are not yet listed in the database or when small differences in, say, glossing conventions are masking underlying consensus in analysis.
At the same time as the morphemeBreakIDs and morphemeGlossIDs values are generated, so too are the values for the syntacticCategoryString and breakGlossCategory attributes. These values for our example form 7 from above would be:
syntacticCategoryString = 'D-Agr N-Agr V-Agr'
breakGlossCategory = 'le|the|D-s|PL|Agr chien|dog|N-s|PL|Agr cour|run|V-ent|3PL|Agr'
The value of the syntacticCategoryString attribute is a string of syntactic category names corresponding to the string of morphemes in the morphemic segmentation.[#f11]_ Since the syntactic category string can be used to filter form resources on search requests, its generation facilitates search based on high-level morphological patterns. For example, using the syntactic category string, one could use regular expressions to search for all forms consisting of an NP followed by a VP.
Note
Given our example dataset, 'D-Num N-Num V-Agr' is a reasonable (and perhaps preferable) syntactic category string value. However, the system has no way of knowing this and therefore when there are two matches for a morpheme (as there are for “s”) it arbitrarily chooses the syntactic category of the lexical form with the lowest id.
The value of breakGlossCategory is a string that unambiguously represents the morphemic analysis of the form. Each morpheme is taken to be a triplet consisting of a phonemic representation (i.e., the morphemeBreak value), a semantic representation (i.e., the morphemeGloss value) and a categorial value (i.e., the syntacticCategory.name value). These break-gloss-category triplets are delimited by the vertical bar “|” and each such triplet is joined using the morpheme delimiters of the morphemeBreak value.
This attribute makes it possible to search for forms that contain a specific morpheme. Consider the case where one wanted to find all forms containing the morpheme “s” glossed as “PL” of category “Num”. Performing a regular expression search on the morphemeBreak line for the pattern -s( |-|$) (i.e., “-s” followed by a space, “-” or the end of the string) would be insufficient since it might also find forms containing an “s” morpheme with a different gloss. Conjoining the above regular expression filter with another on the morphemeGloss line with the pattern -PL( |-|$) would still be insufficient since it would (contra what is desired) match a form with a morphemeBreak value of “le-s oiseau-x” and a morphemeGloss value of “the-plrl bird-PL”. By searching the forms according to those whose breakGlossCategory value matches the regular expression -s\|PL\|Num( |-|$), one can be assured of finding all and only all the forms containing the morpheme “s”/”PL”/”Num”
Given the above discussion, it is evident that an update to an existing lexical form, the creation of a new one or the updating of the name of a syntactic category may require updating the morphemeBreakIDs, morphemeGlossIDs, syntacticCategoryString and/or breakGlossCategory values of a number of different forms. The OLD accomplishes this by calling updateFormsContainingThisFormAsMorpheme whenever a form is created or updated. This function first assesses whether the newly created/updated form is lexical and, if so, it selects all forms whose morphological analyses implicitly reference the lexical form and updates the relevant fields appropriately. Care is taken to reduce database select queries to an absolute minimum with the end result being that the majority of calls to updateFormsContainingThisFormAsMorpheme will require only one select query, i.e., the one to find all of the forms that reference the lexical item just created/updated. In addition, when the name of a (lexical) syntactic category is changed, updateFormsContainingThisFormAsMorpheme is called on each form that has that category.
Whenever a form is created, updated or deleted, the forms controller calls updateApplicationSettingsIfFormIsForeignWord. This function is responsible for updating the transcription validators of the application settings if the form is a foreign word. As described in Object language validation, forms tagged with the “foreign word” tag will create exceptions to the user-defined object language transcription validation. For example, if a form is entered with transcription, morphemeBreak and morphemeGloss values of “John”, “John” and “John” and is tagged as a “foreign word”, then the system will allow the string “John” to be included in the transcription field of other forms even if validation is set to reject forms whose transcriptions contain, say, “J” or “h”.
Note
It is desirable to be able to enter such a lexical entry as “John” with a category of, say, “PN” since doing so will result in sensible syntacticCategoryString values for forms containing “John” in their morphemeBreak value.
The contents attribute of collections is a string that may contain references to forms and other collections. These references determine the value of the contentsUnpacked, html and forms attributes.
When the value of the contents attribute of an existing collection is updated, the update action calls updateCollectionsThatReferenceThisCollection in order to update the contentsUnpacked, html and forms values of all of the collections that reference the updated collection. This same function is called when a collection is deleted; in this case, all references to the deleted collection are removed from any collections that were referencing it and the appropriate values are updated. Similarly, when a form is deleted, the delete action calls updateCollectionsReferencingThisForm and all references to the to-be-deleted form are removed from any collections that reference it.
See the Collection section for more details on collection references and the attributes whose values depend on them.
When new file models are created with locally stored file data, the OLD may create reduced-size copies of certain file types and store them, by default, in files/reduced_files/. Such lossy copies are created when create_reduced_size_file_copies is set to a truthy value (e.g., “1”) in the config file and if the relevant utilities are installed, i.e., for images the Python Imaging Library and for WAV files the FFmpeg command-line utility. See the Soft dependencies and File sections for more details.
| [1] | See this StackOverflow page for a discussion on what exactly REST means and read Fielding’s thesis for the source of the term. |
| [2] | The WebDAV standard includes a SEARCH method so this is not entirely without precedent. |
| [3] | In contrast to POST, PUT and DELETE requests, HTTP GET requests are not, canonically, supposed to possess contentful request bodies; therefore, when optional parameters are permissible on such requests, the OLD will expect GET parameters in the URL string. |
| [4] | Future versions of the OLD may make authentication a configurable option, thus allowing publicization of all data. Another possibility is that the system could allow users to tag some data as public and that these data could be accessed without authentication. A final possibility would be to publicize all data but allow some data to be encrypted such that only authenticated users could decrypt them. |
| [5] | Note that while the results returned will be the same, the SQLAlchemy query object constructed and the SQL issued to the database will be distinct. That is, the filter expression ["Form", "files", "id", "in", [1, 2, 33, 5]] maps to the SQLAlchemy query query(model.Form).filter(model.Form.files.any(model.File.id.in_([1, 2, 33, 5]))) while ["File", "id", "in", [1, 2, 33, 5]] maps to fileAlias = aliased(File) and Session.query(Form).filter(fileAlias.id.in_([1, 2, 33, 5])).outerjoin(fileAlias, Form.files). |
| [6] | Substring pattern match is effected via the SQL LIKE relation. TALK ABOUT WILDCARDS HERE |
| [7] | Actually, the search actions of the relevant controllers convert the JSON string to a Python dictionary using the loads function of the simplejson module. |
| [8] | With MySQL as RDBMS, the “regexp” relation is simply the standard MySQL REGEXP operator, i.e., an implementation of POSIX extended regular expressions. Since SQLite does not implement a REGEXP operator, the OLD supplies one using the standard re Python module. The table on this page does a good job of detailing the difference between these two regular expression implementations. |
| [9] | Cf. http://unicode.org/reports/tr15/ |
| [10] | (1, 2) Since some RDBMSs reuse primary key integers when a record is deleted, it is not possible to associate forms and collections to their backups via their integer id attributes. Therefore, both form and collection resources have UUID attributes and are associated to their backup objects via both form_id/collection_id and UUID attributes. The safest way, therefore, to request all of the backups of a given form/collection, therefore is to pass the UUID to the relevant history GET request. |
| [11] | Note that the morpheme delimiters for both the syntacticCategoryString and breakGlossCategory values are taken, arbitrarily, from the morphemeBreak value. That is, if the morphemic segmentation were “chien-s” and the gloss string were “dog=PL” (and “-” and “=” were both valid morpheme delimiters of the system), then the syntactic category string would be ‘N-Num’ and not ‘N=Num’. Similarly, the breakGlossCategory value would be ‘chien|dog|N-s|PL|Num’ and not ‘chien|dog|N=s|PL|Num’. |


Streaming Music
Home
Overview
Comparison
History
Contact
Quiz
Quiz
A very long anwer which has no meaning at all. But I hope we will get a line break.
Answer2
Answer3
Answer4


The information contained here is only useful if you want to modify the source code, for example to add functionality, fix bugs, or port it to other platforms.
The code is written in the C++11 version of C++ (g++ option "-stdc++0x"). It does use some features unique to gcc and the x86-64 architecture, so porting to other compilers and/or architectures will not be immediate.
The code uses extensively the C++ standard libraries and the Boost libraries. The current version was developed on Linux Mint 18 (a Linux distribution derived from Ubuntu 16.04) and uses Boost version 1.58. However the code should not be strictly dependent on this specific version of Boost.
All code is defined in C++ namespace ChanZuckerberg::ExpressionMatrix2. This will reduce the chance of name conflicts if the code has to be compiled or linked with other C++ libraries. Several names from the std and boost namespaces are added to the ExpressionMatrix2 namespace via using directives (namespace composition).
The code is build as a shared library that can be imported in Python. This is achieved using the boost python library. The code that does this is in src/PythonModule.cpp. It is little more than a list of the classes and functions to be made available in Python. The code is currently built for Python 3, but it should be possible to port it to Python 2 by simply changing the include files and libraries using during compilation and linking.
Persistent data structures are stored in binary files which are memory mapped for efficient access. Various container-like classes that use mapped files are defined for this purpose. See template class ChanZuckerberg::ExpressionMatrix2::MemoryMapped::Vector an other classes defined in the same namespace. Mapped files are manipulated using native linux calls such as mmap and truncate. This presents some advantages compared to corresponding functionality in the boost iostreams library, however it reduces portability.


You might think you’re writing JSX:
<marquee bgcolor="#ffa7c4">hi</marquee>
But really, you’re calling a function:
React.createElement(
/* type */ 'marquee',
/* props */ { bgcolor: '#ffa7c4' },
/* children */ 'hi'
)
And that function gives you back an object. We call this object a React element. It tells React what to render next. Your components return a tree of them.
{
type: 'marquee',
props: {
bgcolor: '#ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$typeof: Symbol.for('react.element'), // 🧐 Who dis
}
If you used React you might be familiar with type
, props
,
key
, and ref
fields.
But what is $$typeof
? And why does it have a Symbol()
as a
value?
That’s another one of those things that you don’t need to know to use React, but that will make you feel good when you do. There’s also some tips about security in this post that you might want to know. Maybe one day you’ll write your own UI library and all of this will come in handy. I certainly hope so.
Before client-side UI libraries became common and added basic protection, it was common for app code to construct HTML and insert it into the DOM:
const messageEl = document.getElementById('message');
messageEl.innerHTML = '
' + message.text + '
';
That works fine, except when your message.text
is something like
''
.
You don’t want things written by strangers to appear verbatim in your app’s rendered
HTML.
(Fun fact: if you only do client-side rendering, a


Conor Townsend feeling much more confident at West Brom
Albion full-back Conor Townsend is grateful for the faith shown in him by Slaven Bilic and now feels much more confident as a Championship player.
Townsend has impressed at left-back after an injury to Kieran Gibbs and Nathan Ferguson's suspension.
The 26-year-old has helped the Baggies in keeping clean sheets in the last two games and is aiming to clinch another one against Sheffield Wednesday at The Hawthorns on Saturday.
“I’ve seen an improvement in my own performances this season. I feel a lot more confident," said Townsend, who was signed from Scunthorpe in the summer of 2018.
“I came up from League One and it probably took me a little bit of time to adjust to the level, even though I wouldn’t have admitted that at the time.
“I think confidence is the main difference I see in myself this season.
"The confidence that the manager and coaching staff have given me is great and I hope that shows on the pitch.
“They are putting on sessions that are spot on and I think you can see that in the way we are playing as a team. We play good football. We dominate possession and games and that suits me more as a player."
With Ferguson serving another game on his ban, Townsend is set to start against Wednesday.
“I do feel more confident stepping out on the pitch now which obviously helps my performance," he said.
“I’d been watching from the side earlier in the campaign and the team have been playing brilliantly. They are a joy to watch.
“I’ve just wanted to get involved, contribute and play a part. I feel like I’ve done that since I’ve been in the team. It’s been nice to play."
Townsend added: “I think I have done alright. I still think there is more to come. I’m trying to keep working as hard as I can in training every day. Hopefully, I can stay in the team."


AMAZING PEOPLE ARE MAKING AMAZING DESIGNS IN A FUN ENVIRONMENT
when you work with us, you are part of a team of committed collaborations. All aspects of our software development process are intergrated, interactive and agile.
Our approach unifies design, development and product management to create exceptional products.
We start each project by understanding your business goals, the user's needs and the product requirements.
Then we help translate them into effective and elegant solutions.
Before we sign a contract or write a line of code our team will spend the necessary time needed to understand your product vision
The outcome of this scoping session is proposal or high-level statement of work
based on your requirements, we can provide acomplete offering or just the pieces you need.
DESIGN
Our design practice offers a full range of services including brand strategy, interaction and visual design and user experience testing
Throughout your project, our designers create and implement visual design and worflows,solicit user feedback and work eith you to make sure what gets built is what is needed.
DEVELOPMENT
All engineers are fluent in the latest enterprise, mobile and web development technologies.
They collaborate with your team to write and improve code on a daily basis, using proven practices such as test-driven development and pair programming.
PRODUCT MANAGMENT
Planning and development is iterative. Because we are constantly coding and testing the product we build are always ready to go live
This iterative process allows for changes as business requirements evolve
DELANI STUDIO
2019


public abstract class CalendarSystem
extends java.lang.Object
CalendarSystem
is an abstract class that defines the
programming interface to deal with calendar date and time.
CalendarSystem
instances are singletons. For
example, there exists only one Gregorian calendar instance in the
Java runtime environment. A singleton instance can be obtained
calling one of the static factory methods.
For the methods in a CalendarSystem
that manipulate
a CalendarDate
, CalendarDate
s that have
been created by the CalendarSystem
must be
specified. Otherwise, the methods throw an exception. This is
because, for example, a Chinese calendar date can't be understood
by the Hebrew calendar system.
Name Calendar System --------------------------------------- gregorian Gregorian Calendar julian Julian Calendar japanese Japanese Imperial Calendar
CalendarDate
| Constructor and Description |
|---|
CalendarSystem() |
| Modifier and Type | Method and Description |
|---|---|
static CalendarSystem |
forName(java.lang.String calendarName)
Returns a
CalendarSystem specified by the calendar
name. |
abstract CalendarDate |
getCalendarDate() |
abstract CalendarDate |
getCalendarDate(long millis)
Calculates calendar fields from the specified number of
milliseconds since the Epoch, January 1, 1970 00:00:00 UTC
(Gregorian).
|
abstract CalendarDate |
getCalendarDate(long millis,
CalendarDate date) |
abstract CalendarDate |
getCalendarDate(long millis,
java.util.TimeZone zone) |
abstract Era |
getEra(java.lang.String eraName)
Returns the
Era designated by the era name that
has to be known to this calendar system. |
abstract Era[] |
getEras()
Returns valid
Era s of this calendar system. |
static Gregorian |
getGregorianCalendar()
Returns the singleton instance of the
Gregorian
calendar system. |
abstract int |
getMonthLength(CalendarDate date)
Returns the length in days of the month specified by the calendar
date.
|
abstract java.lang.String |
getName()
Returns the name of this calendar system.
|
abstract CalendarDate |
getNthDayOfWeek(int nth,
int dayOfWeek,
CalendarDate date)
Returns a
CalendarDate of the n-th day of week
which is on, after or before the specified date. |
abstract long |
getTime(CalendarDate date)
Returns the number of milliseconds since the Epoch, January 1,
1970 00:00:00 UTC (Gregorian), represented by the specified
CalendarDate . |
abstract int |
getWeekLength()
Returns the length in days of a week in this calendar
system.
|
abstract int |
getYearLength(CalendarDate date)
Returns the length in days of the specified year by
date . |
abstract int |
getYearLengthInMonths(CalendarDate date)
Returns the number of months of the specified year.
|
abstract CalendarDate |
newCalendarDate()
Constructs a
CalendarDate that is specific to this
calendar system. |
abstract CalendarDate |
newCalendarDate(java.util.TimeZone zone) |
abstract boolean |
normalize(CalendarDate date)
Normalizes calendar fields in the specified
date . |
abstract void |
setEra(CalendarDate date,
java.lang.String eraName) |
abstract CalendarDate |
setTimeOfDay(CalendarDate date,
int timeOfDay) |
abstract boolean |
validate(CalendarDate date)
Checks whether the calendar fields specified by
date
represents a valid date and time in this calendar system. |
public static Gregorian getGregorianCalendar()
Gregorian
calendar system.Gregorian
instancepublic static CalendarSystem forName(java.lang.String calendarName)
CalendarSystem
specified by the calendar
name. The calendar name has to be one of the supported calendar
names.calendarName
- the calendar nameCalendarSystem
specified by
calendarName
, or null if there is no
CalendarSystem
associated with the given calendar name.public abstract java.lang.String getName()
public abstract CalendarDate getCalendarDate()
public abstract CalendarDate getCalendarDate(long millis)
millis
- the offset value in milliseconds from January 1,
1970 00:00:00 UTC (Gregorian).CalendarDate
instance that contains the
calculated calendar field values.public abstract CalendarDate getCalendarDate(long millis, CalendarDate date)
public abstract CalendarDate getCalendarDate(long millis, java.util.TimeZone zone)
public abstract CalendarDate newCalendarDate()
CalendarDate
that is specific to this
calendar system. All calendar fields have their initial
values. The default time zone
is
set to the instance.CalendarDate
instance that contains the initial
calendar field values.public abstract CalendarDate newCalendarDate(java.util.TimeZone zone)
public abstract long getTime(CalendarDate date)
CalendarDate
.date
- the CalendarDate
from which the time
value is calculatedpublic abstract int getYearLength(CalendarDate date)
date
. This method does not perform the
normalization with the specified CalendarDate
. The
CalendarDate
must be normalized to get a correct
value.public abstract int getYearLengthInMonths(CalendarDate date)
CalendarDate
. The CalendarDate
must
be normalized to get a correct value.public abstract int getMonthLength(CalendarDate date)
CalendarDate
must
be normalized to get a correct value.date
- the date from which the month value is obtainedjava.lang.IllegalArgumentException
- if the specified calendar date
doesn't have a valid month value in this calendar system.public abstract int getWeekLength()
public abstract Era getEra(java.lang.String eraName)
Era
designated by the era name that
has to be known to this calendar system. If no Era is
applicable to this calendar system, null is returned.eraName
- the name of the eraEra
designated by
eraName
, or null
if no Era is
applicable to this calendar system or the specified era name is
not known to this calendar system.public abstract Era[] getEras()
Era
s of this calendar system. The
return value is sorted in the descendant order. (i.e., the first
element of the returned array is the oldest era.) If no era is
applicable to this calendar system, null
is returned.Era
s, or
null
if no era is applicable to this calendar
system.public abstract void setEra(CalendarDate date, java.lang.String eraName)
java.lang.IllegalArgumentException
- if the specified era name is
unknown to this calendar system.Era
public abstract CalendarDate getNthDayOfWeek(int nth, int dayOfWeek, CalendarDate date)
CalendarDate
of the n-th day of week
which is on, after or before the specified date. For example, the
first Sunday in April 2002 (Gregorian) can be obtained as
below:
Gregorian cal = CalendarSystem.getGregorianCalendar();
CalendarDate date = cal.newCalendarDate();
date.setDate(2004, cal.APRIL, 1);
CalendarDate firstSun = cal.getNthDayOfWeek(1, cal.SUNDAY, date);
// firstSun represents April 4, 2004.
This method returns a new CalendarDate
instance
and doesn't modify the original date.nth
- specifies the n-th one. A positive number specifies
on or after the date
. A non-positive number
specifies on or before the date
.dayOfWeek
- the day of weekdate
- the datedayOfWeek
after
or before the specified CalendarDate
public abstract CalendarDate setTimeOfDay(CalendarDate date, int timeOfDay)
public abstract boolean validate(CalendarDate date)
date
represents a valid date and time in this calendar system. If the
given date is valid, date
is marked as normalized.date
- the CalendarDate
to be validatedtrue
if all the calendar fields are consistent,
otherwise, false
is returned.java.lang.NullPointerException
- if the specified
date
is null
public abstract boolean normalize(CalendarDate date)
date
. Also all undefined
fields are set to correct values. The actual
normalization process is calendar system dependent.date
- the calendar date to be validatedtrue
if all fields have been normalized;
false
otherwise.java.lang.NullPointerException
- if the specified
date
is null


By now, your news feed might have been bombarded with reports about the newest Tesla, the Cybertruck – a pickup truck that's so familiar, it looks straight out of the Blade Runner sci-fi movie from the '80s or made from inside the Minecraft video game. From which you think it was from is entirely up to you.
Now, people have strong opinions about the Tesla Cybertruck, including who the real winners and losers are from the explosive reveal in California. Most of the things people say concentrate on the electric pickup truck's design, but what do you really expect to see inside an outrageous shell?
Gallery: Tesla Cybertruck's Interior (Screenshots From Video)
Shmee150's business manager had a chance to ride the newest Tesla during its launch. Based on the video uploaded on Youtube, the Cybertruck's cabin is quite the opposite of what you'll expect from its loud exterior. While the seats follow the futuristic exterior design, the interior's a little tamed and has a minimalist approach. Nothing's really loud there – except for the white table-top dashboard.
All We Know About The Cybertruck:
For starters, the dashboard only contains the huge infotainment tablet and the unconventionally-shaped steering wheel. The only thing loud in the interior is the lack of things that you'll normally find in a car.
Gallery: Tesla Cybertruck Pickup Truck Debut
There are things we've noticed after watching the video, though. At launch, the Cybertruck was touted with a 6-seat capacity – two rows with three seats each. On the video, however, there were only five, but it looks like the center front seat was just folded to conceal the sixth seat. We also noticed that the lack of wing mirrors has been replaced by a wide camera display, presumably located at the back of the Cybertruck.
There is more to know about the Cybretruck at this point, so let's all wait until the production version has been revealed in the next year or so.


In the above, we assume that X and x are always related to each other by the guiding-center transformation (8) or (10) , i.e., x and X are not independent. For some cases, it may be convenient to treat x and X as independent variables and express the guiding-center transformation via an integral of the Dirac delta function. For example,
|
| (235) |
where x and X are considered as independent variables, ρ is the gyroradius evaluated at x, δ3(x − X − ρ) is the three-dimensional Dirac delta function. [In terms of general coordinates (x1,x2,x3), the three-dimensional Dirac delta function is deﬁned via the 1D Dirac delta function as follows:
|
| (236) |
where 𝒥 is the the Jacobian of the general coordinate system. The Jacobian is included in order to make δ3(x) satisfy the normalization condition ∫ δ3(x)dx = ∫ δ3(x)|𝒥|dx1dx2dx3 = 1.]
Expression (235) can be considered as a transformation that transforms an arbitrary function from the guiding-center coordinates to the particle coordinates. Similarly,
|
| (237) |
is a transformation that transforms an arbitrary function from the the particle coordinates to the guiding-center coordinates.


WARNING: This is a proof-of-concept calculator designed to give a general idea of how big of a mortgage you can afford defined by how much you can afford per payment.
Details
$
(ex: 2.64)
%
You can afford $.


Please enter your token to have access to the application:
Available types of products
Freezer section
Product section
Trends
To remove a freezer. It is mandatory that this freezer does not have an history. Thus it should be empty.
It can be interesting to have some knowlegde about the tendencies of the different users. For a user, it is also interesting to have information about his tendencies. This page is dedicated to that purpose. The colored bars are the types of products for which you may have an interest.


Agenda
- Introduce the topic
- Introduce myself and my native desktop product
- Get to know each other
- Break into small groups and list benefits of specific desktop apps
- Compile list of benefits and looks for commonalities
I help
people*
get jobs.
* in the entertainment industry
FastCapture
Native application for capturing, editing, and encoding audition videos.
What's in your Dock or Start menu?
Do you have a native desktop app in your product portfolio?
Do you have a native desktop app in your roadmap?
Which OS do you primarily use?
Assignment
- Value proposition
- Platforms
- Justification vs Mobile/Web
- Critique
- Recommendation


|
| | SC_DEFINE_MESSAGE (SC_ID_NO_BOOL_RETURNED_, 500, "operator does not return boolean") SC_DEFINE_MESSAGE(SC_ID_NO_INT_RETURNED_ |
| |
| | operator does not return int") SC_DEFINE_MESSAGE (SC_ID_NO_SC_LOGIC_RETURNED_, 502, "operator does not return sc_logic") SC_DEFINE_MESSAGE(SC_ID_OPERAND_NOT_SC_LOGIC_ |
| |
| operand is not sc_logic | SC_DEFINE_MESSAGE (SC_ID_OPERAND_NOT_BOOL_, 504, "operand is not bool") SC_DEFINE_MESSAGE(SC_ID_INSTANCE_EXISTS_ |
| |
| operand is not sc_logic object already exists | SC_DEFINE_MESSAGE (SC_ID_ILLEGAL_CHARACTERS_, 506, "illegal characters") SC_DEFINE_MESSAGE(SC_ID_VC6_PROCESS_HELPER_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module | exceeded (VC6)" ) SC_DEFINE_MESSAGE(SC_ID_END_MODULE_NOT_CALLED_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors | SC_DEFINE_MESSAGE (SC_ID_SET_STACK_SIZE_, 511, "set_stack_size() is only allowed for SC_THREADs and SC_CTHREADs") SC_DEFINE_MESSAGE(SC_ID_SC_MODULE_NAME_USE_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name | SC_DEFINE_MESSAGE (SC_ID_SC_MODULE_NAME_REQUIRED_, 513, "an sc_module_name parameter for your constructor is required") SC_DEFINE_MESSAGE(SC_ID_SET_TIME_RESOLUTION_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed | SC_DEFINE_MESSAGE (SC_ID_SET_DEFAULT_TIME_UNIT_, 515, "set default time unit failed") SC_DEFINE_MESSAGE(SC_ID_DEFAULT_TIME_UNIT_CHANGED_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution | SC_DEFINE_MESSAGE (SC_ID_INCONSISTENT_API_CONFIG_, 517, "inconsistent library configuration detected") SC_DEFINE_MESSAGE(SC_ID_WAIT_NOT_ALLOWED_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution | wait () is only allowed in SC_THREADs and SC_CTHREADs" ) SC_DEFINE_MESSAGE(SC_ID_NEXT_TRIGGER_NOT_ALLOWED_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution | next_trigger () is only allowed in SC_METHODs" ) SC_DEFINE_MESSAGE(SC_ID_IMMEDIATE_NOTIFICATION_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration | SC_DEFINE_MESSAGE (SC_ID_HALT_NOT_ALLOWED_, 522, "halt() is only allowed in SC_CTHREADs") SC_DEFINE_MESSAGE(SC_ID_WATCHING_NOT_ALLOWED_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration | watching () has been deprecated |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use | reset_signal_is ()" ) SC_DEFINE_MESSAGE(SC_ID_DONT_INITIALIZE_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use | dont_initialize () has no effect for SC_CTHREADs" ) SC_DEFINE_MESSAGE(SC_ID_WAIT_N_INVALID_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use | wait (n) is only valid for n > 0" ) SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed | SC_DEFINE_MESSAGE (SC_ID_MAKE_SENSITIVE_POS_, 527, "make sensitive pos failed") SC_DEFINE_MESSAGE(SC_ID_MAKE_SENSITIVE_NEG_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed make sensitive neg failed | SC_DEFINE_MESSAGE (SC_ID_INSERT_MODULE_, 529, "insert module failed") SC_DEFINE_MESSAGE(SC_ID_REMOVE_MODULE_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed make sensitive neg failed remove module failed | SC_DEFINE_MESSAGE (SC_ID_NOTIFY_DELAYED_, 531, "notify_delayed() cannot be called on events " "that have pending notifications") SC_DEFINE_MESSAGE(SC_ID_GEN_UNIQUE_NAME_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed make sensitive neg failed remove module failed cannot generate unique name from null string | SC_DEFINE_MESSAGE (SC_ID_MODULE_NAME_STACK_EMPTY_, 533, "module name stack is empty: did you forget to " "add a sc_module_name parameter to your module " "constructor?") SC_DEFINE_MESSAGE(SC_ID_NAME_EXISTS_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed make sensitive neg failed remove module failed cannot generate unique name from null string name already exists | SC_DEFINE_MESSAGE (SC_ID_WAIT_NEGATIVE_CYCLES_, 535, "wait(n) not allowed for n <= 0") SC_DEFINE_MESSAGE(SC_ID_IMMEDIATE_SELF_NOTIFICATION_ |
| |
| operand is not sc_logic object already exists internal maximum number of processes per module module construction not properly hierarchical name as shown may be incorrect due to previous errors incorrect use of sc_module_name set time resolution failed default time unit changed to time resolution immediate notification is not allowed during update phase or elaboration use make sensitive failed make sensitive neg failed remove module failed cannot generate unique name from null string name already exists immediate self notification ignored as of IEEE | SC_DEFINE_MESSAGE (SC_ID_WAIT_DURING_UNWINDING_, 537, "wait() not allowed during unwinding") SC_DEFINE_MESSAGE(SC_ID_CYCLE_MISSES_EVENTS_ |
| |


A History Has Written For Nemoshi
Founded since 2017, the name Nemoshi immediately stole the attention of the foodies.
This tiny restaurant in the Panglima Polim area marries burgers and sushi in a dish
called 'Nemoshi.'
Founded since 2017, the name Nemoshi immediately stole the attention of the foodies.
This tiny restaurant in the Panglima Polim area marries burgers and sushi in a dish
called 'Nemoshi.'


About Me
Susan Villatoro is a determined individual, who has dedicated the past twelve years to breaking the generational cycle of abuse and neglect within families. What she lacks in size she makes up for in personality. Her positive attitude and creative way of thinking leads to quickly building rapport with her clients, allowing the client to feel supported as they venture on a new journey.
When she is not working, Susan volunteers her time with different animal, arts, and LGBT organizations. She believes that every person and animal should have the opportunity to thrive. Susan also enjoys binge watching YouTube Videos whenever possible and lives by the motto “DFTBA” (Don’t Forget to Be Awesome), which she learned from her favorite YouTubers, vlogbrothers.


To bring you a brand new user experience, Oria has built a sophisticated system that enables you to compose your music with effects without using any features on your synthesizer. Everything is made so that using our connected ring and a MIDI software, you are freely able to add effects on your composition by moving your hand.


Tile Path
The Tile Path command may be used to apply a repetative decoration to a font. You invoke the command on a glyph (or set of glyphs), then design your tile(s). All selected paths in the glyph will be replaced by the tile fit to the curve.
Consider the following:
| ![](img/tilepath-orig. | png) | |
| The tile | Two paths to be tiled. | The result. |
The tile has been replicated (and warped) to follow the original contours.
As you can see above there are several different tiles you can specify. You must specify the tile called Medial; you may specify the other three. There meanings are:
- If you have an open contour and a single tile will cover it, then the "Isolated" tile will be used
- Otherwise, if you have an open contour, then the first tile laid down will be the "First" tile, the last tile laid will be the "Final" tile, and any intermediate tiles will be the medial tiles.
- Closed contours will always be covered by "Medial" tiles.
The reasoning behind this is that you may want special edge effects. In the example above it would be nice if the ends of open contours were automatically closed, so the first and final tiles might look just like the medial tile except with their respective edges closed, while the isolated tile would have both edges closed.
The Tile Path dialog gives you several choices to control how the tile is placed. The tile can be either centered on the path, or be tangent to the left edge of the path (for a clockwise path, the left edge is outside the path), or be tangent to the right edge (for a clockwise path the right edge is inside the path).
| ![](img/tilepath-center. | png) | |
| left (outside) | center | right (inside) |
You can also chose whether you want the tile to be tiled without scaling (in which case you will probably be left with a fraction of the tile at one end), tiled with scaling (the tile will be scaled so that it fits on the path an integral number of times), or simply scaled (in which case there will be exactly one tile and it will be scaled to be as long as the path.
| ![](img/tilepath-ts. | png) | |
| tile | tile & scale | scale |
Tile Pattern
The Tile Pattern dialog allows you to design a pattern which will be tiled (both horizontally and vertically across the current layer.
You design the pattern in the edit pane of the dialog, and specify, the size of the tile using the width and height fields -- note that the size may be larger than the pattern's bounding box if you want white space around the tile (the green lines show the bounds of the tile). You also specify how many times the pattern is to be repeated in the x and y directions.
The tiling will start at the origin. After the pattern has been tiled you may apply other transformations to distort it into a non-rectangular shape, or use the Element->Overlap->Intersect command to clip it to some contour. Thus you can simulate some of the capabilities of a true pattern tile as is available in a type3 font.


Our lab is hiring motivated Graduate students and postdoctoral Researchers. This page is regularly updated depending on the availability of research fund.
Our interest sits at the interface between computational materials science and the development of new materials for applications in energy storage and conversion. We are looking for industrious and inquisitive candidates that can bring novel and interdisciplinary momentum to the field of energy storage. We are committed to improving diversity in materials sciences. Applicants from diverse backgrounds are encouraged to apply.
Please contact Prof Canepa for info.
Potential postdoctoral candidates will guide together with experimental collaborators the prediction of novel materials’ compositions of electrodes and electrolytes for batteries applications. Ideal candidates should master:
Interested candidates should directly submit their curriculum vitae to Prof. Canepa. Candidates must hold a PhD in materials science, chemistry and chemical engineering, physics or related field by the commencement of employment. Our group is truly multicultural and there are no citizenship restrictions. Successful candidate will be able to negotiate their salary based on their experience.
We are also happy to support the development of candidates that are targeting indipendent research proposals for PostDoctoral opportunities. Singapore research provides serveral funding opportunities, including:
Or in collaboration with A*Star scientists.
Graduate students from the MSE at the National University of Singapore can Prof Canepa inquiries to join the group. Interested, international students should Prof Canepa in advance and follow the admission to the Faculty of Engineering following this link.
Potential graduate applicants are not required prior knowledge in computational materials science. However, we require some interest in computational science, physics and chemistry. PhD research projects split between theoretical and experimental research are also very welcomed.


Lord Of Illusions A review by Joe Chamberlain
Starring Scott Bakula; Kevin J. O'Connor; Famke Janssen; Vincent Schiavelli & Barry Sherman
If you could say one thing about Lord Of Illusions, it would be that it is definitely different. Scott Bakula stars as a private eye that specializes in cases dealing with the paranormal, such as demonic possessions and the like. Dorothea (Famke Janssen), who is the wife of a magician, approaches Bakula's character, Harry D'Amour. She is worried about her husband's safety. Hubby was involved in an incident, years before, where he and several others tracked down and killed a cult leader who had kidnapped a little girl. This was no ordinary cult leader -- this guy had the power to control people's minds using the power of illusions. Well, all these years later the folks that helped to get rid of the cult leader are starting to die. Famke's character thinks the reason for the deaths is that the cult leader is coming back to get revenge for his death years earlier. She wants Bakula's character to get to the bottom of it, and provide some protection to boot. That's pretty much the story in a nutshell, and if it sounds strange, it's not just because I'm lousy at describing movies. The story really is a little on the strange side, although surprisingly easy to follow.
On the whole, the acting isn't bad in this film, but some performances are over the top to the extent that they end up being just plain terrible. That goes for pretty much all the villains in the movie. No, strike that. Bakula and Janssen are OK in the film, but everybody else is bad or borders on it. With that being said, it really doesn't hurt the film all that much. That is to say that you could have had Robert De Niro or Jack Nicholson in some of these parts and it wouldn't have made the film a whole lot better.
It really isn't a bad film all and all. Although, if you are someone who can't stand magic, and really can't swallow mind over matter plots, then you should definitely stay far away from this movie. The special effects in the illusion sequences aren't bad, but they look like something that you would see on television as opposed to a production intended for theaters. Confusion, bad acting, and a less than wonderful idea for a movie all contribute to making Lord Of Illusions just your average thoughtless horror film. The only saving grace is the fact that Bakula can actually act, and Famke Janssen is a major babe. (I'm sexist, so sue me.) But even Famke couldn't get me to sit though Lord Of Illusions for a second time. I've never understood why Clive Barker is held up with such great regard among horror fans. His writing and direction of this film leave me even more puzzled than before over his popularity.
5/10
Visit The Movie Guy http://movieguy.tripod.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


@JvmOverloads fun with(paymentApp: PaymentApp = PaymentApp.ALL): Builder
Sets default payment app for transaction.
paymentApp
- Sets default payment app from Enum of PaymentApp.
For e.g. To start payment with BHIM UPI then use PaymentApp.BHIM_UPI.
Return
this, for chaining.


Datasets
predicsis.jsSDK.models
| post /datasets | Datasets.create() | async |
| post /datasets | Datasets.split() | async |
| get /datasets | Datasets.all() | |
| get /datasets/:id | Datasets.get() | |
| getgetget | Datasets.getChildren() | |
| patch /datasets/:id | Datasets.update() | async |
| delete /datasets/:id | Datasets.delete() | |
| Tells if a dataset has subsets | Jobs.hasChildren() | |
| Tells if a dataset is a parent dataset | Jobs.isParent() | |
| Tells if a dataset is a child dataset | Jobs.isChild() | |
| Tells if a dataset is a train subset | Jobs.isTrainPart() | |
| Tells if a dataset is a test subset | Jobs.isTestPart() | |
| Tells if a dataset has both header and separator defined | Jobs.isFormatted() | |
| Tells if a dataset is the result of a score | Jobs.isScore() | |
| Official documentation is available at https://developer.predicsis.com/doc/v1/data_management/dataset/ |
A dataset may have various differents states:
{ id: 'learning_dataset', created_at: '2014-12-14T15:09:08.112Z', updated_at: '2014-12-14T15:08:57.970Z', name: 'Learning dataset', header: null, separator: null, user_id: '541b06dc617070006d060000', source_ids: ['54904b136170700007330000'], parent_dataset_id: null, sampling: 100, nb_of_lines: 50002, children_dataset_ids: [], dictionary_ids: [], generated_dictionaries_ids: [], data_file: '54904b09776f720001650000', main_modality: null, classifier_id: null, dataset_id: null, job_ids: ['54904b146170700007360000'], preview: [ '...\t...\t...', '...\t...\t...', '...\t...\t...', '...\t...\t...', '...\t...\t...' ] }
{ ... source_ids: [], parent_dataset_id: 'learning_dataset_with_model', sampling: 70, nb_of_lines: null, preview: null ... }
{ ... source_ids: [], parent_dataset_id: 'learning_dataset_with_model', sampling: -70, nb_of_lines: null, preview: null ... }
{ ... generated_dictionaries_ids: ['parent_dictionary'], children_dataset_ids: ['learned_learning_dataset', 'tested_learning_dataset'], job_ids: [ '54904bfe6170700007930000', '54904bf961707000078c0000', '54904b146170700007360000', '54904ce06170700007d10000' ] ... }
{ ... source_ids: ['54904da06170700007df0000'], generated_dictionaries_ids: [], children_dataset_ids: [], ... }
{ ... classifier_id: '5436431070632d15f4260000', dataset_id: 'scoring_dataset', modalities_set_id: '53fdfa7070632d0fc5030000', ... }
Please also note that there is no distinction between a learning dataset and a scoring dataset.
Create a dataset from a source
{ name: 'My awesome dataset', source_ids: ['original_source_id'], header: true, separator: '\t', data_file: { filename: 'source.csv' } }
Only name
and source_ids
are required.
{ name: 'My awesome dataset', classifier_id: $classifier_id$, dataset_id: $dataset_id$, modalities_set_id: $modalities_set_id$, main_modality: $main_modality$, separator: $separator$, header: $header$, data_file: { filename: $name$ } }
| Param | Type | Details |
|---|---|---|
| params | Object | See above description |
| Promise | New dataset or new scoreset |
Create API resources once an upload is successfully finished:
| Param | Type | Details |
|---|---|---|
| fileName | String | used to create the source and the dataset |
| destFolder | String | AWS key where the dataset has been uploaded |
| pathName | String | name of the key used to provide destFolder ('key' for S3, 'object' for swift) |
| Promise | Newly created dataset |
Get learning/testing subsets of an original dataset
/datasets
/datasets/:learned_dataset_id
/datasets/:tested_dataset_id
| Param | Type | Details |
|---|---|---|
| datasetId | String | parent Dataset identifier |
| dictionaryId | String | Identifier of the Dictionary |
| Promise |
|
Tells if a dataset is the result of a score. A score result is identified by the following rules:
dataset.source_ids.length === 0
dataset.main_modality !== null
dataset.classifier !== null
dataset.dataset_id !== null
| Param | Type | Details |
|---|---|---|
| dataset | Object | Instance of dataset |
| Boolean | true / false |
Tells if a dataset is a test subset. Note: A dataset is considered as a test subset if its sampling is negative and equal to the given sampling value.
| Param | Type | Details |
|---|---|---|
| dataset | Object | Instance of dataset |
| sampling | Number | You can give a positive or negative value for the sampling, we automatically compute a negative one. (If you give 70, we'll use -70, and if you give -70, we'll use -70) (default: 70) |
| Boolean | true / false |
Tells if a dataset is a train subset. Note: A dataset is considered as a train subset if its sampling is positive and equal to the given sampling value. A sampling must be between 0 and 100.
| Param | Type | Details |
|---|---|---|
| dataset | Object | Instance of dataset |
| sampling | Number | You can give a positive or negative value for the sampling, we automatically compute a positive one. (If you give 70, we'll use 70, and if you give -70, we'll use 70) (default: 70) |
| Boolean | true / false |
Split a dataset into subsets according to smapling
ratio.
Note:
learned_#datasetname#
tested#dataset_name#
According to @sferrandiz, the split()
function is deterministic one (if you ask to split a dataset
a lot of time, you will always get the same result). There is a insignificant risk of non-deterministic behaviour
based on the compilation of random generator (which can be different from one OS to an other)
| Param | Type | Details |
|---|---|---|
| id | String | Dataset id you want to split (called original dataset) |
| name | String | Name of the original dataset (used to name its subsets) |
| filename | String | Name of the original datafile (used to name its subsets's datafile). If undefined, value of name parameter is used (default: name) |
| sampling | Number | Examples: If you set
(default: 70) |
| Promise | Subsets |
Update specified dataset You can update the following parameters:
{String} name
{Boolean} header
{String} separator
If a separator
is updated, this function also escape this string because there is a paradox:
| Param | Type | Details |
|---|---|---|
| id | String | Id of the dictionary you want to update |
| changes | Object | see above description to know parameters you are able to update |
| Promise | Updated dataset |


ADMIN
Member Overview
Add Member
Check Member
Search Query
Search By
Name
School Number
Class
Search Results
1