diff --git a/.gitignore b/.gitignore index 3d5f1043..e9222c2d 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ MANIFEST !.gitignore !.travis.yml +!.isort.cfg diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..4d4a6a50 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,7 @@ +[settings] +skip=.tox +atomic=true +multi_line_output=5 +known_standard_library=types +known_third_party=pytest,django +known_first_party=rest_framework diff --git a/.travis.yml b/.travis.yml index 2134a144..67404d75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,11 @@ language: python sudo: false env: - - TOX_ENV=py27-flake8 + - TOX_ENV=py27-lint - TOX_ENV=py27-docs + - TOX_ENV=py35-django19 + - TOX_ENV=py34-django19 + - TOX_ENV=py27-django19 - TOX_ENV=py34-django18 - TOX_ENV=py33-django18 - TOX_ENV=py32-django18 @@ -13,33 +16,19 @@ env: - TOX_ENV=py33-django17 - TOX_ENV=py32-django17 - TOX_ENV=py27-django17 - - TOX_ENV=py34-django16 - - TOX_ENV=py33-django16 - - TOX_ENV=py32-django16 - - TOX_ENV=py27-django16 - - TOX_ENV=py26-django16 - - TOX_ENV=py34-django15 - - TOX_ENV=py33-django15 - - TOX_ENV=py32-django15 - - TOX_ENV=py27-django15 - - TOX_ENV=py26-django15 - - TOX_ENV=py27-django14 - - TOX_ENV=py26-django14 - - TOX_ENV=py27-djangomaster - - TOX_ENV=py32-djangomaster - - TOX_ENV=py33-djangomaster - - TOX_ENV=py34-djangomaster matrix: + # Python 3.5 not yet available on travis, watch this to see when it is. fast_finish: true allow_failures: - - env: TOX_ENV=py27-djangomaster - - env: TOX_ENV=py32-djangomaster - - env: TOX_ENV=py33-djangomaster - - env: TOX_ENV=py34-djangomaster + - env: TOX_ENV=py35-django19 install: - pip install tox script: - tox -e $TOX_ENV + +after_success: + - pip install codecov + - codecov -e TOX_ENV diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9626ebf..a383660e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ Some tips on good issue reporting: ## Triaging issues -Getting involved in triaging incoming issues is a good way to start contributing. Every single ticket that comes into the ticket tracker needs to be reviewed in order to determine what the next steps should be. Anyone can help out with this, you just need to be willing to +Getting involved in triaging incoming issues is a good way to start contributing. Every single ticket that comes into the ticket tracker needs to be reviewed in order to determine what the next steps should be. Anyone can help out with this, you just need to be willing to: * Read through the ticket - does it make sense, is it missing any context that would help explain it better? * Is the ticket reported in the correct place, would it be better suited as a discussion on the discussion group? diff --git a/README.md b/README.md index af8ac58e..b5b33212 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # [Django REST framework][docs] [![build-status-image]][travis] +[![coverage-status-image]][codecov] [![pypi-version]][pypi] **Awesome web-browsable Web APIs.** @@ -9,9 +10,9 @@ Full documentation for the project is available at [http://www.django-rest-frame --- -**Note**: We have now released Django REST framework 3.1. For older codebases you may want to refer to the version 2.4.4 [source code](https://github.com/tomchristie/django-rest-framework/tree/version-2.4.x), and [documentation](http://tomchristie.github.io/rest-framework-2-docs/). +**Note**: We have now released Django REST framework 3.3. For older codebases you may want to refer to the version 2.4.4 [source code][2.4-code], and [documentation][2.4-docs]. -For more details see the [3.1 release notes][3.1-announcement] +For more details see the 3.3 [announcement][3.3-announcement] and [release notes][3.3-release-notes]. --- @@ -35,8 +36,8 @@ There is a live example API for testing purposes, [available here][sandbox]. # Requirements -* Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7, 1.8) +* Python (2.7, 3.2, 3.3, 3.4, 3.5) +* Django (1.7, 1.8, 1.9) # Installation @@ -156,9 +157,10 @@ If you believe you’ve found something in Django REST framework which has secur Send a description of the issue via email to [rest-framework-security@googlegroups.com][security-mail]. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure. - [build-status-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.svg?branch=master [travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=master +[coverage-status-image]: https://img.shields.io/codecov/c/github/tomchristie/django-rest-framework/master.svg +[codecov]: http://codecov.io/github/tomchristie/django-rest-framework?branch=master [pypi-version]: https://img.shields.io/pypi/v/djangorestframework.svg [pypi]: https://pypi.python.org/pypi/djangorestframework [twitter]: https://twitter.com/_tomchristie @@ -179,4 +181,7 @@ Send a description of the issue via email to [rest-framework-security@googlegrou [docs]: http://www.django-rest-framework.org/ [security-mail]: mailto:rest-framework-security@googlegroups.com -[3.1-announcement]: http://www.django-rest-framework.org/topics/3.1-announcement/ +[2.4-code]: https://github.com/tomchristie/django-rest-framework/tree/version-2.4.x +[2.4-docs]: http://tomchristie.github.io/rest-framework-2-docs/ +[3.3-announcement]: http://www.django-rest-framework.org/topics/3.3-announcement/ +[3.3-release-notes]: http://www.django-rest-framework.org/topics/release-notes/#33x-series diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 2ccf7d72..3ade3a66 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -360,6 +360,14 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a [Django-rest-auth][django-rest-auth] library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management. +## django-rest-framework-social-oauth2 + +[Django-rest-framework-social-oauth2][django-rest-framework-social-oauth2] library provides an easy way to integrate social plugins (facebook, twitter, google, etc.) to your authentication system and an easy oauth2 setup. With this library, you will be able to authenticate users based on external tokens (e.g. facebook access token), convert these tokens to "in-house" oauth2 tokens and use and generate oauth2 tokens to authenticate your users. + +## django-rest-knox + +[Django-rest-knox][django-rest-knox] library provides models and views to handle token based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into). + [cite]: http://jacobian.org/writing/rest-worst-practices/ [http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 [http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4 @@ -400,3 +408,5 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a [mac]: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05 [djoser]: https://github.com/sunscrapers/djoser [django-rest-auth]: https://github.com/Tivix/django-rest-auth +[django-rest-framework-social-oauth2]: https://github.com/PhilipGarnero/django-rest-framework-social-oauth2 +[django-rest-knox]: https://github.com/James1345/django-rest-knox diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 18637f21..4118f6df 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -20,6 +20,8 @@ Each serializer field class constructor takes at least these arguments. Some Fi ### `read_only` +Read-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored. + Set this to `True` to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization. Defaults to `False` @@ -49,13 +51,13 @@ Defaults to `False` If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behavior is to not populate the attribute at all. -May be set to a function or other callable, in which case the value will be evaluated each time it is used. +May be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a `set_context` method, that will be called each time before getting the value with the field instance as only argument. This works the same way as for [validators](validators.md#using-set_context). Note that setting a `default` value implies that the field is not required. Including both the `default` and `required` keyword arguments is invalid and will raise an error. ### `source` -The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField('get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`. +The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField(source='get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`. The value `source='*'` has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation. @@ -83,9 +85,9 @@ A value that should be used for pre-populating the value of HTML form fields. ### `style` -A dictionary of key-value pairs that can be used to control how renderers should render the field. The API for this should still be considered experimental, and will be formalized with the 3.1 release. +A dictionary of key-value pairs that can be used to control how renderers should render the field. -Two options are currently used in HTML form generation, `'input_type'` and `'base_template'`. +Two examples here are `'input_type'` and `'base_template'`: # Use for the input. password = serializers.CharField( @@ -98,7 +100,7 @@ Two options are currently used in HTML form generation, `'input_type'` and `'bas style = {'base_template': 'radio.html'} } -**Note**: The `style` argument replaces the old-style version 2.x `widget` keyword argument. Because REST framework 3 now uses templated HTML form generation, the `widget` option that was used to support Django built-in widgets can no longer be supported. Version 3.1 is planned to include public API support for customizing HTML form generation. +For more details see the [HTML & Forms][html-and-forms] documentation. --- @@ -192,6 +194,20 @@ A field that ensures the input is a valid UUID string. The `to_internal_value` m - `'urn'` - RFC 4122 URN representation of the UUID: `"urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"` Changing the `format` parameters only affects representation values. All formats are accepted by `to_internal_value` +## FilePathField + +A field whose choices are limited to the filenames in a certain directory on the filesystem + +Corresponds to `django.forms.fields.FilePathField`. + +**Signature:** `FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)` + +- `path` - The absolute filesystem path to a directory from which this FilePathField should get its choice. +- `match` - A regular expression, as a string, that FilePathField will use to filter filenames. +- `recursive` - Specifies whether all subdirectories of path should be included. Default is `False`. +- `allow_files` - Specifies whether files in the specified location should be included. Default is `True`. Either this or `allow_folders` must be `True`. +- `allow_folders` - Specifies whether folders in the specified location should be included. Default is `False`. Either this or `allow_files` must be `True`. + ## IPAddressField A field that ensures the input is a valid IPv4 or IPv6 string. @@ -348,6 +364,8 @@ Used by `ModelSerializer` to automatically generate fields if the corresponding - `choices` - A list of valid values, or a list of `(key, display_name)` tuples. - `allow_blank` - If set to `True` then the empty string should be considered a valid value. If set to `False` then the empty string is considered invalid and will raise a validation error. Defaults to `False`. +- `html_cutoff` - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to `None`. +- `html_cutoff_text` - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to `"More than {count} items…"` Both the `allow_blank` and `allow_null` are valid options on `ChoiceField`, although it is highly recommended that you only use one and not both. `allow_blank` should be preferred for textual choices, and `allow_null` should be preferred for numeric or other non-textual choices. @@ -359,6 +377,8 @@ A field that can accept a set of zero, one or many values, chosen from a limited - `choices` - A list of valid values, or a list of `(key, display_name)` tuples. - `allow_blank` - If set to `True` then the empty string should be considered a valid value. If set to `False` then the empty string is considered invalid and will raise a validation error. Defaults to `False`. +- `html_cutoff` - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to `None`. +- `html_cutoff_text` - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to `"More than {count} items…"` As with `ChoiceField`, both the `allow_blank` and `allow_null` options are valid, although it is highly recommended that you only use one and not both. `allow_blank` should be preferred for textual choices, and `allow_null` should be preferred for numeric or other non-textual choices. @@ -439,6 +459,14 @@ You can also use the declarative style, as with `ListField`. For example: class DocumentField(DictField): child = CharField() +## JSONField + +A field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings. + +**Signature**: `JSONField(binary)` + +- `binary` - If set to `True` then the field will output and validate a JSON encoded string, rather than a primitive data structure. Defaults to `False`. + --- # Miscellaneous fields @@ -544,7 +572,7 @@ Let's look at an example of serializing a class that represents an RGB color val By default field values are treated as mapping to an attribute on the object. If you need to customize how the field value is accessed and set you need to override `.get_attribute()` and/or `.get_value()`. -As an example, let's create a field that can be used represent the class name of the object being serialized: +As an example, let's create a field that can be used to represent the class name of the object being serialized: class ClassNameField(serializers.Field): def get_attribute(self, obj): @@ -630,6 +658,7 @@ The [django-rest-framework-gis][django-rest-framework-gis] package provides geog The [django-rest-framework-hstore][django-rest-framework-hstore] package provides an `HStoreField` to support [django-hstore][django-hstore] `DictionaryField` model field. [cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data +[html-and-forms]: ../topics/html-and-forms.md [FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS [ecma262]: http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 [strftime]: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index cd017341..9e5f605f 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -83,6 +83,10 @@ We can override `.get_queryset()` to deal with URLs such as `http://example.com/ As well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex searches and filters. +Generic filters can also present themselves as HTML controls in the browsable API and admin API. + +![Filter Example](../img/filter-controls.png) + ## Setting filter backends The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKENDS` setting. For example. @@ -95,9 +99,9 @@ You can also set the filter backends on a per-view, or per-viewset basis, using the `GenericAPIView` class based views. from django.contrib.auth.models import User - from myapp.serializers import UserSerializer + from myapp.serializers import UserSerializer from rest_framework import filters - from rest_framework import generics + from rest_framework import generics class UserListView(generics.ListAPIView): queryset = User.objects.all() @@ -141,6 +145,13 @@ To use REST framework's `DjangoFilterBackend`, first install `django-filter`. pip install django-filter +If you are using the browsable API or admin API you may also want to install `django-crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML. + + pip install django-crispy-forms + +With crispy forms installed and added to Django's `INSTALLED_APPS`, the browsable API will present a filtering control for `DjangoFilterBackend`, like so: + +![Django Filter](../img/django-filter.png) #### Specifying filter fields @@ -149,6 +160,7 @@ If all you need is simple equality-based filtering, you can set a `filter_fields class ProductList(generics.ListAPIView): queryset = Product.objects.all() serializer_class = ProductSerializer + filter_backends = (filters.DjangoFilterBackend,) filter_fields = ('category', 'in_stock') This will automatically create a `FilterSet` class for the given fields, and will allow you to make requests such as: @@ -162,6 +174,7 @@ For more advanced filtering requirements you can specify a `FilterSet` class tha import django_filters from myapp.models import Product from myapp.serializers import ProductSerializer + from rest_framework import filters from rest_framework import generics class ProductFilter(django_filters.FilterSet): @@ -174,6 +187,7 @@ For more advanced filtering requirements you can specify a `FilterSet` class tha class ProductList(generics.ListAPIView): queryset = Product.objects.all() serializer_class = ProductSerializer + filter_backends = (filters.DjangoFilterBackend,) filter_class = ProductFilter @@ -234,6 +248,10 @@ For more details on using filter sets see the [django-filter documentation][djan The `SearchFilter` class supports simple single query parameter based searching, and is based on the [Django admin's search functionality][search-django-admin]. +When in use, the browsable API will include a `SearchFilter` control: + +![Search Filter](../img/search-filter.png) + The `SearchFilter` class will only be applied if the view has a `search_fields` attribute set. The `search_fields` attribute should be a list of names of text type fields on the model, such as `CharField` or `TextField`. class UserListView(generics.ListAPIView): @@ -257,6 +275,7 @@ The search behavior may be restricted by prepending various characters to the `s * '^' Starts-with search. * '=' Exact matches. * '@' Full-text search. (Currently only supported Django's MySQL backend.) +* '$' Regex search. For example: @@ -270,7 +289,11 @@ For more details, see the [Django documentation][search-django-admin]. ## OrderingFilter -The `OrderingFilter` class supports simple query parameter controlled ordering of results. By default, the query parameter is named `'ordering'`, but this may by overridden with the `ORDERING_PARAM` setting. +The `OrderingFilter` class supports simple query parameter controlled ordering of results. + +![Ordering Filter](../img/ordering-filter.png) + +By default, the query parameter is named `'ordering'`, but this may by overridden with the `ORDERING_PARAM` setting. For example, to order users by username: @@ -327,8 +350,6 @@ The `ordering` attribute may be either a string or a list/tuple of strings. The `DjangoObjectPermissionsFilter` is intended to be used together with the [`django-guardian`][guardian] package, with custom `'view'` permissions added. The filter will ensure that querysets only returns objects for which the user has the appropriate view permission. -This filter class must be used with views that provide either a `queryset` or a `model` attribute. - If you're using `DjangoObjectPermissionsFilter`, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass `DjangoObjectPermissions` and add `'view'` permissions to the `perms_map` attribute. A complete example using both `DjangoObjectPermissionsFilter` and `DjangoObjectPermissions` might look something like this. @@ -387,6 +408,14 @@ For example, you might need to restrict users to only being able to see objects We could achieve the same behavior by overriding `get_queryset()` on the views, but using a filter backend allows you to more easily add this restriction to multiple views, or to apply it across the entire API. +## Customizing the interface + +Generic filters may also present an interface in the browsable API. To do so you should implement a `to_html()` method which returns a rendered HTML representation of the filter. This method should have the following signature: + +`to_html(self, request, queryset, view)` + +The method should return a rendered HTML string. + # Third party packages The following third party packages provide additional filter implementations. @@ -399,6 +428,10 @@ The [django-rest-framework-filters package][django-rest-framework-filters] works The [djangorestframework-word-filter][django-rest-framework-word-search-filter] developed as alternative to `filters.SearchFilter` which will search full word in text, or exact match. +## Django URL Filter + +[django-url-filter][django-url-filter] provides a safe way to filter data via human-friendly URLs. It works very similar to DRF serializers and fields in a sense that they can be nested except they are called filtersets and filters. That provides easy way to filter related data. Also this library is generic-purpose so it can be used to filter other sources of data and not only Django `QuerySet`s. + [cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters [django-filter]: https://github.com/alex/django-filter [django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html @@ -409,3 +442,4 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter] [search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields [django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters [django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter +[django-url-filter]: https://github.com/miki725/django-url-filter diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md index 35dbcd39..13717b05 100644 --- a/docs/api-guide/format-suffixes.md +++ b/docs/api-guide/format-suffixes.md @@ -69,6 +69,16 @@ If using the `i18n_patterns` function provided by Django, as well as `format_suf --- +## Query parameter formats + +An alternative to the format suffixes is to include the requested format in a query parameter. REST framework provides this option by default, and it is used in the browsable API to switch between differing available representations. + +To select a representation using its short format, use the `format` query parameter. For example: `http://example.com/organizations/?format=csv`. + +The name of this query parameter can be modified using the `URL_FORMAT_OVERRIDE` setting. Set the value to `None` to disable this behavior. + +--- + ## Accept headers vs. format suffixes There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that `HTTP Accept` headers should always be used instead. diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index cb31f5f7..4a958121 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -35,14 +35,6 @@ For more complex cases you might also want to override various methods on the vi serializer_class = UserSerializer permission_classes = (IsAdminUser,) - def get_paginate_by(self): - """ - Use smaller pagination for HTML representations. - """ - if self.request.accepted_renderer.format == 'html': - return 20 - return 100 - def list(self, request): # Note the use of `get_queryset()` instead of `self.queryset` queryset = self.get_queryset() @@ -124,21 +116,24 @@ For example: Note that if your API doesn't include any object level permissions, you may optionally exclude the `self.check_object_permissions`, and simply return the object from the `get_object_or_404` lookup. -#### `get_filter_backends(self)` +#### `filter_queryset(self, queryset)` -Returns the classes that should be used to filter the queryset. Defaults to returning the `filter_backends` attribute. +Given a queryset, filter it with whichever filter backends are in use, returning a new queryset. -May be overridden to provide more complex behavior with filters, such as using different (or even exclusive) lists of filter_backends depending on different criteria. +For example: -For example: + def filter_queryset(self, queryset): + filter_backends = (CategoryFilter,) - def get_filter_backends(self): - if "geo_route" in self.request.query_params: - return (GeoRouteFilter, CategoryFilter) - elif "geo_point" in self.request.query_params: - return (GeoPointFilter, CategoryFilter) + if 'geo_route' in self.request.query_params: + filter_backends = (GeoRouteFilter, CategoryFilter) + elif 'geo_point' in self.request.query_params: + filter_backends = (GeoPointFilter, CategoryFilter) - return (CategoryFilter,) + for backend in list(filter_backends): + queryset = backend().filter_queryset(self.request, queryset, view=self) + + return queryset #### `get_serializer_class(self)` @@ -153,19 +148,6 @@ For example: return FullAccountSerializer return BasicAccountSerializer -#### `get_paginate_by(self)` - -Returns the page size to use with pagination. By default this uses the `paginate_by` attribute, and may be overridden by the client if the `paginate_by_param` attribute is set. - -You may want to override this method to provide more complex behavior, such as modifying page sizes based on the media type of the response. - -For example: - - def get_paginate_by(self): - if self.request.accepted_renderer.format == 'html': - return 20 - return 100 - **Save and deletion hooks**: The following methods are provided by the mixin classes, and provide easy overriding of the object save or deletion behavior. @@ -185,6 +167,14 @@ These override points are also particularly useful for adding behavior that occu instance = serializer.save() send_email_confirmation(user=self.request.user, modified=instance) +You can also use these hooks to provide additional validation, by raising a `ValidationError()`. This can be useful if you need some validation logic to apply at the point of database save. For example: + + def perform_create(self, serializer): + queryset = SignupRequest.objects.filter(user=self.request.user) + if queryset.exists(): + raise ValidationError('You have already signed up') + serializer.save(user=self.request.user) + **Note**: These methods replace the old-style version 2.x `pre_save`, `post_save`, `pre_delete` and `post_delete` methods, which are no longer available. **Other methods**: @@ -192,7 +182,7 @@ These override points are also particularly useful for adding behavior that occu You won't typically need to override the following methods, although you might need to call into them if you're writing custom views using `GenericAPIView`. * `get_serializer_context(self)` - Returns a dictionary containing any extra context that should be supplied to the serializer. Defaults to including `'request'`, `'view'` and `'format'` keys. -* `get_serializer(self, instance=None, data=None, files=None, many=False, partial=False, allow_add_remove=False)` - Returns a serializer instance. +* `get_serializer(self, instance=None, data=None, many=False, partial=False)` - Returns a serializer instance. * `get_paginated_response(self, data)` - Returns a paginated style `Response` object. * `paginate_queryset(self, queryset)` - Paginate a queryset if required, either returning a page object, or `None` if pagination is not configured for this view. * `filter_queryset(self, queryset)` - Given a queryset, filter it with whichever filter backends are in use, returning a new queryset. @@ -391,6 +381,10 @@ The following third party packages provide additional generic view implementatio The [django-rest-framework-bulk package][django-rest-framework-bulk] implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests. +## Django Rest Multiple Models + +[Django Rest Multiple Models][django-rest-multiple-models] provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request. + [cite]: https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views [GenericAPIView]: #genericapiview @@ -400,3 +394,4 @@ The [django-rest-framework-bulk package][django-rest-framework-bulk] implements [UpdateModelMixin]: #updatemodelmixin [DestroyModelMixin]: #destroymodelmixin [django-rest-framework-bulk]: https://github.com/miki725/django-rest-framework-bulk +[django-rest-multiple-models]: https://github.com/Axiologue/DjangoRestMultipleModels diff --git a/docs/api-guide/metadata.md b/docs/api-guide/metadata.md index 01727440..e12aeb7f 100644 --- a/docs/api-guide/metadata.md +++ b/docs/api-guide/metadata.md @@ -98,6 +98,12 @@ The following class could be used to limit the information that is returned to ` 'description': view.get_view_description() } +Then configure your settings to use this custom class: + + REST_FRAMEWORK = { + 'DEFAULT_METADATA_CLASS': 'myproject.apps.core.MinimalMetadata' + } + [cite]: http://tools.ietf.org/html/rfc7231#section-4.3.7 [no-options]: https://www.mnot.net/blog/2012/10/29/NO_OPTIONS [json-schema]: http://json-schema.org/ diff --git a/docs/api-guide/pagination.md b/docs/api-guide/pagination.md index 687e4dc4..da096bde 100644 --- a/docs/api-guide/pagination.md +++ b/docs/api-guide/pagination.md @@ -15,7 +15,9 @@ The pagination API can support either: The built-in styles currently all use links included as part of the content of the response. This style is more accessible when using the browsable API. -Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListMixin` and `generics.GenericAPIView` classes for an example. +Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListModelMixin` and `generics.GenericAPIView` classes for an example. + +Pagination can be turned off by setting the pagination class to `None`. ## Setting the pagination style @@ -95,6 +97,7 @@ The `PageNumberPagination` class includes a number of attributes that may be ove To set these attributes you should override the `PageNumberPagination` class, and then enable your custom pagination class as above. +* `django_paginator_class` - The Django Paginator class to use. Default is `django.core.paginator.Paginator`, which should be fine for most usecases. * `page_size` - A numeric value indicating the page size. If set, this overrides the `PAGE_SIZE` setting. Defaults to the same value as the `PAGE_SIZE` settings key. * `page_query_param` - A string value indicating the name of the query parameter to use for the pagination control. * `page_size_query_param` - If set, this is a string value indicating the name of a query parameter that allows the client to set the page size on a per-request basis. Defaults to `None`, indicating that the client may not control the requested page size. @@ -246,11 +249,11 @@ Let's modify the built-in `PageNumberPagination` style, so that instead of inclu previous_url = self.get_previous_link() if next_url is not None and previous_url is not None: - link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">' + link = '<{next_url}>; rel="next", <{previous_url}>; rel="prev"' elif next_url is not None: - link = '<{next_url}; rel="next">' + link = '<{next_url}>; rel="next"' elif previous_url is not None: - link = '<{previous_url}; rel="prev">' + link = '<{previous_url}>; rel="prev"' else: link = '' diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index c242f878..84fd6e5a 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -51,6 +51,9 @@ using the `APIView` class based views. return Response({'received data': request.data}) Or, if you're using the `@api_view` decorator with function based views. + + from rest_framework.decorators import api_view + from rest_framework.decorators import parser_classes @api_view(['POST']) @parser_classes((JSONParser,)) @@ -144,17 +147,16 @@ By default this will include the following keys: `view`, `request`, `args`, `kwa The following is an example plaintext parser that will populate the `request.data` property with a string representing the body of the request. class PlainTextParser(BaseParser): - """ - Plain text parser. - """ - - media_type = 'text/plain' - - def parse(self, stream, media_type=None, parser_context=None): """ - Simply return a string representing the body of the request. + Plain text parser. """ - return stream.read() + media_type = 'text/plain' + + def parse(self, stream, media_type=None, parser_context=None): + """ + Simply return a string representing the body of the request. + """ + return stream.read() --- diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index e86158fe..0f5947d6 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -74,8 +74,8 @@ You can also set the authentication policy on a per-view, or per-viewset basis, using the `APIView` class based views. from rest_framework.permissions import IsAuthenticated - from rest_framework.response import Response - from rest_framework.views import APIView + from rest_framework.response import Response + from rest_framework.views import APIView class ExampleView(APIView): permission_classes = (IsAuthenticated,) @@ -88,6 +88,10 @@ using the `APIView` class based views. Or, if you're using the `@api_view` decorator with function based views. + from rest_framework.decorators import api_view, permission_classes + from rest_framework.permissions import IsAuthenticated + from rest_framework.response import Response + @api_view('GET') @permission_classes((IsAuthenticated, )) def example_view(request, format=None): @@ -190,6 +194,16 @@ If you need to test if a request is a read operation or a write operation, you s --- +Custom permissions will raise a `PermissionDenied` exception if the test fails. To change the error message associated with the exception, implement a `message` attribute directly on your custom permission. Otherwise the `default_detail` attribute from `PermissionDenied` will be used. + + from rest_framework import permissions + + class CustomerAccessPermission(permissions.BasePermission): + message = 'Adding customers not allowed.' + + def has_permission(self, request, view): + ... + ## Examples The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted. @@ -241,6 +255,10 @@ The [Composed Permissions][composed-permissions] package provides a simple way t The [REST Condition][rest-condition] package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators. +## DRY Rest Permissions + +The [DRY Rest Permissions][dry-rest-permissions] package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user. + [cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html [authentication]: authentication.md [throttling]: throttling.md @@ -254,3 +272,4 @@ The [REST Condition][rest-condition] package is another extension for building c [drf-any-permissions]: https://github.com/kevin-brown/drf-any-permissions [composed-permissions]: https://github.com/niwibe/djangorestframework-composed-permissions [rest-condition]: https://github.com/caxap/rest_condition +[dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index 741943de..51e5f78c 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -16,7 +16,7 @@ Relational fields are used to represent model relationships. They can be applie --- -#### Inspecting automatically generated relationships. +#### Inspecting relationships. When using the `ModelSerializer` class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style. @@ -116,6 +116,8 @@ By default this field is read-write, although you can change this behavior using * `queryset` - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set `read_only=True`. * `many` - If applied to a to-many relationship, you should set this argument to `True`. * `allow_null` - If set to `True`, the field will accept values of `None` or the empty string for nullable relationships. Defaults to `False`. +* `pk_field` - Set to a field to control serialization/deserialization of the primary key's value. For example, `pk_field=UUIDField(format='hex')` would serialize a UUID primary key into its compact hex representation. + ## HyperlinkedRelatedField @@ -149,6 +151,16 @@ Would serialize to a representation like this: By default this field is read-write, although you can change this behavior using the `read_only` flag. +--- + +**Note**: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the `lookup_field` and `lookup_url_kwarg` arguments. + +This is suitable for URLs that contain a single primary key or slug argument as part of the URL. + +If you require more complex hyperlinked representation you'll need to customize the field, as described in the [custom hyperlinked fields](#custom-hyperlinked-fields) section, below. + +--- + **Arguments**: * `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `-detail`. **required**. @@ -243,7 +255,7 @@ For example, the following serializer: class TrackSerializer(serializers.ModelSerializer): class Meta: model = Track - fields = ('order', 'title') + fields = ('order', 'title', 'duration') class AlbumSerializer(serializers.ModelSerializer): tracks = TrackSerializer(many=True, read_only=True) @@ -254,17 +266,64 @@ For example, the following serializer: Would serialize to a nested representation like this: + >>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse') + >>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245) + + >>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264) + + >>> Track.objects.create(album=album, order=3, title='Encore', duration=159) + + >>> serializer = AlbumSerializer(instance=album) + >>> serializer.data { 'album_name': 'The Grey Album', 'artist': 'Danger Mouse', 'tracks': [ - {'order': 1, 'title': 'Public Service Announcement'}, - {'order': 2, 'title': 'What More Can I Say'}, - {'order': 3, 'title': 'Encore'}, + {'order': 1, 'title': 'Public Service Announcement', 'duration': 245}, + {'order': 2, 'title': 'What More Can I Say', 'duration': 264}, + {'order': 3, 'title': 'Encore', 'duration': 159}, ... ], } +# Writable nested serializers + +By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create `create()` and/or `update()` methods in order to explicitly specify how the child relationships should be saved. + + class TrackSerializer(serializers.ModelSerializer): + class Meta: + model = Track + fields = ('order', 'title', 'duration') + + class AlbumSerializer(serializers.ModelSerializer): + tracks = TrackSerializer(many=True) + + class Meta: + model = Album + fields = ('album_name', 'artist', 'tracks') + + def create(self, validated_data): + tracks_data = validated_data.pop('tracks') + album = Album.objects.create(**validated_data) + for track_data in tracks_data: + Track.objects.create(album=album, **track_data) + return album + + >>> data = { + 'album_name': 'The Grey Album', + 'artist': 'Danger Mouse', + 'tracks': [ + {'order': 1, 'title': 'Public Service Announcement', 'duration': 245}, + {'order': 2, 'title': 'What More Can I Say', 'duration': 264}, + {'order': 3, 'title': 'Encore', 'duration': 159}, + ], + } + >>> serializer = AlbumSerializer(data=data) + >>> serializer.is_valid() + True + >>> serializer.save() + + # Custom relational fields To implement a custom relational field, you should override `RelatedField`, and implement the `.to_representation(self, value)` method. This method takes the target of the field as the `value` argument, and should return the representation that should be used to serialize the target. The `value` argument will typically be a model instance. @@ -304,6 +363,65 @@ This custom field would then serialize to the following representation. --- +# Custom hyperlinked fields + +In some cases you may need to customize the behavior of a hyperlinked field, in order to represent URLs that require more than a single lookup field. + +You can achieve this by overriding `HyperlinkedRelatedField`. There are two methods that may be overridden: + +**get_url(self, obj, view_name, request, format)** + +The `get_url` method is used to map the object instance to its URL representation. + +May raise a `NoReverseMatch` if the `view_name` and `lookup_field` +attributes are not configured to correctly match the URL conf. + +**get_object(self, queryset, view_name, view_args, view_kwargs)** + +If you want to support a writable hyperlinked field then you'll also want to override `get_object`, in order to map incoming URLs back to the object they represent. For read-only hyperlinked fields there is no need to override this method. + +The return value of this method should the object that corresponds to the matched URL conf arguments. + +May raise an `ObjectDoesNotExist` exception. + +## Example + +Say we have a URL for a customer object that takes two keyword arguments, like so: + + /api//customers// + +This cannot be represented with the default implementation, which accepts only a single lookup field. + +In this case we'd need to override `HyperlinkedRelatedField` to get the behavior we want: + + from rest_framework import serializers + from rest_framework.reverse import reverse + + class CustomerHyperlink(serializers.HyperlinkedRelatedField): + # We define these as class attributes, so we don't need to pass them as arguments. + view_name = 'customer-detail' + queryset = Customer.objects.all() + + def get_url(self, obj, view_name, request, format): + url_kwargs = { + 'organization_slug': obj.organization.slug, + 'customer_pk': obj.pk + } + return reverse(view_name, kwargs=url_kwargs, request=request, format=format) + + def get_object(self, view_name, view_args, view_kwargs): + lookup_kwargs = { + 'organization__slug': view_kwargs['organization_slug'], + 'pk': view_kwargs['customer_pk'] + } + return self.get_queryset().get(**lookup_kwargs) + +Note that if you wanted to use this style together with the generic views then you'd also need to override `.get_object` on the view in order to get the correct lookup behavior. + +Generally we recommend a flat style for API representations where possible, but the nested URL style can also be reasonable when used in moderation. + +--- + # Further notes ## The `queryset` argument @@ -316,6 +434,35 @@ This behavior is now replaced with *always* using an explicit `queryset` argumen Doing so reduces the amount of hidden 'magic' that `ModelSerializer` provides, makes the behavior of the field more clear, and ensures that it is trivial to move between using the `ModelSerializer` shortcut, or using fully explicit `Serializer` classes. +## Customizing the HTML display + +The built-in `__str__` method of the model will be used to generate string representations of the objects used to populate the `choices` property. These choices are used to populate select HTML inputs in the browsable API. + +To provide customized representations for such inputs, override `display_value()` of a `RelatedField` subclass. This method will receive a model object, and should return a string suitable for representing it. For example: + + class TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): + def display_value(self, instance): + return 'Track: %s' % (instance.title) + +## Select field cutoffs + +When rendered in the browsable API relational fields will default to only displaying a maximum of 1000 selectable items. If more items are present then a disabled option with "More than 1000 items…" will be displayed. + +This behavior is intended to prevent a template from being unable to render in an acceptable timespan due to a very large number of relationships being displayed. + +There are two keyword arguments you can use to control this behavior: + +- `html_cutoff` - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Set to `None` to disable any limiting. Defaults to `1000`. +- `html_cutoff_text` - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to `"More than {count} items…"` + +In cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the `style` keyword argument. For example: + + assigned_to = serializers.SlugRelatedField( + queryset=User.objects.all(), + slug field='username', + style={'base_template': 'input.html'} + ) + ## Reverse relations Note that reverse relationships are not automatically included by the `ModelSerializer` and `HyperlinkedModelSerializer` classes. To include a reverse relationship, you must explicitly add it to the fields list. For example: @@ -356,7 +503,7 @@ For example, given the following model for a tag, which has a generic relationsh tagged_object = GenericForeignKey('content_type', 'object_id') def __unicode__(self): - return self.tag + return self.tag_name And the following two models, which may be have associated tags: @@ -421,39 +568,6 @@ If you explicitly specify a relational field pointing to a ``ManyToManyField`` with a through model, be sure to set ``read_only`` to ``True``. -## Advanced Hyperlinked fields - -If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`. - -There are two methods you'll need to override. - -#### get_url(self, obj, view_name, request, format) - -This method should return the URL that corresponds to the given object. - -May raise a `NoReverseMatch` if the `view_name` and `lookup_field` -attributes are not configured to correctly match the URL conf. - -#### get_object(self, queryset, view_name, view_args, view_kwargs) - -This method should the object that corresponds to the matched URL conf arguments. - -May raise an `ObjectDoesNotExist` exception. - -### Example - -For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this: - - class CustomHyperlinkedField(serializers.HyperlinkedRelatedField): - def get_url(self, obj, view_name, request, format): - kwargs = {'account': obj.account, 'slug': obj.slug} - return reverse(view_name, kwargs=kwargs, request=request, format=format) - - def get_object(self, queryset, view_name, view_args, view_kwargs): - account = view_kwargs['account'] - slug = view_kwargs['slug'] - return queryset.get(account=account, slug=slug) - --- # Third Party Packages diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 744b4064..b495fd09 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -153,23 +153,13 @@ You can use `StaticHTMLRenderer` either to return regular HTML pages using REST See also: `TemplateHTMLRenderer` -## HTMLFormRenderer - -Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `
` tags or an submit actions, as you'll probably need those to include the desired method and URL. Also note that the `HTMLFormRenderer` does not yet support including field error messages. - -Note that the template used by the `HTMLFormRenderer` class, and the context submitted to it **may be subject to change**. If you need to use this renderer class it is advised that you either make a local copy of the class and templates, or follow the release note on REST framework upgrades closely. - -**.media_type**: `text/html` - -**.format**: `'.form'` - -**.charset**: `utf-8` - -**.template**: `'rest_framework/form.html'` - ## BrowsableAPIRenderer -Renders data into HTML for the Browsable API. This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page. +Renders data into HTML for the Browsable API: + +![The BrowsableAPIRenderer](../img/quickstart.png) + +This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page. **.media_type**: `text/html` @@ -181,12 +171,63 @@ Renders data into HTML for the Browsable API. This renderer will determine whic #### Customizing BrowsableAPIRenderer -By default the response content will be rendered with the highest priority renderer apart from `BrowseableAPIRenderer`. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the `get_default_renderer()` method. For example: +By default the response content will be rendered with the highest priority renderer apart from `BrowsableAPIRenderer`. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the `get_default_renderer()` method. For example: class CustomBrowsableAPIRenderer(BrowsableAPIRenderer): def get_default_renderer(self, view): return JSONRenderer() +## AdminRenderer + +Renders data into HTML for an admin-like display: + +![The AdminRender view](../img/admin.png) + +This renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data. + +Note that views that have nested or list serializers for their input won't work well with the `AdminRenderer`, as the HTML forms are unable to properly support them. + +**Note**: The `AdminRenderer` is only able to include links to detail pages when a properly configured `URL_FIELD_NAME` (`url` by default) attribute is present in the data. For `HyperlinkedModelSerializer` this will be the case, but for `ModelSerializer` or plain `Serializer` classes you'll need to make sure to include the field explicitly. For example here we use models `get_absolute_url` method: + + class AccountSerializer(serializers.ModelSerializer): + url = serializers.CharField(source='get_absolute_url', read_only=True) + + class Meta: + model = Account + + +**.media_type**: `text/html` + +**.format**: `'.admin'` + +**.charset**: `utf-8` + +**.template**: `'rest_framework/admin.html'` + +## HTMLFormRenderer + +Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `` tags, a hidden CSRF input or any submit buttons. + +This renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the `render_form` template tag. + + {% load rest_framework %} + + + {% csrf_token %} + {% render_form serializer %} + +
+ +For more information see the [HTML & Forms][html-and-forms] documentation. + +**.media_type**: `text/html` + +**.format**: `'.form'` + +**.charset**: `utf-8` + +**.template**: `'rest_framework/horizontal/form.html'` + ## MultiPartRenderer This renderer is used for rendering HTML multipart form data. **It is not suitable as a response renderer**, but is instead used for creating test requests, using REST framework's [test client and test request factory][testing]. @@ -433,6 +474,7 @@ Comma-separated values are a plain-text tabular data format, that can be easily [cite]: https://docs.djangoproject.com/en/dev/ref/template-response/#the-rendering-process [conneg]: content-negotiation.md +[html-and-forms]: ../topics/html-and-forms.md [browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers [testing]: testing.md [HATEOAS]: http://timelessrepo.com/haters-gonna-hateoas diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md index 658a5ffd..94cdb14f 100644 --- a/docs/api-guide/requests.md +++ b/docs/api-guide/requests.md @@ -30,14 +30,6 @@ For more details see the [parsers documentation]. For clarity inside your code, we recommend using `request.query_params` instead of the Django's standard `request.GET`. Doing so will help keep your codebase more correct and obvious - any HTTP method type may include query parameters, not just `GET` requests. -## .DATA and .FILES - -The old-style version 2.x `request.DATA` and `request.FILES` attributes are still available, but are now pending deprecation in favor of the unified `request.data` attribute. - -## .QUERY_PARAMS - -The old-style version 2.x `request.QUERY_PARAMS` attribute is still available, but is now pending deprecation in favor of the more pythonic `request.query_params`. - ## .parsers The `APIView` class or `@api_view` decorator will ensure that this property is automatically set to a list of `Parser` instances, based on the `parser_classes` set on the view or based on the `DEFAULT_PARSER_CLASSES` setting. diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 2f13bd2a..78c2dd0d 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -189,6 +189,12 @@ Your `validate_` methods should return the validated value or raise raise serializers.ValidationError("Blog post is not about Django") return value +--- + +**Note:** If your `` is declared on your serializer with the parameter `required=False` then this validation step will not take place if the field is not included. + +--- + #### Object-level validation To do any other validation that requires access to multiple fields, add a method called `.validate()` to your `Serializer` subclass. This method takes a single argument, which is a dictionary of field values. It should raise a `ValidationError` if necessary, or just return the validated values. For example: @@ -281,7 +287,7 @@ Similarly if a nested representation should be a list of items, you should pass ## Writable nested representations -When dealing with nested representations that support deserializing the data, an errors with nested objects will be nested under the field name of the nested object. +When dealing with nested representations that support deserializing the data, any errors with nested objects will be nested under the field name of the nested object. serializer = CommentSerializer(data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'}) serializer.is_valid() @@ -350,7 +356,7 @@ It is possible that a third party package, providing automatic support some kind #### Handling saving related instances in model manager classes -An alternative to saving multiple related instances in the serializer is to write custom model manager classes handle creating the correct instances. +An alternative to saving multiple related instances in the serializer is to write custom model manager classes that handle creating the correct instances. For example, suppose we wanted to ensure that `User` instances and `Profile` instances are always created together as a pair. We might write a custom manager class that looks something like this: @@ -399,7 +405,7 @@ To serialize a queryset or list of objects instead of a single object instance, #### Deserializing multiple objects -The default behavior for deserializing multiple objects is to support multiple object creation, but not support multiple object updates. For more information on how to support or customize either of these cases, see the [ListSerializer](#ListSerializer) documentation below. +The default behavior for deserializing multiple objects is to support multiple object creation, but not support multiple object updates. For more information on how to support or customize either of these cases, see the [ListSerializer](#listserializer) documentation below. ## Including extra context @@ -432,6 +438,7 @@ Declaring a `ModelSerializer` looks like this: class AccountSerializer(serializers.ModelSerializer): class Meta: model = Account + fields = ('id', 'account_name', 'users', 'created') By default, all the model fields on the class will be mapped to a corresponding serializer fields. @@ -453,7 +460,7 @@ To do so, open the Django shell, using `python manage.py shell`, then import the ## Specifying which fields to include -If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`. +If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`. It is strongly recommended that you explicitly set all fields that should be serialized using the `fields` attribute. This will make it less likely to result in unintentionally exposing data when your models change. For example: @@ -462,7 +469,27 @@ For example: model = Account fields = ('id', 'account_name', 'users', 'created') -The names in the `fields` option will normally map to model fields on the model class. +You can also set the `fields` attribute to the special value `'__all__'` to indicate that all fields in the model should be used. + +For example: + + class AccountSerializer(serializers.ModelSerializer): + class Meta: + model = Account + fields = '__all__' + +You can set the `exclude` attribute to a list of fields to be excluded from the serializer. + +For example: + + class AccountSerializer(serializers.ModelSerializer): + class Meta: + model = Account + exclude = ('users',) + +In the example above, if the `Account` model had 3 fields `account_name`, `users`, and `created`, this will result in the fields `account_name` and `created` to be serialized. + +The names in the `fields` and `exclude` attributes will normally map to model fields on the model class. Alternatively names in the `fields` options can map to properties or methods which take no arguments that exist on the model class. @@ -524,7 +551,7 @@ Please review the [Validators Documentation](/api-guide/validators/) for details ## Additional keyword arguments -There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. Similarly to `read_only_fields` this means you do not need to explicitly declare the field on the serializer. +There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. As in the case of `read_only_fields`, this means you do not need to explicitly declare the field on the serializer. This option is a dictionary, mapping field names to a dictionary of keyword arguments. For example: @@ -565,7 +592,7 @@ Typically we would recommend *not* using inheritance on inner Meta classes, but The ModelSerializer class also exposes an API that you can override in order to alter how serializer fields are automatically determined when instantiating the serializer. -Normally if a `ModelSerializer` does not generate the fields you need by default the you should either add them to the class explicitly, or simply use a regular `Serializer` class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model. +Normally if a `ModelSerializer` does not generate the fields you need by default then you should either add them to the class explicitly, or simply use a regular `Serializer` class instead. However in some cases you may want to create a new base class that defines how the serializer fields are created for any given model. ### `.serializer_field_mapping` @@ -773,6 +800,10 @@ Here's an example of how you might choose to implement multiple updates: return ret class BookSerializer(serializers.Serializer): + # We need to identify elements in the list using their primary key, + # so use a writable field here, rather than the default which would be read-only. + id = serializers.IntegerField() + ... class Meta: list_serializer_class = BookListSerializer @@ -805,7 +836,7 @@ This class implements the same basic API as the `Serializer` class: * `.data` - Returns the outgoing primitive representation. * `.is_valid()` - Deserializes and validates incoming data. * `.validated_data` - Returns the validated incoming data. -* `.errors` - Returns an errors during validation. +* `.errors` - Returns any errors during validation. * `.save()` - Persists the validated data into an object instance. There are four methods that can be overridden, depending on what functionality you want the serializer class to support: @@ -1022,6 +1053,13 @@ A new interface for controlling this behavior is currently planned for REST fram The following third party packages are also available. +## Django REST marshmallow + +The [django-rest-marshmallow][django-rest-marshmallow] package provides an alternative implementation for serializers, using the python [marshmallow][marshmallow] library. It exposes the same API as the REST framework serializers, and can be used as a drop-in replacement in some use-cases. + +## Serpy +The [serpy][serpy] package is an alternative implementation for serializers that is built for speed. [Serpy][serpy] serializes complex datatypes to simple native types. The native types can be easily converted to JSON or any other format needed. + ## MongoengineModelSerializer The [django-rest-framework-mongoengine][mongoengine] package provides a `MongoEngineModelSerializer` serializer class that supports using MongoDB as the storage layer for Django REST framework. @@ -1038,6 +1076,9 @@ The [django-rest-framework-hstore][django-rest-framework-hstore] package provide [relations]: relations.md [model-managers]: https://docs.djangoproject.com/en/dev/topics/db/managers/ [encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/ +[django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/ +[marshmallow]: https://marshmallow.readthedocs.org/en/latest/ +[serpy]: https://github.com/clarkduvall/serpy [mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine [django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis [django-rest-framework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 5af429d1..23691dec 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -119,6 +119,14 @@ Default: `None` #### PAGINATE_BY_PARAM +--- + +**This setting is pending deprecation.** + +See the pagination documentation for further guidance on [setting the pagination style](pagination.md#modifying-the-pagination-style). + +--- + The name of a query parameter, which can be used by the client to override the default page size to use for pagination. If set to `None`, clients may not override the default page size. For example, given the following settings: @@ -136,6 +144,14 @@ Default: `None` #### MAX_PAGINATE_BY +--- + +**This setting is pending deprecation.** + +See the pagination documentation for further guidance on [setting the pagination style](pagination.md#modifying-the-pagination-style). + +--- + The maximum page size to allow when the page size is specified by the client. If set to `None`, then no maximum limit is applied. For example, given the following settings: @@ -233,45 +249,23 @@ Default: --- -## Browser overrides - -*The following settings provide URL or form-based overrides of the default browser behavior.* - -#### FORM_METHOD_OVERRIDE - -The name of a form field that may be used to override the HTTP method of the form. - -If the value of this setting is `None` then form method overloading will be disabled. - -Default: `'_method'` - -#### FORM_CONTENT_OVERRIDE - -The name of a form field that may be used to override the content of the form payload. Must be used together with `FORM_CONTENTTYPE_OVERRIDE`. - -If either setting is `None` then form content overloading will be disabled. - -Default: `'_content'` - -#### FORM_CONTENTTYPE_OVERRIDE - -The name of a form field that may be used to override the content type of the form payload. Must be used together with `FORM_CONTENT_OVERRIDE`. - -If either setting is `None` then form content overloading will be disabled. - -Default: `'_content_type'` - -#### URL_ACCEPT_OVERRIDE - -The name of a URL parameter that may be used to override the HTTP `Accept` header. - -If the value of this setting is `None` then URL accept overloading will be disabled. - -Default: `'accept'` +## Content type controls #### URL_FORMAT_OVERRIDE -The name of a URL parameter that may be used to override the default `Accept` header based content negotiation. +The name of a URL parameter that may be used to override the default content negotiation `Accept` header behavior, by using a `format=…` query parameter in the request URL. + +For example: `http://example.com/organizations/?format=csv` + +If the value of this setting is `None` then URL format overrides will be disabled. + +Default: `'format'` + +#### FORMAT_SUFFIX_KWARG + +The name of a parameter in the URL conf that may be used to provide a format suffix. This setting is applied when using `format_suffix_patterns` to include suffixed URL patterns. + +For example: `http://example.com/organizations.csv/` Default: `'format'` @@ -433,12 +427,6 @@ A string representing the key that should be used for the URL fields generated b Default: `'url'` -#### FORMAT_SUFFIX_KWARG - -The name of a parameter in the URL conf that may be used to provide a format suffix. - -Default: `'format'` - #### NUM_PROXIES An integer of 0 or more, that may be used to specify the number of application proxies that the API runs behind. This allows throttling to more accurately identify client IP addresses. If set to `None` then less strict IP matching will be used by the throttle classes. diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index dd3295c4..69da7d10 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -200,6 +200,7 @@ You can use any of REST framework's test case classes as you would for the regul from django.core.urlresolvers import reverse from rest_framework import status from rest_framework.test import APITestCase + from myproject.apps.core.models import Account class AccountTests(APITestCase): def test_create_account(self): @@ -210,7 +211,8 @@ You can use any of REST framework's test case classes as you would for the regul data = {'name': 'DabApps'} response = self.client.post(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(response.data, data) + self.assertEqual(Account.objects.count(), 1) + self.assertEqual(Account.objects.get().name, 'DabApps') --- diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index 3f668867..36753aaf 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -148,7 +148,7 @@ For example, given the following views... throttle_scope = 'contacts' ... - class ContactDetailView(ApiView): + class ContactDetailView(APIView): throttle_scope = 'contacts' ... @@ -184,7 +184,7 @@ If the `.wait()` method is implemented and the request is throttled, then a `Ret The following is an example of a rate throttle, that will randomly throttle 1 in every 10 requests. - class RandomRateThrottle(throttles.BaseThrottle): + class RandomRateThrottle(throttling.BaseThrottle): def allow_request(self, request, view): return random.randint(1, 10) == 1 diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md index 69408c4a..e54ebfc3 100644 --- a/docs/api-guide/validators.md +++ b/docs/api-guide/validators.md @@ -204,7 +204,7 @@ A validator may be any callable that raises a `serializers.ValidationError` on f To write a class based validator, use the `__call__` method. Class based validators are useful as they allow you to parameterize and reuse behavior. - class MultipleOf: + class MultipleOf(object): def __init__(self, base): self.base = base diff --git a/docs/api-guide/versioning.md b/docs/api-guide/versioning.md index 846698fc..f6e32f47 100644 --- a/docs/api-guide/versioning.md +++ b/docs/api-guide/versioning.md @@ -3,7 +3,7 @@ source: versioning.py # Versioning > Versioning an interface is just a "polite" way to kill deployed clients. -> +> > — [Roy Fielding][cite]. API versioning allows you to alter behavior between different clients. REST framework provides for a number of different versioning schemes. @@ -71,8 +71,21 @@ You can also set the versioning scheme on an individual view. Typically you won' The following settings keys are also used to control versioning: * `DEFAULT_VERSION`. The value that should be used for `request.version` when no versioning information is present. Defaults to `None`. -* `ALLOWED_VERSIONS`. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version if not in this set. Defaults to `None`. -* `VERSION_PARAMETER`. The string that should used for any versioning parameters, such as in the media type or URL query parameters. Defaults to `'version'`. +* `ALLOWED_VERSIONS`. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version if not in this set. Note that the value used for the `DEFAULT_VERSION` setting is always considered to be part of the `ALLOWED_VERSIONS` set. Defaults to `None`. +* `VERSION_PARAM`. The string that should used for any versioning parameters, such as in the media type or URL query parameters. Defaults to `'version'`. + +You can also set your versioning class plus those three values on a per-view or a per-viewset basis by defining your own versioning scheme and using the `default_version`, `allowed_versions` and `version_param` class variables. For example, if you want to use `URLPathVersioning`: + + from rest_framework.versioning import URLPathVersioning + from rest_framework.views import APIView + + class ExampleVersioning(URLPathVersioning): + default_version = ... + allowed_versions = ... + version_param = ... + + class ExampleView(APIVIew): + versioning_class = ExampleVersioning --- @@ -117,12 +130,12 @@ Your URL conf must include a pattern that matches the version with a `'version'` urlpatterns = [ url( - r'^(?P{v1,v2})/bookings/$', + r'^(?P(v1|v2))/bookings/$', bookings_list, name='bookings-list' ), url( - r'^(?P{v1,v2})/bookings/(?P[0-9]+)/$', + r'^(?P(v1|v2))/bookings/(?P[0-9]+)/$', bookings_detail, name='bookings-detail' ) diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 0ada0eb5..0452a0f7 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -27,7 +27,7 @@ Let's define a simple viewset that can be used to list or retrieve all the users class UserViewSet(viewsets.ViewSet): """ - A simple ViewSet that for listing or retrieving users. + A simple ViewSet for listing or retrieving users. """ def list(self, request): queryset = User.objects.all() diff --git a/docs/img/admin.png b/docs/img/admin.png new file mode 100644 index 00000000..f12df099 Binary files /dev/null and b/docs/img/admin.png differ diff --git a/docs/img/django-filter.png b/docs/img/django-filter.png new file mode 100644 index 00000000..5baef32f Binary files /dev/null and b/docs/img/django-filter.png differ diff --git a/docs/img/filter-controls.png b/docs/img/filter-controls.png new file mode 100644 index 00000000..4a41cf04 Binary files /dev/null and b/docs/img/filter-controls.png differ diff --git a/docs/img/horizontal.png b/docs/img/horizontal.png new file mode 100644 index 00000000..3852070a Binary files /dev/null and b/docs/img/horizontal.png differ diff --git a/docs/img/inline.png b/docs/img/inline.png new file mode 100644 index 00000000..a910de19 Binary files /dev/null and b/docs/img/inline.png differ diff --git a/docs/img/ordering-filter.png b/docs/img/ordering-filter.png new file mode 100644 index 00000000..25bc4ec7 Binary files /dev/null and b/docs/img/ordering-filter.png differ diff --git a/docs/img/search-filter.png b/docs/img/search-filter.png new file mode 100644 index 00000000..d36f2b96 Binary files /dev/null and b/docs/img/search-filter.png differ diff --git a/docs/img/vertical.png b/docs/img/vertical.png new file mode 100644 index 00000000..a85e5c6c Binary files /dev/null and b/docs/img/vertical.png differ diff --git a/docs/index.md b/docs/index.md index a8da1946..622e35ab 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,18 @@

- + - - + + + - + + +

--- -**Note**: This is the documentation for the **version 3.1** of REST framework. Documentation for [version 2.4](http://tomchristie.github.io/rest-framework-2-docs/) is also available. - -For more details see the [3.1 release notes][3.1-announcement]. +**Note**: This is the documentation for the **version 3** of REST framework. Documentation for [version 2](http://tomchristie.github.io/rest-framework-2-docs/) is also available. --- @@ -28,7 +29,7 @@ For more details see the [3.1 release notes][3.1-announcement]. Django REST Framework

-Django REST framework is a powerful and flexible toolkit that makes it easy to build Web APIs. +Django REST framework is a powerful and flexible toolkit for building Web APIs. Some reasons you might want to use REST framework: @@ -49,13 +50,14 @@ Some reasons you might want to use REST framework: REST framework requires the following: -* Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7+, 1.8) +* Python (2.7, 3.2, 3.3, 3.4, 3.5) +* Django (1.7+, 1.8, 1.9) The following packages are optional: * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API. * [django-filter][django-filter] (0.9.2+) - Filtering support. +* [django-crispy-forms][django-crispy-forms] - Improved HTML display for filtering. * [django-guardian][django-guardian] (1.1.1+) - Object level permissions support. ## Installation @@ -84,7 +86,7 @@ If you're intending to use the browsable API you'll probably also want to add RE url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) ] -Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace. +Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace. You may leave out the namespace in Django 1.9+, and REST framework will set it for you. ## Example @@ -188,7 +190,9 @@ The API guide is your complete reference manual to all the functionality provide General guides to using REST framework. * [Documenting your API][documenting-your-api] +* [Internationalization][internationalization] * [AJAX, CSRF & CORS][ajax-csrf-cors] +* [HTML & Forms][html-and-forms] * [Browser enhancements][browser-enhancements] * [The Browsable API][browsableapi] * [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas] @@ -197,6 +201,8 @@ General guides to using REST framework. * [Project management][project-management] * [3.0 Announcement][3.0-announcement] * [3.1 Announcement][3.1-announcement] +* [3.2 Announcement][3.2-announcement] +* [3.3 Announcement][3.3-announcement] * [Kickstarter Announcement][kickstarter-announcement] * [Release Notes][release-notes] @@ -248,12 +254,11 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -[travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=master -[travis-build-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.png?branch=master [mozilla]: http://www.mozilla.org/en-US/about/ [eventbrite]: https://www.eventbrite.co.uk/about/ [markdown]: http://pypi.python.org/pypi/Markdown/ [django-filter]: http://pypi.python.org/pypi/django-filter +[django-crispy-forms]: https://github.com/maraujop/django-crispy-forms [django-guardian]: https://github.com/lukaszb/django-guardian [0.4]: https://github.com/tomchristie/django-rest-framework/tree/0.4.X [image]: img/quickstart.png @@ -301,8 +306,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [settings]: api-guide/settings.md [documenting-your-api]: topics/documenting-your-api.md -[internationalization]: topics/documenting-your-api.md +[internationalization]: topics/internationalization.md [ajax-csrf-cors]: topics/ajax-csrf-cors.md +[html-and-forms]: topics/html-and-forms.md [browser-enhancements]: topics/browser-enhancements.md [browsableapi]: topics/browsable-api.md [rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md @@ -311,7 +317,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [third-party-resources]: topics/third-party-resources.md [3.0-announcement]: topics/3.0-announcement.md [3.1-announcement]: topics/3.1-announcement.md +[3.2-announcement]: topics/3.2-announcement.md +[3.3-announcement]: topics/3.3-announcement.md [kickstarter-announcement]: topics/kickstarter-announcement.md +[funding]: topics/funding.md [release-notes]: topics/release-notes.md [tox]: http://testrun.org/tox/latest/ diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 59fe779c..89f9e800 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -940,7 +940,7 @@ The default JSON renderer will return float objects for un-coerced `Decimal` ins * The serializer `ChoiceField` does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1. * Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand. * Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still [create language files with Django][django-localization] if you wish to localize them. -* `APIException` subclasses could previously take could previously take any arbitrary type in the `detail` argument. These exceptions now use translatable text strings, and as a result call `force_text` on the `detail` argument, which *must be a string*. If you need complex arguments to an `APIException` class, you should subclass it and override the `__init__()` method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses. +* `APIException` subclasses could previously take any arbitrary type in the `detail` argument. These exceptions now use translatable text strings, and as a result call `force_text` on the `detail` argument, which *must be a string*. If you need complex arguments to an `APIException` class, you should subclass it and override the `__init__()` method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses. --- diff --git a/docs/topics/3.2-announcement.md b/docs/topics/3.2-announcement.md new file mode 100644 index 00000000..f0cc09a4 --- /dev/null +++ b/docs/topics/3.2-announcement.md @@ -0,0 +1,113 @@ +# Django REST framework 3.2 + +The 3.2 release is the first version to include an admin interface for the browsable API. + +![The AdminRenderer](../img/admin.png) + +This interface is intended to act as a more user-friendly interface to the API. It can be used either as a replacement to the existing `BrowsableAPIRenderer`, or used together with it, allowing you to switch between the two styles as required. + +We've also fixed a huge number of issues, and made numerous cleanups and improvements. + +Over the course of the 3.1.x series we've [resolved nearly 600 tickets](https://github.com/tomchristie/django-rest-framework/issues?utf8=%E2%9C%93&q=closed%3A%3E2015-03-05) on our GitHub issue tracker. This means we're currently running at a rate of **closing around 100 issues or pull requests per month**. + +None of this would have been possible without the support of our wonderful Kickstarter backers. If you're looking for a job in Django development we'd strongly recommend taking [a look through our sponsors](http://www.django-rest-framework.org/topics/kickstarter-announcement/#sponsors) and finding out who's hiring. + +## AdminRenderer + +To include `AdminRenderer` simply add it to your settings: + + REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': [ + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.AdminRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer' + ], + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'PAGE_SIZE': 100 + } + +There are some limitations to the `AdminRenderer`, in particular it is not yet able to handle list or dictionary inputs, as we do not have any HTML form fields that support those. + +Also note that this is an initial release and we do not yet have a public API for modifying the behavior or documentation on overriding the templates. + +The idea is to get this released to users early, so we can start getting feedback and release a more fully featured version in 3.3. + +## Supported versions + +This release drops support for Django 1.4. + +Our supported Django versions are now 1.5.6+, 1.6.3+, 1.7 and 1.8. + +## Deprecations + +There are no new deprecations in 3.2, although a number of existing deprecations have now escalated in line with our deprecation policy. + +* `request.DATA` was put on the deprecation path in 3.0. It has now been removed and its usage will result in an error. Use the more pythonic style of `request.data` instead. +* `request.QUERY_PARAMS` was put on the deprecation path in 3.0. It has now been removed and its usage will result in an error. Use the more pythonic style of `request.query_params` instead. +* The following `ModelSerializer.Meta` options have now been removed: `write_only_fields`, `view_name`, `lookup_field`. Use the more general `extra_kwargs` option instead. + +The following pagination view attributes and settings have been moved into attributes on the pagination class since 3.1. Their usage was formerly in 'pending deprecation', and has now escalated to 'deprecated'. They will continue to function but will raise errors. + +* `view.paginate_by` - Use `paginator.page_size` instead. +* `view.page_query_param` - Use `paginator.page_query_param` instead. +* `view.paginate_by_param` - Use `paginator.page_size_query_param` instead. +* `view.max_paginate_by` - Use `paginator.max_page_size` instead. +* `settings.PAGINATE_BY` - Use `paginator.page_size` instead. +* `settings.PAGINATE_BY_PARAM` - Use `paginator.page_size_query_param` instead. +* `settings.MAX_PAGINATE_BY` - Use `max_page_size` instead. + +## Modifications to list behaviors + +There are a couple of bug fixes that are worth calling out as they introduce differing behavior. + +These are a little subtle and probably won't affect most users, but are worth understanding before upgrading your project. + +### ManyToMany fields and blank=True + +We've now added an `allow_empty` argument, which can be used with `ListSerializer`, or with `many=True` relationships. This is `True` by default, but can be set to `False` if you want to disallow empty lists as valid input. + +As a follow-up to this we are now able to properly mirror the behavior of Django's `ModelForm` with respect to how many-to-many fields are validated. + +Previously a many-to-many field on a model would map to a serializer field that would allow either empty or non-empty list inputs. Now, a many-to-many field will map to a serializer field that requires at least one input, unless the model field has `blank=True` set. + +Here's what the mapping looks like in practice: + +* `models.ManyToManyField()` → `serializers.PrimaryKeyRelatedField(many=True, allow_empty=False)` +* `models.ManyToManyField(blank=True)` → `serializers.PrimaryKeyRelatedField(many=True)` + +The upshot is this: If you have many to many fields in your models, then make sure you've included the argument `blank=True` if you want to allow empty inputs in the equivalent `ModelSerializer` fields. + +### List fields and allow_null + +When using `allow_null` with `ListField` or a nested `many=True` serializer the previous behavior was to allow `null` values as items in the list. The behavior is now to allow `null` values instead of the list. + +For example, take the following field: + + NestedSerializer(many=True, allow_null=True) + +Previously the validation behavior would be: + +* `[{…}, null, {…}]` is **valid**. +* `null` is **invalid**. + +Our validation behavior as of 3.2.0 is now: + +* `[{…}, null, {…}]` is **invalid**. +* `null` is **valid**. + +If you want to allow `null` child items, you'll need to instead specify `allow_null` on the child class, using an explicit `ListField` instead of `many=True`. For example: + + ListField(child=NestedSerializer(allow_null=True)) + +## What's next? + +The 3.3 release is currently planned for the start of October, and will be the last Kickstarter-funded release. + +This release is planned to include: + +* Search and filtering controls in the browsable API and admin interface. +* Improvements and public API for the admin interface. +* Improvements and public API for our templated HTML forms and fields. +* Nested object and list support in HTML forms. + +Thanks once again to all our sponsors and supporters. \ No newline at end of file diff --git a/docs/topics/3.3-announcement.md b/docs/topics/3.3-announcement.md new file mode 100644 index 00000000..d1a8f4da --- /dev/null +++ b/docs/topics/3.3-announcement.md @@ -0,0 +1,58 @@ +# Django REST framework 3.3 + +The 3.3 release marks the final work in the Kickstarter funded series. We'd like to offer a final resounding **thank you** to all our wonderful sponsors and supporters. + +The amount of work that has been achieved as a direct result of the funding is immense. We've added a huge amounts of new functionality, resolved nearly 2,000 tickets, and redesigned & refined large parts of the project. + +In order to continue driving REST framework forward, we'll shortly be announcing a new set of funding plans. Follow [@_tomchristie](https://twitter.com/_tomchristie) to keep up to date with these announcements, and be among the first set of sign ups. + +We strongly believe that collaboratively funded software development yields outstanding results for a relatively low investment-per-head. If you or your company use REST framework commercially, then we would strongly urge you to participate in this latest funding drive, and help us continue to build an increasingly polished & professional product. + +--- + +## Release notes + +Significant new functionality in the 3.3 release includes: + +* Filters presented as HTML controls in the browsable API. +* A [forms API][forms-api], allowing serializers to be rendered as HTML forms. +* Django 1.9 support. +* A [`JSONField` serializer field][jsonfield], corresponding to Django 1.9's Postgres `JSONField` model field. +* Browsable API support [via AJAX][ajax-form], rather than server side request overloading. + +![Filter Controls](../img/filter-controls.png) + +*Example of the new filter controls* + +--- + +## Supported versions + +This release drops support for Django 1.5 and 1.6. Django 1.7, 1.8 or 1.9 are now required. + +This brings our supported versions into line with Django's [currently supported versions][django-supported-versions] + +## Deprecations + +The AJAX based support for the browsable API means that there are a number of internal cleanups in the `request` class. For the vast majority of developers this should largely remain transparent: + +* To support form based `PUT` and `DELETE`, or to support form content types such as JSON, you should now use the [AJAX forms][ajax-form] javascript library. This replaces the previous 'method and content type overloading' that required significant internal complexity to the request class. +* The `accept` query parameter is no longer supported by the default content negotiation class. If you require it then you'll need to [use a custom content negotiation class](browser-enhancements.md#url-based-accept-headers). +* The custom `HTTP_X_HTTP_METHOD_OVERRIDE` header is no longer supported by default. If you require it then you'll need to [use custom middleware](browser-enhancements.md#http-header-based-method-overriding). + +The following pagination view attributes and settings have been moved into attributes on the pagination class since 3.1. Their usage was formerly deprecated, and has now been removed entirely, in line with the deprecation policy. + +* `view.paginate_by` - Use `paginator.page_size` instead. +* `view.page_query_param` - Use `paginator.page_query_param` instead. +* `view.paginate_by_param` - Use `paginator.page_size_query_param` instead. +* `view.max_paginate_by` - Use `paginator.max_page_size` instead. +* `settings.PAGINATE_BY` - Use `paginator.page_size` instead. +* `settings.PAGINATE_BY_PARAM` - Use `paginator.page_size_query_param` instead. +* `settings.MAX_PAGINATE_BY` - Use `paginator.max_page_size` instead. + +The `ModelSerializer` and `HyperlinkedModelSerializer` classes should now include either a `fields` or `exclude` option, although the `fields = '__all__'` shortcut may be used. Failing to include either of these two options is currently pending deprecation, and will be removed entirely in the 3.5 release. This behavior brings `ModelSerializer` more closely in line with Django's `ModelForm` behavior. + +[forms-api]: html-and-forms.md +[ajax-form]: https://github.com/tomchristie/ajax-form +[jsonfield]: ../../api-guide/fields#jsonfield +[django-supported-versions]: https://www.djangoproject.com/download/#supported-versions \ No newline at end of file diff --git a/docs/topics/browsable-api.md b/docs/topics/browsable-api.md index 2879db74..0e12f925 100644 --- a/docs/topics/browsable-api.md +++ b/docs/topics/browsable-api.md @@ -35,7 +35,7 @@ To replace the default theme, add a `bootstrap_theme` block to your `api.html` a {% endblock %} -A suitable replacement theme can be generated using Bootstrap's [Customize Tool][bcustomize]. There are also pre-made themes available at [Bootswatch][bswatch]. To use any of the Bootswatch themes, simply download the theme's `bootstrap.min.css` file, add it to your project, and replace the default one as described above. +Suitable pre-made replacement themes are available at [Bootswatch][bswatch]. To use any of the Bootswatch themes, simply download the theme's `bootstrap.min.css` file, add it to your project, and replace the default one as described above. You can also change the navbar variant, which by default is `navbar-inverse`, using the `bootstrap_navbar_variant` block. The empty `{% block bootstrap_navbar_variant %}{% endblock %}` will use the original Bootstrap navbar style. @@ -75,7 +75,6 @@ All of the blocks available in the browsable API base template that can be used * `bootstrap_navbar_variant` - CSS class for the navbar. * `branding` - Branding section of the navbar, see [Bootstrap components][bcomponentsnav]. * `breadcrumbs` - Links showing resource nesting, allowing the user to go back up the resources. It's recommended to preserve these, but they can be overridden using the breadcrumbs block. -* `footer` - Any copyright notices or similar footer materials can go here (by default right-aligned). * `script` - JavaScript files for the page. * `style` - CSS stylesheets for the page. * `title` - Title of the page. diff --git a/docs/topics/browser-enhancements.md b/docs/topics/browser-enhancements.md index 5a172620..e1977e82 100644 --- a/docs/topics/browser-enhancements.md +++ b/docs/topics/browser-enhancements.md @@ -4,58 +4,36 @@ > > — [RESTful Web Services][cite], Leonard Richardson & Sam Ruby. +In order to allow the browsable API to function, there are a couple of browser enhancements that REST framework needs to provide. + +As of version 3.3.0 onwards these are enabled with javascript, using the [ajax-form][ajax-form] library. + ## Browser based PUT, DELETE, etc... -REST framework supports browser-based `PUT`, `DELETE` and other methods, by -overloading `POST` requests using a hidden form field. +The [AJAX form library][ajax-form] supports browser-based `PUT`, `DELETE` and other methods on HTML forms. -Note that this is the same strategy as is used in [Ruby on Rails][rails]. +After including the library, use the `data-method` attribute on the form, like so: -For example, given the following form: - -
- + + + ...
-`request.method` would return `"DELETE"`. - -## HTTP header based method overriding - -REST framework also supports method overriding via the semi-standard `X-HTTP-Method-Override` header. This can be useful if you are working with non-form content such as JSON and are working with an older web server and/or hosting provider that doesn't recognise particular HTTP methods such as `PATCH`. For example [Amazon Web Services ELB][aws_elb]. - -To use it, make a `POST` request, setting the `X-HTTP-Method-Override` header. - -For example, making a `PATCH` request via `POST` in jQuery: - - $.ajax({ - url: '/myresource/', - method: 'POST', - headers: {'X-HTTP-Method-Override': 'PATCH'}, - ... - }); +Note that prior to 3.3.0, this support was server-side rather than javascript based. The method overloading style (as used in [Ruby on Rails][rails]) is no longer supported due to subtle issues that it introduces in request parsing. ## Browser based submission of non-form content -Browser-based submission of content types other than form are supported by -using form fields named `_content` and `_content_type`: +Browser-based submission of content types such as JSON are supported by the [AJAX form library][ajax-form], using form fields with `data-override='content-type'` and `data-override='content'` attributes. -For example, given the following form: +For example: -
- - -
+
+ + + +
-`request.content_type` would return `"application/json"`, and -`request.stream` would return `"{'count': 1}"` - -## URL based accept headers - -REST framework can take `?accept=application/json` style URL parameters, -which allow the `Accept` header to be overridden. - -This can be useful for testing the API from a web browser, where you don't -have any control over what is sent in the `Accept` header. +Note that prior to 3.3.0, this support was server-side rather than javascript based. ## URL based format suffixes @@ -63,8 +41,37 @@ REST framework can take `?format=json` style URL parameters, which can be a useful shortcut for determining which content type should be returned from the view. -This is a more concise than using the `accept` override, but it also gives -you less control. (For example you can't specify any media type parameters) +This behavior is controlled using the `URL_FORMAT_OVERRIDE` setting. + +## HTTP header based method overriding + +Prior to version 3.3.0 the semi extension header `X-HTTP-Method-Override` was supported for overriding the request method. This behavior is no longer in core, but can be adding if needed using middleware. + +For example: + + METHOD_OVERRIDE_HEADER = 'HTTP_X_HTTP_METHOD_OVERRIDE' + + class MethodOverrideMiddleware(object): + def process_view(self, request, callback, callback_args, callback_kwargs): + if request.method != 'POST': + return + if METHOD_OVERRIDE_HEADER not in request.META: + return + request.method = request.META[METHOD_OVERRIDE_HEADER] + +## URL based accept headers + +Until version 3.3.0 REST framework included built-in support for `?accept=application/json` style URL parameters, which would allow the `Accept` header to be overridden. + +Since the introduction of the content negotiation API this behavior is no longer included in core, but may be added using a custom content negotiation class, if needed. + +For example: + + class AcceptQueryParamOverride() + def get_accept_list(self, request): + header = request.META.get('HTTP_ACCEPT', '*/*') + header = request.query_params.get('_accept', header) + return [token.strip() for token in header.split(',')] ## Doesn't HTML5 support PUT and DELETE forms? @@ -74,7 +81,7 @@ was later [dropped from the spec][html5]. There remains as well as how to support content types other than form-encoded data. [cite]: http://www.amazon.com/Restful-Web-Services-Leonard-Richardson/dp/0596529260 +[ajax-form]: https://github.com/tomchristie/ajax-form [rails]: http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-put-or-delete-methods-work [html5]: http://www.w3.org/TR/html5-diff/#changes-2010-06-24 [put_delete]: http://amundsen.com/examples/put-delete-forms/ -[aws_elb]: https://forums.aws.amazon.com/thread.jspa?messageID=400724 diff --git a/docs/topics/funding.md b/docs/topics/funding.md new file mode 100644 index 00000000..7857f865 --- /dev/null +++ b/docs/topics/funding.md @@ -0,0 +1,314 @@ + + + + +# Funding + +If you use REST framework commercially we strongly encourage you to invest in its continued development by signing up for a paid plan. + +**We believe that collaboratively funded software can offer outstanding returns on investment, by allowing users and clients to collectively share the cost of development.** + +Signing up for a paid plan will: + +* Directly contribute to faster releases, more features and higher quality software. +* Allow more time to be invested in documentation, issue triage and community support. +* Safeguard the future development of REST framework. + +REST framework will always be open source and permissively licensed, but we firmly believe it is in the commercial best-interest for users of the project to fund its ongoing development. + +--- + +## Making the business case + +Our successful Kickstarter campaign demonstrates the cost-reward ratio of shared development funding. + +With *typical corporate fundings of just £100-£1000 per organization* we successfully delivered: + +* The comprehensive 3.0 serializer redesign. +* Substantial improvements to the Browsable API. +* The admin interface. +* A new pagination API including offset/limit and cursor pagination implementations, plus on-page controls. +* A versioning API, including URL-based and header-based versioning schemes. +* Support for customizable exception handling. +* Support for Django's PostgreSQL HStoreField, ArrayField and JSONField. +* Templated HTML form support, including HTML forms with nested list and objects. +* Internationalization support for API responses, currently with 27 languages. +* The metadata APIs for handling `OPTIONS` requests and schema endpoints. +* Numerous minor improvements and better quality throughout the codebase. +* Ongoing triage and community support, closing over 1600 tickets. + +This incredible level of return on investment is *only possible through collaboratively funded models*, which is why we believe that supporting our paid plans is in everyone's best interest. + +--- + +## Individual plan + +This subscription is recommended for freelancers and other individuals with an interest in seeing REST framework continue to improve. + +If you are using REST framework as an full-time employee, consider recommending that your company takes out a [corporate plan](#corporate-plans). + +
+
+
+
+ $ + 15 + /month +
+
Individual
+
+
+ Support ongoing development +
+
+ Credited on the site +
+
+ +
+
+
+
+ +*Billing is monthly and you can cancel at any time.* + +--- + +## Corporate plans + +These subscriptions are recommended for companies and organizations using REST framework either publicly or privately. + +In exchange for funding you'll also receive advertising space on our site, allowing you to **promote your company or product to many tens of thousands of developers worldwide**. + +Our professional and premium plans also include **priority support**. At any time your engineers can escalate an issue or discussion group thread, and we'll ensure it gets a guaranteed response within the next working day. + +
+
+
+
+ $ + 50 + /month +
+
Basic
+
+
+ Support ongoing development +
+
+ Funding page ad placement +
+
+ +
+
+
+
+
+ $ + 250 + /month +
+
Professional
+
+
+ Add a half day per month development time to the project +
+
+ Homepage ad placement +
+
+ Priority support for your engineers +
+
+ +
+
+
+
+
+ $ + 500 + /month +
+
Premium
+
+
+ Add one full day per month development time to the project +
+
+ Full site ad placement +
+
+ Priority support for your engineers +
+
+ +
+
+
+ +
+ +*Billing is monthly and you can cancel at any time.* + +Once you've signed up we'll contact you via email and arrange your ad placements on the site. + +For further enquires please contact tom@tomchristie.com. + +--- + +## Roadmap + +Although we're incredibly proud of REST framework in its current state we believe there is still huge scope for improvement. What we're aiming for here is a *highly polished, rock solid product*. This needs to backed up with impeccable documentation and a great third party ecosystem. + +The roadmap below is a broad indication of just some of the ongoing and future work we believe is important to REST framework. + +* Increasing our "bus factor" through documented organizational process & safeguards. +* More time towards testing and hardening releases, with only gradual, well-documented deprecations. +* A formal policy on security backports for non-current releases. +* Continuing triage & community support. +* Improved project documentation, including versioned & internationalized docs. +* Improved third party package visibility. +* Refining the admin interface, ensuring it has a fully customizable API and making it suitable as end-user facing application. +* Cleaning up internal complexities including the `BrowsableAPIRenderer` and `Request` object. +* Support for alternative backends such as SQLAlchemy. +* Support for non-database backed services. +* HTTP Caching API & support for conditional database lookups. +* Benchmarking and performance improvements. +* In depth documentation on advanced usage and best practices. +* Documentation & support for integration with realtime systems. +* Hypermedia support and client libraries. +* Support for JSON schema as endpoints or `OPTIONS` responses. +* API metric tools. +* Debug & logging tools. +* Third party GraphQL support. + +By taking out a paid plan you'll be directly contributing towards making these features happen. diff --git a/docs/topics/html-and-forms.md b/docs/topics/html-and-forms.md new file mode 100644 index 00000000..7b8f1ccc --- /dev/null +++ b/docs/topics/html-and-forms.md @@ -0,0 +1,219 @@ +# HTML & Forms + +REST framework is suitable for returning both API style responses, and regular HTML pages. Additionally, serializers can used as HTML forms and rendered in templates. + +## Rendering HTML + +In order to return HTML responses you'll need to either `TemplateHTMLRenderer`, or `StaticHTMLRenderer`. + +The `TemplateHTMLRenderer` class expects the response to contain a dictionary of context data, and renders an HTML page based on a template that must be specified either in the view or on the response. + +The `StaticHTMLRender` class expects the response to contain a string of the pre-rendered HTML content. + +Because static HTML pages typically have different behavior from API responses you'll probably need to write any HTML views explicitly, rather than relying on the built-in generic views. + +Here's an example of a view that returns a list of "Profile" instances, rendered in an HTML template: + +**views.py**: + + from my_project.example.models import Profile + from rest_framework.renderers import TemplateHTMLRenderer + from rest_framework.response import Response + from rest_framework.views import APIView + + + class ProfileList(APIView): + renderer_classes = [TemplateHTMLRenderer] + template_name = 'profile_list.html' + + def get(self, request): + queryset = Profile.objects.all() + return Response({'profiles': queryset}) + +**profile_list.html**: + + +

Profiles

+
    + {% for profile in profiles %} +
  • {{ profile.name }}
  • + {% endfor %} +
+ + +## Rendering Forms + +Serializers may be rendered as forms by using the `render_form` template tag, and including the serializer instance as context to the template. + +The following view demonstrates an example of using a serializer in a template for viewing and updating a model instance: + +**views.py**: + + from django.shortcuts import get_object_or_404 + from my_project.example.models import Profile + from rest_framework.renderers import TemplateHTMLRenderer + from rest_framework.views import APIView + + + class ProfileDetail(APIView): + renderer_classes = [TemplateHTMLRenderer] + template_name = 'profile_detail.html' + + def get(self, request, pk): + profile = get_object_or_404(Profile, pk=pk) + serializer = ProfileSerializer(profile) + return Response({'serializer': serializer, 'profile': profile}) + + def post(self, request, pk): + profile = get_object_or_404(Profile, pk=pk) + serializer = ProfileSerializer(profile) + if not serializer.is_valid(): + return Response({'serializer': serializer, 'profile': profile}) + return redirect('profile-list') + +**profile_detail.html**: + + {% load rest_framework %} + + + +

Profile - {{ profile.name }}

+ +
+ {% csrf_token %} + {% render_form serializer %} + +
+ + + +### Using template packs + +The `render_form` tag takes an optional `template_pack` argument, that specifies which template directory should be used for rendering the form and form fields. + +REST framework includes three built-in template packs, all based on Bootstrap 3. The built-in styles are `horizontal`, `vertical`, and `inline`. The default style is `horizontal`. To use any of these template packs you'll want to also include the Bootstrap 3 CSS. + +The following HTML will link to a CDN hosted version of the Bootstrap 3 CSS: + + + … + + + +Third party packages may include alternate template packs, by bundling a template directory containing the necessary form and field templates. + +Let's take a look at how to render each of the three available template packs. For these examples we'll use a single serializer class to present a "Login" form. + + class LoginSerializer(serializers.Serializer): + email = serializers.EmailField( + max_length=100, + style={'placeholder': 'Email'} + ) + password = serializers.CharField( + max_length=100, + style={'input_type': 'password', 'placeholder': 'Password'} + ) + remember_me = serializers.BooleanField() + +--- + +#### `rest_framework/vertical` + +Presents form labels above their corresponding control inputs, using the standard Bootstrap layout. + +*This is the default template pack.* + + {% load rest_framework %} + + ... + +
+ {% csrf_token %} + {% render_form serializer template_pack='rest_framework/vertical' %} + +
+ +![Vertical form example](../img/vertical.png) + +--- + +#### `rest_framework/horizontal` + +Presents labels and controls alongside each other, using a 2/10 column split. + +*This is the form style used in the browsable API and admin renderers.* + + {% load rest_framework %} + + ... + +
+ {% csrf_token %} + {% render_form serializer %} +
+
+ +
+
+
+ +![Horizontal form example](../img/horizontal.png) + +--- + +#### `rest_framework/inline` + +A compact form style that presents all the controls inline. + + {% load rest_framework %} + + ... + +
+ {% csrf_token %} + {% render_form serializer template_pack='rest_framework/inline' %} + +
+ +![Inline form example](../img/inline.png) + +## Field styles + +Serializer fields can have their rendering style customized by using the `style` keyword argument. This argument is a dictionary of options that control the template and layout used. + +The most common way to customize the field style is to use the `base_template` style keyword argument to select which template in the template pack should be use. + +For example, to render a `CharField` as an HTML textarea rather than the default HTML input, you would use something like this: + + details = serializers.CharField( + max_length=1000, + style={'base_template': 'textarea.html'} + ) + +If you instead want a field to be rendered using a custom template that is *not part of an included template pack*, you can instead use the `template` style option, to fully specify a template name: + + details = serializers.CharField( + max_length=1000, + style={'template': 'my-field-templates/custom-input.html'} + ) + +Field templates can also use additional style properties, depending on their type. For example, the `textarea.html` template also accepts a `rows` property that can be used to affect the sizing of the control. + + details = serializers.CharField( + max_length=1000, + style={'base_template': 'textarea.html', 'rows': 10} + ) + +The complete list of `base_template` options and their associated style options is listed below. + +base_template | Valid field types | Additional style options +----|----|---- +input.html | Any string, numeric or date/time field | input_type, placeholder, hide_label +textarea.html | `CharField` | rows, placeholder, hide_label +select.html | `ChoiceField` or relational field types | hide_label +radio.html | `ChoiceField` or relational field types | inline, hide_label +select_multiple.html | `MultipleChoiceField` or relational fields with `many=True` | hide_label +checkbox_multiple.html | `MultipleChoiceField` or relational fields with `many=True` | inline, hide_label +checkbox.html | `BooleanField` | hide_label +fieldset.html | Nested serializer | hide_label +list_fieldset.html | `ListField` or nested serializer with `many=True` | hide_label diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 4bfcb003..d21f8e51 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -38,6 +38,142 @@ You can determine your currently installed version using `pip freeze`: --- +## 3.3.x series + +### 3.3.2 + +**Date**: [14th December 2015][3.3.2-milestone]. + +* `ListField` enforces input is a list. ([#3513][gh3513]) +* Fix regression hiding raw data form. ([#3600][gh3600], [#3578][gh3578]) +* Fix Python 3.5 compatibility. ([#3534][gh3534], [#3626][gh3626]) +* Allow setting a custom Django Paginator in `pagination.PageNumberPagination`. ([#3631][gh3631], [#3684][gh3684]) +* Fix relational fields without `to_fields` attribute. ([#3635][gh3635], [#3634][gh3634]) +* Fix `template.render` deprecation warnings for Django 1.9. ([#3654][gh3654]) +* Sort response headers in browsable API renderer. ([#3655][gh3655]) +* Use related_objects api for Django 1.9+. ([#3656][gh3656], [#3252][gh3252]) +* Add confirm modal when deleting. ([#3228][gh3228], [#3662][gh3662]) +* Reveal previously hidden AttributeErrors and TypeErrors while calling has_[object_]permissions. ([#3668][gh3668]) +* Make DRF compatible with multi template engine in Django 1.8. ([#3672][gh3672]) +* Update `NestedBoundField` to also handle empty string when rendering its form. ([#3677][gh3677]) +* Fix UUID validation to properly catch invalid input types. ([#3687][gh3687], [#3679][gh3679]) +* Fix caching issues. ([#3628][gh3628], [#3701][gh3701]) +* Fix Admin and API browser for views without a filter_class. ([#3705][gh3705], [#3596][gh3596], [#3597][gh3597]) +* Add app_name to rest_framework.urls. ([#3714][gh3714]) +* Improve authtoken's views to support url versioning. ([#3718][gh3718], [#3723][gh3723]) + +### 3.3.1 + +**Date**: [4th November 2015][3.3.1-milestone]. + +* Resolve parsing bug when accessing `request.POST` ([#3592][gh3592]) +* Correctly deal with `to_field` referring to primary key. ([#3593][gh3593]) +* Allow filter HTML to render when no `filter_class` is defined. ([#3560][gh3560]) +* Fix admin rendering issues. ([#3564][gh3564], [#3556][gh3556]) +* Fix issue with DecimalValidator. ([#3568][gh3568]) + +### 3.3.0 + +**Date**: [28th October 2015][3.3.0-milestone]. + +* HTML controls for filters. ([#3315][gh3315]) +* Forms API. ([#3475][gh3475]) +* AJAX browsable API. ([#3410][gh3410]) +* Added JSONField. ([#3454][gh3454]) +* Correctly map `to_field` when creating `ModelSerializer` relational fields. ([#3526][gh3526]) +* Include keyword arguments when mapping `FilePathField` to a serializer field. ([#3536][gh3536]) +* Map appropriate model `error_messages` on `ModelSerializer` uniqueness constraints. ([#3435][gh3435]) +* Include `max_length` constraint for `ModelSerializer` fields mapped from TextField. ([#3509][gh3509]) +* Added support for Django 1.9. ([#3450][gh3450], [#3525][gh3525]) +* Removed support for Django 1.5 & 1.6. ([#3421][gh3421], [#3429][gh3429]) +* Removed 'south' migrations. ([#3495][gh3495]) + +## 3.2.x series + +### 3.2.5 + +**Date**: [27th October 2015][3.2.5-milestone]. + +* Escape `username` in optional logout tag. ([#3550][gh3550]) + +### 3.2.4 + +**Date**: [21th September 2015][3.2.4-milestone]. + +* Don't error on missing `ViewSet.search_fields` attribute. ([#3324][gh3324], [#3323][gh3323]) +* Fix `allow_empty` not working on serializers with `many=True`. ([#3361][gh3361], [#3364][gh3364]) +* Let `DurationField` accepts integers. ([#3359][gh3359]) +* Multi-level dictionaries not supported in multipart requests. ([#3314][gh3314]) +* Fix `ListField` truncation on HTTP PATCH ([#3415][gh3415], [#2761][gh2761]) + +### 3.2.3 + +**Date**: [24th August 2015][3.2.3-milestone]. + +* Added `html_cutoff` and `html_cutoff_text` for limiting select dropdowns. ([#3313][gh3313]) +* Added regex style to `SearchFilter`. ([#3316][gh3316]) +* Resolve issues with setting blank HTML fields. ([#3318][gh3318]) ([#3321][gh3321]) +* Correctly display existing 'select multiple' values in browsable API forms. ([#3290][gh3290]) +* Resolve duplicated validation message for `IPAddressField`. ([#3249[gh3249]) ([#3250][gh3250]) +* Fix to ensure admin renderer continues to work when pagination is disabled. ([#3275][gh3275]) +* Resolve error with `LimitOffsetPagination` when count=0, offset=0. ([#3303][gh3303]) + +### 3.2.2 + +**Date**: [13th August 2015][3.2.2-milestone]. + +* Add `display_value()` method for use when displaying relational field select inputs. ([#3254][gh3254]) +* Fix issue with `BooleanField` checkboxes incorrectly displaying as checked. ([#3258][gh3258]) +* Ensure empty checkboxes properly set `BooleanField` to `False` in all cases. ([#2776][gh2776]) +* Allow `WSGIRequest.FILES` property without raising incorrect deprecated error. ([#3261][gh3261]) +* Resolve issue with rendering nested serializers in forms. ([#3260][gh3260]) +* Raise an error if user accidentally pass a serializer instance to a response, rather than data. ([#3241][gh3241]) + +### 3.2.1 + +**Date**: [7th August 2015][3.2.1-milestone]. + +* Fix for relational select widgets rendering without any choices. ([#3237][gh3237]) +* Fix for `1`, `0` rendering as `true`, `false` in the admin interface. [#3227][gh3227]) +* Fix for ListFields with single value in HTML form input. ([#3238][gh3238]) +* Allow `request.FILES` for compat with Django's `HTTPRequest` class. ([#3239][gh3239]) + +### 3.2.0 + +**Date**: [6th August 2015][3.2.0-milestone]. + +* Add `AdminRenderer`. ([#2926][gh2926]) +* Add `FilePathField`. ([#1854][gh1854]) +* Add `allow_empty` to `ListField`. ([#2250][gh2250]) +* Support django-guardian 1.3. ([#3165][gh3165]) +* Support grouped choices. ([#3225][gh3225]) +* Support error forms in browsable API. ([#3024][gh3024]) +* Allow permission classes to customize the error message. ([#2539][gh2539]) +* Support `source=` on hyperlinked fields. ([#2690][gh2690]) +* `ListField(allow_null=True)` now allows null as the list value, not null items in the list. ([#2766][gh2766]) +* `ManyToMany()` maps to `allow_empty=False`, `ManyToMany(blank=True)` maps to `allow_empty=True`. ([#2804][gh2804]) +* Support custom serialization styles for primary key fields. ([#2789][gh2789]) +* `OPTIONS` requests support nested representations. ([#2915][gh2915]) +* Set `view.action == "metadata"` for viewsets with `OPTIONS` requests. ([#3115][gh3115]) +* Support `allow_blank` on `UUIDField`. ([#3130][gh#3130]) +* Do not display view docstrings with 401 or 403 response codes. ([#3216][gh3216]) +* Resolve Django 1.8 deprecation warnings. ([#2886][gh2886]) +* Fix for `DecimalField` validation. ([#3139][gh3139]) +* Fix behavior of `allow_blank=False` when used with `trim_whitespace=True`. ([#2712][gh2712]) +* Fix issue with some field combinations incorrectly mapping to an invalid `allow_blank` argument. ([#3011][gh3011]) +* Fix for output representations with prefetches and modified querysets. ([#2704][gh2704], [#2727][gh2727]) +* Fix assertion error when CursorPagination is provided with certains invalid query parameters. (#2920)[gh2920]. +* Fix `UnicodeDecodeError` when invalid characters included in header with `TokenAuthentication`. ([#2928][gh2928]) +* Fix transaction rollbacks with `@non_atomic_requests` decorator. ([#3016][gh3016]) +* Fix duplicate results issue with Oracle databases using `SearchFilter`. ([#2935][gh2935]) +* Fix checkbox alignment and rendering in browsable API forms. ([#2783][gh2783]) +* Fix for unsaved file objects which should use `"url": null` in the representation. ([#2759][gh2759]) +* Fix field value rendering in browsable API. ([#2416][gh2416]) +* Fix `HStoreField` to include `allow_blank=True` in `DictField` mapping. ([#2659][gh2659]) +* Numerous other cleanups, improvements to error messaging, private API & minor fixes. + +--- + ## 3.1.x series ### 3.1.3 @@ -225,6 +361,15 @@ For older release notes, [please see the version 2.x documentation][old-release- [3.1.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.1+Release%22 [3.1.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.2+Release%22 [3.1.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.3+Release%22 +[3.2.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.0+Release%22 +[3.2.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.1+Release%22 +[3.2.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.2+Release%22 +[3.2.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.3+Release%22 +[3.2.4-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.4+Release%22 +[3.2.5-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.5+Release%22 +[3.3.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.3.0+Release%22 +[3.3.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.3.1+Release%22 +[3.3.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.3.2+Release%22 [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013 @@ -382,3 +527,125 @@ For older release notes, [please see the version 2.x documentation][old-release- [gh2618]: https://github.com/tomchristie/django-rest-framework/issues/2618 [gh3008]: https://github.com/tomchristie/django-rest-framework/issues/3008 [gh2695]: https://github.com/tomchristie/django-rest-framework/issues/2695 + + +[gh1854]: https://github.com/tomchristie/django-rest-framework/issues/1854 +[gh2250]: https://github.com/tomchristie/django-rest-framework/issues/2250 +[gh2416]: https://github.com/tomchristie/django-rest-framework/issues/2416 +[gh2539]: https://github.com/tomchristie/django-rest-framework/issues/2539 +[gh2659]: https://github.com/tomchristie/django-rest-framework/issues/2659 +[gh2690]: https://github.com/tomchristie/django-rest-framework/issues/2690 +[gh2704]: https://github.com/tomchristie/django-rest-framework/issues/2704 +[gh2712]: https://github.com/tomchristie/django-rest-framework/issues/2712 +[gh2727]: https://github.com/tomchristie/django-rest-framework/issues/2727 +[gh2759]: https://github.com/tomchristie/django-rest-framework/issues/2759 +[gh2766]: https://github.com/tomchristie/django-rest-framework/issues/2766 +[gh2783]: https://github.com/tomchristie/django-rest-framework/issues/2783 +[gh2789]: https://github.com/tomchristie/django-rest-framework/issues/2789 +[gh2804]: https://github.com/tomchristie/django-rest-framework/issues/2804 +[gh2886]: https://github.com/tomchristie/django-rest-framework/issues/2886 +[gh2915]: https://github.com/tomchristie/django-rest-framework/issues/2915 +[gh2920]: https://github.com/tomchristie/django-rest-framework/issues/2920 +[gh2926]: https://github.com/tomchristie/django-rest-framework/issues/2926 +[gh2928]: https://github.com/tomchristie/django-rest-framework/issues/2928 +[gh2935]: https://github.com/tomchristie/django-rest-framework/issues/2935 +[gh3011]: https://github.com/tomchristie/django-rest-framework/issues/3011 +[gh3016]: https://github.com/tomchristie/django-rest-framework/issues/3016 +[gh3024]: https://github.com/tomchristie/django-rest-framework/issues/3024 +[gh3115]: https://github.com/tomchristie/django-rest-framework/issues/3115 +[gh3139]: https://github.com/tomchristie/django-rest-framework/issues/3139 +[gh3165]: https://github.com/tomchristie/django-rest-framework/issues/3165 +[gh3216]: https://github.com/tomchristie/django-rest-framework/issues/3216 +[gh3225]: https://github.com/tomchristie/django-rest-framework/issues/3225 + + +[gh3237]: https://github.com/tomchristie/django-rest-framework/issues/3237 +[gh3227]: https://github.com/tomchristie/django-rest-framework/issues/3227 +[gh3238]: https://github.com/tomchristie/django-rest-framework/issues/3238 +[gh3239]: https://github.com/tomchristie/django-rest-framework/issues/3239 + + +[gh3254]: https://github.com/tomchristie/django-rest-framework/issues/3254 +[gh3258]: https://github.com/tomchristie/django-rest-framework/issues/3258 +[gh2776]: https://github.com/tomchristie/django-rest-framework/issues/2776 +[gh3261]: https://github.com/tomchristie/django-rest-framework/issues/3261 +[gh3260]: https://github.com/tomchristie/django-rest-framework/issues/3260 +[gh3241]: https://github.com/tomchristie/django-rest-framework/issues/3241 + + +[gh3249]: https://github.com/tomchristie/django-rest-framework/issues/3249 +[gh3250]: https://github.com/tomchristie/django-rest-framework/issues/3250 +[gh3275]: https://github.com/tomchristie/django-rest-framework/issues/3275 +[gh3288]: https://github.com/tomchristie/django-rest-framework/issues/3288 +[gh3290]: https://github.com/tomchristie/django-rest-framework/issues/3290 +[gh3303]: https://github.com/tomchristie/django-rest-framework/issues/3303 +[gh3313]: https://github.com/tomchristie/django-rest-framework/issues/3313 +[gh3316]: https://github.com/tomchristie/django-rest-framework/issues/3316 +[gh3318]: https://github.com/tomchristie/django-rest-framework/issues/3318 +[gh3321]: https://github.com/tomchristie/django-rest-framework/issues/3321 + + +[gh2761]: https://github.com/tomchristie/django-rest-framework/issues/2761 +[gh3314]: https://github.com/tomchristie/django-rest-framework/issues/3314 +[gh3323]: https://github.com/tomchristie/django-rest-framework/issues/3323 +[gh3324]: https://github.com/tomchristie/django-rest-framework/issues/3324 +[gh3359]: https://github.com/tomchristie/django-rest-framework/issues/3359 +[gh3361]: https://github.com/tomchristie/django-rest-framework/issues/3361 +[gh3364]: https://github.com/tomchristie/django-rest-framework/issues/3364 +[gh3415]: https://github.com/tomchristie/django-rest-framework/issues/3415 + + +[gh3550]:https://github.com/tomchristie/django-rest-framework/issues/3550 + + +[gh3315]: https://github.com/tomchristie/django-rest-framework/issues/3315 +[gh3410]: https://github.com/tomchristie/django-rest-framework/issues/3410 +[gh3435]: https://github.com/tomchristie/django-rest-framework/issues/3435 +[gh3450]: https://github.com/tomchristie/django-rest-framework/issues/3450 +[gh3454]: https://github.com/tomchristie/django-rest-framework/issues/3454 +[gh3475]: https://github.com/tomchristie/django-rest-framework/issues/3475 +[gh3495]: https://github.com/tomchristie/django-rest-framework/issues/3495 +[gh3509]: https://github.com/tomchristie/django-rest-framework/issues/3509 +[gh3421]: https://github.com/tomchristie/django-rest-framework/issues/3421 +[gh3525]: https://github.com/tomchristie/django-rest-framework/issues/3525 +[gh3526]: https://github.com/tomchristie/django-rest-framework/issues/3526 +[gh3429]: https://github.com/tomchristie/django-rest-framework/issues/3429 +[gh3536]: https://github.com/tomchristie/django-rest-framework/issues/3536 + + +[gh3556]: https://github.com/tomchristie/django-rest-framework/issues/3556 +[gh3560]: https://github.com/tomchristie/django-rest-framework/issues/3560 +[gh3564]: https://github.com/tomchristie/django-rest-framework/issues/3564 +[gh3568]: https://github.com/tomchristie/django-rest-framework/issues/3568 +[gh3592]: https://github.com/tomchristie/django-rest-framework/issues/3592 +[gh3593]: https://github.com/tomchristie/django-rest-framework/issues/3593 + + +[gh3228]: https://github.com/tomchristie/django-rest-framework/issues/3228 +[gh3252]: https://github.com/tomchristie/django-rest-framework/issues/3252 +[gh3513]: https://github.com/tomchristie/django-rest-framework/issues/3513 +[gh3534]: https://github.com/tomchristie/django-rest-framework/issues/3534 +[gh3578]: https://github.com/tomchristie/django-rest-framework/issues/3578 +[gh3596]: https://github.com/tomchristie/django-rest-framework/issues/3596 +[gh3597]: https://github.com/tomchristie/django-rest-framework/issues/3597 +[gh3600]: https://github.com/tomchristie/django-rest-framework/issues/3600 +[gh3626]: https://github.com/tomchristie/django-rest-framework/issues/3626 +[gh3628]: https://github.com/tomchristie/django-rest-framework/issues/3628 +[gh3631]: https://github.com/tomchristie/django-rest-framework/issues/3631 +[gh3634]: https://github.com/tomchristie/django-rest-framework/issues/3634 +[gh3635]: https://github.com/tomchristie/django-rest-framework/issues/3635 +[gh3654]: https://github.com/tomchristie/django-rest-framework/issues/3654 +[gh3655]: https://github.com/tomchristie/django-rest-framework/issues/3655 +[gh3656]: https://github.com/tomchristie/django-rest-framework/issues/3656 +[gh3662]: https://github.com/tomchristie/django-rest-framework/issues/3662 +[gh3668]: https://github.com/tomchristie/django-rest-framework/issues/3668 +[gh3672]: https://github.com/tomchristie/django-rest-framework/issues/3672 +[gh3677]: https://github.com/tomchristie/django-rest-framework/issues/3677 +[gh3679]: https://github.com/tomchristie/django-rest-framework/issues/3679 +[gh3684]: https://github.com/tomchristie/django-rest-framework/issues/3684 +[gh3687]: https://github.com/tomchristie/django-rest-framework/issues/3687 +[gh3701]: https://github.com/tomchristie/django-rest-framework/issues/3701 +[gh3705]: https://github.com/tomchristie/django-rest-framework/issues/3705 +[gh3714]: https://github.com/tomchristie/django-rest-framework/issues/3714 +[gh3718]: https://github.com/tomchristie/django-rest-framework/issues/3718 +[gh3723]: https://github.com/tomchristie/django-rest-framework/issues/3723 diff --git a/docs/topics/rest-hypermedia-hateoas.md b/docs/topics/rest-hypermedia-hateoas.md index 7e6d2408..5517b150 100644 --- a/docs/topics/rest-hypermedia-hateoas.md +++ b/docs/topics/rest-hypermedia-hateoas.md @@ -32,7 +32,7 @@ REST framework also includes [serialization] and [parser]/[renderer] components ## What REST framework doesn't provide. -What REST framework doesn't do is give you is machine readable hypermedia formats such as [HAL][hal], [Collection+JSON][collection], [JSON API][json-api] or HTML [microformats] by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope. +What REST framework doesn't do is give you machine readable hypermedia formats such as [HAL][hal], [Collection+JSON][collection], [JSON API][json-api] or HTML [microformats] by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope. [cite]: http://vimeo.com/channels/restfest/page:2 [dissertation]: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm diff --git a/docs/topics/third-party-resources.md b/docs/topics/third-party-resources.md index a024ddfc..fc507dea 100644 --- a/docs/topics/third-party-resources.md +++ b/docs/topics/third-party-resources.md @@ -195,6 +195,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque * [drf-any-permissions][drf-any-permissions] - Provides alternative permission handling. * [djangorestframework-composed-permissions][djangorestframework-composed-permissions] - Provides a simple way to define complex permissions. * [rest_condition][rest-condition] - Another extension for building complex permissions in a simple and convenient way. +* [dry-rest-permissions][dry-rest-permissions] - Provides a simple way to define permissions for individual api actions. ### Serializers @@ -211,6 +212,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque ### Views * [djangorestframework-bulk][djangorestframework-bulk] - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests. +* [django-rest-multiple-models][django-rest-multiple-models] - Provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request. ### Routers @@ -231,17 +233,22 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque ### Filtering * [djangorestframework-chain][djangorestframework-chain] - Allows arbitrary chaining of both relations and lookup filters. +* [django-url-filter][django-url-filter] - Allows a safe way to filter data via human-friendly URLs. It is a generic library which is not tied to DRF but it provides easy integration with DRF. ### Misc +* [cookiecutter-django-rest][cookiecutter-django-rest] - A cookiecutter template that takes care of the setup and configuration so you can focus on making your REST apis awesome. * [djangorestrelationalhyperlink][djangorestrelationalhyperlink] - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer. * [django-rest-swagger][django-rest-swagger] - An API documentation generator for Swagger UI. * [django-rest-framework-proxy][django-rest-framework-proxy] - Proxy to redirect incoming request to another API server. -* [gaiarestframework][gaiarestframework] - Utils for django-rest-framewok +* [gaiarestframework][gaiarestframework] - Utils for django-rest-framework * [drf-extensions][drf-extensions] - A collection of custom extensions * [ember-django-adapter][ember-django-adapter] - An adapter for working with Ember.js * [django-versatileimagefield][django-versatileimagefield] - Provides a drop-in replacement for Django's stock `ImageField` that makes it easy to serve images in multiple sizes/renditions from a single field. For DRF-specific implementation docs, [click here][django-versatileimagefield-drf-docs]. * [drf-tracking][drf-tracking] - Utilities to track requests to DRF API views. +* [django-rest-framework-braces][django-rest-framework-braces] - Collection of utilities for working with Django Rest Framework. The most notable ones are [FormSerializer](https://django-rest-framework-braces.readthedocs.org/en/latest/overview.html#formserializer) and [SerializerForm](https://django-rest-framework-braces.readthedocs.org/en/latest/overview.html#serializerform), which are adapters between DRF serializers and Django forms. +* [drf-haystack][drf-haystack] - Haystack search for Django Rest Framework +* [django-rest-framework-version-transforms][django-rest-framework-version-transforms] - Enables the use of delta transformations for versioning of DRF resource representations. ## Other Resources @@ -286,6 +293,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque [drf-create-issue]: https://github.com/tomchristie/django-rest-framework/issues/new [authentication]: ../api-guide/authentication.md [permissions]: ../api-guide/permissions.md +[third-party-resources]: ../topics/third-party-resources/#existing-third-party-packages [discussion-group]: https://groups.google.com/forum/#!forum/django-rest-framework [djangorestframework-digestauth]: https://github.com/juanriaza/django-rest-framework-digestauth [django-oauth-toolkit]: https://github.com/evonove/django-oauth-toolkit @@ -303,6 +311,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque [drf-compound-fields]: https://github.com/estebistec/drf-compound-fields [django-extra-fields]: https://github.com/Hipo/drf-extra-fields [djangorestframework-bulk]: https://github.com/miki725/django-rest-framework-bulk +[django-rest-multiple-models]: https://github.com/Axiologue/DjangoRestMultipleModels [drf-nested-routers]: https://github.com/alanjds/drf-nested-routers [wq.db.rest]: http://wq.io/docs/about-rest [djangorestframework-msgpack]: https://github.com/juanriaza/django-rest-framework-msgpack @@ -336,3 +345,9 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque [django-versatileimagefield-drf-docs]:http://django-versatileimagefield.readthedocs.org/en/latest/drf_integration.html [cdrf.co]:http://www.cdrf.co [drf-tracking]: https://github.com/aschn/drf-tracking +[django-rest-framework-braces]: https://github.com/dealertrack/django-rest-framework-braces +[dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions +[django-url-filter]: https://github.com/miki725/django-url-filter +[cookiecutter-django-rest]: https://github.com/agconti/cookiecutter-django-rest +[drf-haystack]: http://drf-haystack.readthedocs.org/en/latest/ +[django-rest-framework-version-transforms]: https://github.com/mrhwick/django-rest-framework-version-transforms diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 09a124d3..890f8d56 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -89,7 +89,6 @@ We'll also need to create an initial migration for our snippet model, and sync t The first thing we need to get started on our Web API is to provide a way of serializing and deserializing the snippet instances into representations such as `json`. We can do this by declaring serializers that work very similar to Django's forms. Create a file in the `snippets` directory named `serializers.py` and add the following. - from django.forms import widgets from rest_framework import serializers from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES @@ -182,7 +181,7 @@ We can also serialize querysets instead of model instances. To do so we simply serializer = SnippetSerializer(Snippet.objects.all(), many=True) serializer.data - # [{'pk': 1, 'title': u'', 'code': u'foo = "bar"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}, {'pk': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}] + # [OrderedDict([('pk', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])] ## Using ModelSerializers @@ -318,7 +317,7 @@ Quit out of the shell... Validating models... 0 errors found - Django version 1.4.3, using settings 'tutorial.settings' + Django version 1.8.3, using settings 'tutorial.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C. diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 2cad1e5d..c2e7e1c0 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -108,7 +108,7 @@ and Now update the `urls.py` file slightly, to append a set of `format_suffix_patterns` in addition to the existing URLs. - from django.conf.urls import patterns, url + from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views @@ -157,8 +157,8 @@ We can control the format of the response that we get back, either by using the Or by appending a format suffix: - http http://127.0.0.1:8000/snippets/.json # JSON suffix - http http://127.0.0.1:8000/snippets/.api # Browsable API suffix + http http://127.0.0.1:8000/snippets.json # JSON suffix + http http://127.0.0.1:8000/snippets.api # Browsable API suffix Similarly, we can control the format of the request that we send, using the `Content-Type` header. diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 887d1e56..8a9d73e4 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -146,7 +146,7 @@ And, at the end of the file, add a pattern to include the login and logout views namespace='rest_framework')), ] -The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the `'rest_framework'` namespace. +The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the `'rest_framework'` namespace. In Django 1.9+, REST framework will set the namespace, so you may leave it out. Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again. diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index 63dff73f..f1dbe944 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -45,7 +45,7 @@ Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighl return Response(snippet.highlighted) def perform_create(self, serializer): - serializer.save(owner=self.request.user) + serializer.save(owner=self.request.user) This time we've used the `ModelViewSet` class in order to get the complete set of default read and write operations. diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 5feacf4c..2bb27435 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -68,7 +68,7 @@ Right, we'd better write some views then. Open `tutorial/quickstart/views.py` a """ API endpoint that allows users to be viewed or edited. """ - queryset = User.objects.all() + queryset = User.objects.all().order_by('-date_joined') serializer_class = UserSerializer @@ -83,8 +83,6 @@ Rather than write multiple views we're grouping together all the common behavior We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise. -For trivial cases you can simply set a `model` attribute on the `ViewSet` class and the serializer and queryset will be automatically generated for you. Setting the `queryset` and/or `serializer_class` attributes gives you more explicit control of the API behaviour, and is the recommended style for most applications. - ## URLs Okay, now let's wire up the API URLs. On to `tutorial/urls.py`... diff --git a/docs_theme/base.html b/docs_theme/base.html index 4ec726b0..369927b4 100644 --- a/docs_theme/base.html +++ b/docs_theme/base.html @@ -57,12 +57,10 @@
- {% include "nav.html" %}
- - -
- +
+
+ +
- - +
@@ -172,10 +151,10 @@ diff --git a/docs_theme/css/default.css b/docs_theme/css/default.css index c3b9e0f1..192e8686 100644 --- a/docs_theme/css/default.css +++ b/docs_theme/css/default.css @@ -5,11 +5,12 @@ pre { } .dropdown .dropdown-menu { - display: none; + display: none; + overflow-y: scroll; } .dropdown.open .dropdown-menu { - display: block; + display: block; } @media (max-width: 480px) { @@ -36,15 +37,8 @@ body.index-page #main-content iframe.github-star-button { margin-right: -15px; } -/* Tweet button */ -body.index-page #main-content iframe.twitter-share-button { - float: right; - margin-top: -12px; - margin-right: 8px; -} - -/* Travis CI badge */ -body.index-page #main-content img.travis-build-image { +/* Travis CI and PyPI badge */ +body.index-page #main-content img.status-badge { float: right; margin-right: 8px; margin-top: -11px; @@ -182,7 +176,7 @@ body{ } #main-content h3, #main-content h4, #main-content h5 { - font-weight: 500; + font-weight: 300; margin-top: 15px } @@ -419,3 +413,7 @@ ul.sponsor { #mkdocs_search_modal article p{ word-wrap: break-word; } + +.toclink { + color: #333; +} diff --git a/docs_theme/js/theme.js b/docs_theme/js/theme.js index 8208f1f4..ddbd9c90 100644 --- a/docs_theme/js/theme.js +++ b/docs_theme/js/theme.js @@ -1,35 +1,35 @@ -function getSearchTerm() -{ - var sPageURL = window.location.search.substring(1); - var sURLVariables = sPageURL.split('&'); - for (var i = 0; i < sURLVariables.length; i++) - { - var sParameterName = sURLVariables[i].split('='); - if (sParameterName[0] == 'q') - { - return sParameterName[1]; - } +var getSearchTerm = function() { + var sPageURL = window.location.search.substring(1); + var sURLVariables = sPageURL.split('&'); + for (var i = 0; i < sURLVariables.length; i++) { + var sParameterName = sURLVariables[i].split('='); + if (sParameterName[0] === 'q') { + return sParameterName[1]; } -} + } +}; + +var initilizeSearch = function() { + require.config({ baseUrl: '/mkdocs/js' }); + require(['search']); +}; $(function() { + var searchTerm = getSearchTerm(), + $searchModal = $('#mkdocs_search_modal'), + $searchQuery = $searchModal.find('#mkdocs-search-query'), + $searchResults = $searchModal.find('#mkdocs-search-results'); - var initialise_search = function(){ - require.config({"baseUrl":"/mkdocs/js"}); - require(["search",]); - } + $('pre code').parent().addClass('prettyprint well'); - var search_term = getSearchTerm(); - if(search_term){ - $('#mkdocs_search_modal').modal(); - } - - $('pre code').parent().addClass('prettyprint well'); - - $(document).on("submit", "#mkdocs_search_modal form", function (e) { - $("#mkdocs-search-results").html("Searching..."); - initialise_search(); - return false; - }); + if (searchTerm) { + $searchQuery.val(searchTerm); + $searchResults.text('Searching...'); + $searchModal.modal(); + } + $searchModal.on('shown', function() { + $searchQuery.focus(); + initilizeSearch(); + }); }); diff --git a/mkdocs.yml b/mkdocs.yml index efb43f39..a2f97702 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,6 +6,10 @@ repo_url: https://github.com/tomchristie/django-rest-framework theme_dir: docs_theme +markdown_extensions: + - toc: + anchorlink: True + pages: - Home: 'index.md' - Tutorial: @@ -47,6 +51,7 @@ pages: - 'Documenting your API': 'topics/documenting-your-api.md' - 'Internationalization': 'topics/internationalization.md' - 'AJAX, CSRF & CORS': 'topics/ajax-csrf-cors.md' + - 'HTML & Forms': 'topics/html-and-forms.md' - 'Browser Enhancements': 'topics/browser-enhancements.md' - 'The Browsable API': 'topics/browsable-api.md' - 'REST, Hypermedia & HATEOAS': 'topics/rest-hypermedia-hateoas.md' @@ -55,5 +60,7 @@ pages: - 'Project management': 'topics/project-management.md' - '3.0 Announcement': 'topics/3.0-announcement.md' - '3.1 Announcement': 'topics/3.1-announcement.md' + - '3.2 Announcement': 'topics/3.2-announcement.md' + - '3.3 Announcement': 'topics/3.3-announcement.md' - 'Kickstarter Announcement': 'topics/kickstarter-announcement.md' - 'Release Notes': 'topics/release-notes.md' diff --git a/requirements.txt b/requirements.txt index 4ec84f68..0b41cd50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ # The base set of requirements for REST framework is actually # just Django, but for the purposes of development and testing -# there are a number of packages that it is useful to install. +# there are a number of packages that are useful to install. # Laying these out as seperate requirements files, allows us to # only included the relevent sets when running tox, and ensures -# we are only ever declaring out dependancies in one place. +# we are only ever declaring our dependencies in one place. -r requirements/requirements-optionals.txt -r requirements/requirements-testing.txt diff --git a/requirements/requirements-codestyle.txt b/requirements/requirements-codestyle.txt index 88f61fdf..2284a4ca 100644 --- a/requirements/requirements-codestyle.txt +++ b/requirements/requirements-codestyle.txt @@ -1,3 +1,6 @@ # PEP8 code linting, which we run on all commits. flake8==2.4.0 pep8==1.5.7 + +# Sort and lint imports +isort==4.2.2 diff --git a/requirements/requirements-optionals.txt b/requirements/requirements-optionals.txt index af9937cf..3ada43eb 100644 --- a/requirements/requirements-optionals.txt +++ b/requirements/requirements-optionals.txt @@ -1,4 +1,4 @@ # Optional packages which may be used with REST framework. markdown==2.5.2 -django-guardian==1.2.5 -django-filter==0.9.2 +django-guardian==1.3.0 +django-filter==0.10.0 diff --git a/requirements/requirements-packaging.txt b/requirements/requirements-packaging.txt index 1efb2f83..8f62ee36 100644 --- a/requirements/requirements-packaging.txt +++ b/requirements/requirements-packaging.txt @@ -5,4 +5,4 @@ wheel==0.24.0 twine==1.4.0 # Transifex client for managing translation resources. -transifex-client==0.10 +transifex-client==0.11 diff --git a/requirements/requirements-testing.txt b/requirements/requirements-testing.txt index a8d5d322..6900028d 100644 --- a/requirements/requirements-testing.txt +++ b/requirements/requirements-testing.txt @@ -1,3 +1,4 @@ # PyTest for running the tests. pytest==2.6.4 pytest-django==2.8.0 +pytest-cov==1.8.1 diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index 33414f76..0e519999 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -8,7 +8,7 @@ ______ _____ _____ _____ __ """ __title__ = 'Django REST framework' -__version__ = '3.1.3' +__version__ = '3.3.2' __author__ = 'Tom Christie' __license__ = 'BSD 2-Clause' __copyright__ = 'Copyright 2011-2015 Tom Christie' diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 8b5c2009..9e73ef63 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -2,13 +2,15 @@ Provides various authentication policies. """ from __future__ import unicode_literals + import base64 -from django.contrib.auth import authenticate + +from django.contrib.auth import authenticate, get_user_model from django.middleware.csrf import CsrfViewMiddleware from django.utils.translation import ugettext_lazy as _ -from rest_framework import exceptions, HTTP_HEADER_ENCODING + +from rest_framework import HTTP_HEADER_ENCODING, exceptions from rest_framework.authtoken.models import Token -from rest_framework.compat import get_user_model def get_authorization_header(request): @@ -86,9 +88,8 @@ class BasicAuthentication(BaseAuthentication): """ Authenticate the userid and password against username and password. """ - username_field = getattr(get_user_model(), 'USERNAME_FIELD', 'username') credentials = { - username_field: userid, + get_user_model().USERNAME_FIELD: userid, 'password': password } user = authenticate(**credentials) @@ -116,9 +117,8 @@ class SessionAuthentication(BaseAuthentication): Otherwise returns `None`. """ - # Get the underlying HttpRequest object - request = request._request - user = getattr(request, 'user', None) + # Get the session-based user from the underlying HttpRequest object + user = getattr(request._request, 'user', None) # Unauthenticated, CSRF validation not required if not user or not user.is_active: @@ -170,7 +170,13 @@ class TokenAuthentication(BaseAuthentication): msg = _('Invalid token header. Token string should not contain spaces.') raise exceptions.AuthenticationFailed(msg) - return self.authenticate_credentials(auth[1]) + try: + token = auth[1].decode() + except UnicodeError: + msg = _('Invalid token header. Token string should not contain invalid characters.') + raise exceptions.AuthenticationFailed(msg) + + return self.authenticate_credentials(token) def authenticate_credentials(self, key): try: diff --git a/rest_framework/authtoken/admin.py b/rest_framework/authtoken/admin.py index ec28eb1c..1a507249 100644 --- a/rest_framework/authtoken/admin.py +++ b/rest_framework/authtoken/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from rest_framework.authtoken.models import Token diff --git a/rest_framework/authtoken/migrations/0001_initial.py b/rest_framework/authtoken/migrations/0001_initial.py index 769f6202..0eb9fbcb 100644 --- a/rest_framework/authtoken/migrations/0001_initial.py +++ b/rest_framework/authtoken/migrations/0001_initial.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations from django.conf import settings +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/rest_framework/authtoken/models.py b/rest_framework/authtoken/models.py index a1a9315f..b329ee65 100644 --- a/rest_framework/authtoken/models.py +++ b/rest_framework/authtoken/models.py @@ -5,7 +5,6 @@ from django.conf import settings from django.db import models from django.utils.encoding import python_2_unicode_compatible - # Prior to Django 1.5, the AUTH_USER_MODEL setting does not exist. # Note that we don't perform this code in the compat module due to # bug report #1297 diff --git a/rest_framework/authtoken/serializers.py b/rest_framework/authtoken/serializers.py index 597aeed2..8a295c03 100644 --- a/rest_framework/authtoken/serializers.py +++ b/rest_framework/authtoken/serializers.py @@ -1,7 +1,7 @@ from django.contrib.auth import authenticate from django.utils.translation import ugettext_lazy as _ -from rest_framework import exceptions, serializers +from rest_framework import serializers class AuthTokenSerializer(serializers.Serializer): @@ -18,13 +18,13 @@ class AuthTokenSerializer(serializers.Serializer): if user: if not user.is_active: msg = _('User account is disabled.') - raise exceptions.ValidationError(msg) + raise serializers.ValidationError(msg) else: msg = _('Unable to log in with provided credentials.') - raise exceptions.ValidationError(msg) + raise serializers.ValidationError(msg) else: msg = _('Must include "username" and "password".') - raise exceptions.ValidationError(msg) + raise serializers.ValidationError(msg) attrs['user'] = user return attrs diff --git a/rest_framework/authtoken/south_migrations/0001_initial.py b/rest_framework/authtoken/south_migrations/0001_initial.py deleted file mode 100644 index 5b927f3e..00000000 --- a/rest_framework/authtoken/south_migrations/0001_initial.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -from south.db import db -from south.v2 import SchemaMigration - -try: - from django.contrib.auth import get_user_model -except ImportError: # django < 1.5 - from django.contrib.auth.models import User -else: - User = get_user_model() - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'Token' - db.create_table('authtoken_token', ( - ('key', self.gf('django.db.models.fields.CharField')(max_length=40, primary_key=True)), - ('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='auth_token', unique=True, to=orm['%s.%s' % (User._meta.app_label, User._meta.object_name)])), - ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - )) - db.send_create_signal('authtoken', ['Token']) - - def backwards(self, orm): - # Deleting model 'Token' - db.delete_table('authtoken_token') - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - "%s.%s" % (User._meta.app_label, User._meta.module_name): { - 'Meta': {'object_name': User._meta.module_name, 'db_table': repr(User._meta.db_table)}, - }, - 'authtoken.token': { - 'Meta': {'object_name': 'Token'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'auth_token'", 'unique': 'True', 'to': "orm['%s.%s']" % (User._meta.app_label, User._meta.object_name)}) - }, - 'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - } - } - - complete_apps = ['authtoken'] diff --git a/rest_framework/authtoken/views.py b/rest_framework/authtoken/views.py index 66bbc49b..0c6596a7 100644 --- a/rest_framework/authtoken/views.py +++ b/rest_framework/authtoken/views.py @@ -1,9 +1,8 @@ -from rest_framework.views import APIView -from rest_framework import parsers -from rest_framework import renderers -from rest_framework.response import Response +from rest_framework import parsers, renderers from rest_framework.authtoken.models import Token from rest_framework.authtoken.serializers import AuthTokenSerializer +from rest_framework.response import Response +from rest_framework.views import APIView class ObtainAuthToken(APIView): @@ -13,7 +12,7 @@ class ObtainAuthToken(APIView): renderer_classes = (renderers.JSONRenderer,) serializer_class = AuthTokenSerializer - def post(self, request): + def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 139d085d..de8e77ae 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -1,22 +1,23 @@ """ The `compat` module provides support for backwards compatibility with older -versions of django/python, and compatibility wrappers around optional packages. +versions of Django/Python, and compatibility wrappers around optional packages. """ # flake8: noqa from __future__ import unicode_literals -from django.core.exceptions import ImproperlyConfigured + +import django from django.conf import settings from django.db import connection, transaction -from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import urlparse as _urlparse +from django.template import Context, RequestContext, Template from django.utils import six -import django -import inspect +from django.views.generic import View + try: - import importlib + import importlib # Available in Python 3.1+ except ImportError: - from django.utils import importlib + from django.utils import importlib # Will be removed in Django 1.9 + def unicode_repr(instance): # Get the repr of an instance, but ensure it is a unicode string @@ -50,21 +51,11 @@ def total_seconds(timedelta): return (timedelta.days * 86400.0) + float(timedelta.seconds) + (timedelta.microseconds / 1000000.0) -# OrderedDict only available in Python 2.7. -# This will always be the case in Django 1.7 and above, as these versions -# no longer support Python 2.6. -# For Django <= 1.6 and Python 2.6 fall back to SortedDict. -try: - from collections import OrderedDict -except ImportError: - from django.utils.datastructures import SortedDict as OrderedDict - - -# HttpResponseBase only exists from 1.5 onwards -try: - from django.http.response import HttpResponseBase -except ImportError: - from django.http import HttpResponse as HttpResponseBase +def distinct(queryset, base): + if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": + # distinct analogue for Oracle users + return base.filter(pk__in=set(queryset.values_list('pk', flat=True))) + return queryset.distinct() # contrib.postgres only supported from 1.8 onwards. @@ -74,14 +65,11 @@ except ImportError: postgres_fields = None -# request only provides `resolver_match` from 1.5 onwards. -def get_resolver_match(request): - try: - return request.resolver_match - except AttributeError: - # Django < 1.5 - from django.core.urlresolvers import resolve - return resolve(request.path_info) +# JSONField is only supported from 1.9 onwards +try: + from django.contrib.postgres.fields import JSONField +except ImportError: + JSONField = None # django-filter is optional @@ -90,6 +78,14 @@ try: except ImportError: django_filters = None + +# django-crispy-forms is optional +try: + import crispy_forms +except ImportError: + crispy_forms = None + + if django.VERSION >= (1, 6): def clean_manytomany_helptext(text): return text @@ -101,42 +97,16 @@ else: text = text[:-69] return text + # Django-guardian is optional. Import only if guardian is in INSTALLED_APPS # Fixes (#1712). We keep the try/except for the test suite. guardian = None -if 'guardian' in settings.INSTALLED_APPS: - try: +try: + if 'guardian' in settings.INSTALLED_APPS: import guardian import guardian.shortcuts # Fixes #1624 - except ImportError: - pass - - -def get_model_name(model_cls): - try: - return model_cls._meta.model_name - except AttributeError: - # < 1.6 used module_name instead of model_name - return model_cls._meta.module_name - - -# Support custom user models in Django 1.5+ -try: - from django.contrib.auth import get_user_model except ImportError: - from django.contrib.auth.models import User - get_user_model = lambda: User - - -# View._allowed_methods only present from 1.5 onwards -if django.VERSION >= (1, 5): - from django.views.generic import View -else: - from django.views.generic import View as DjangoView - - class View(DjangoView): - def _allowed_methods(self): - return [m.upper() for m in self.http_method_names if hasattr(self, m)] + pass # MinValueValidator, MaxValueValidator et al. only accept `message` in 1.8+ @@ -149,92 +119,41 @@ else: from django.core.validators import MinLengthValidator as DjangoMinLengthValidator from django.core.validators import MaxLengthValidator as DjangoMaxLengthValidator + class MinValueValidator(DjangoMinValueValidator): def __init__(self, *args, **kwargs): self.message = kwargs.pop('message', self.message) super(MinValueValidator, self).__init__(*args, **kwargs) + class MaxValueValidator(DjangoMaxValueValidator): def __init__(self, *args, **kwargs): self.message = kwargs.pop('message', self.message) super(MaxValueValidator, self).__init__(*args, **kwargs) + class MinLengthValidator(DjangoMinLengthValidator): def __init__(self, *args, **kwargs): self.message = kwargs.pop('message', self.message) super(MinLengthValidator, self).__init__(*args, **kwargs) + class MaxLengthValidator(DjangoMaxLengthValidator): def __init__(self, *args, **kwargs): self.message = kwargs.pop('message', self.message) super(MaxLengthValidator, self).__init__(*args, **kwargs) -# URLValidator only accepts `message` in 1.6+ -if django.VERSION >= (1, 6): - from django.core.validators import URLValidator -else: - from django.core.validators import URLValidator as DjangoURLValidator - - class URLValidator(DjangoURLValidator): - def __init__(self, *args, **kwargs): - self.message = kwargs.pop('message', self.message) - super(URLValidator, self).__init__(*args, **kwargs) - - -# EmailValidator requires explicit regex prior to 1.6+ -if django.VERSION >= (1, 6): - from django.core.validators import EmailValidator -else: - from django.core.validators import EmailValidator as DjangoEmailValidator - from django.core.validators import email_re - - class EmailValidator(DjangoEmailValidator): - def __init__(self, *args, **kwargs): - super(EmailValidator, self).__init__(email_re, *args, **kwargs) - - # PATCH method is not implemented by Django if 'patch' not in View.http_method_names: View.http_method_names = View.http_method_names + ['patch'] -# RequestFactory only provides `generic` from 1.5 onwards -from django.test.client import RequestFactory as DjangoRequestFactory -from django.test.client import FakePayload - -try: - # In 1.5 the test client uses force_bytes - from django.utils.encoding import force_bytes as force_bytes_or_smart_bytes -except ImportError: - # In 1.4 the test client just uses smart_str - from django.utils.encoding import smart_str as force_bytes_or_smart_bytes - - -class RequestFactory(DjangoRequestFactory): - def generic(self, method, path, - data='', content_type='application/octet-stream', **extra): - parsed = _urlparse(path) - data = force_bytes_or_smart_bytes(data, settings.DEFAULT_CHARSET) - r = { - 'PATH_INFO': self._get_path(parsed), - 'QUERY_STRING': force_text(parsed[4]), - 'REQUEST_METHOD': six.text_type(method), - } - if data: - r.update({ - 'CONTENT_LENGTH': len(data), - 'CONTENT_TYPE': six.text_type(content_type), - 'wsgi.input': FakePayload(data), - }) - r.update(extra) - return self.request(**r) - - # Markdown is optional try: import markdown + def apply_markdown(text): """ Simple wrapper around :func:`markdown.markdown` to set the base level @@ -260,7 +179,6 @@ else: LONG_SEPARATORS = (b', ', b': ') INDENT_SEPARATORS = (b',', b': ') - if django.VERSION >= (1, 8): from django.db.models import DurationField from django.utils.dateparse import parse_duration @@ -268,13 +186,20 @@ if django.VERSION >= (1, 8): else: DurationField = duration_string = parse_duration = None +try: + # DecimalValidator is unavailable in Django < 1.9 + from django.core.validators import DecimalValidator +except ImportError: + DecimalValidator = None + def set_rollback(): if hasattr(transaction, 'set_rollback'): if connection.settings_dict.get('ATOMIC_REQUESTS', False): # If running in >=1.6 then mark a rollback as required, # and allow it to be handled by Django. - transaction.set_rollback(True) + if connection.in_atomic_block: + transaction.set_rollback(True) elif transaction.is_managed(): # Otherwise handle it explicitly if in managed mode. if transaction.is_dirty(): @@ -283,3 +208,54 @@ def set_rollback(): else: # transaction not managed pass + + +def template_render(template, context=None, request=None): + """ + Passing Context or RequestContext to Template.render is deprecated in 1.9+, + see https://github.com/django/django/pull/3883 and + https://github.com/django/django/blob/1.9rc1/django/template/backends/django.py#L82-L84 + + :param template: Template instance + :param context: dict + :param request: Request instance + :return: rendered template as SafeText instance + """ + if django.VERSION < (1, 8) or isinstance(template, Template): + if request: + context = RequestContext(request, context) + else: + context = Context(context) + return template.render(context) + # backends template, e.g. django.template.backends.django.Template + else: + return template.render(context, request=request) + + +def get_all_related_objects(opts): + """ + Django 1.8 changed meta api, see + https://docs.djangoproject.com/en/1.8/ref/models/meta/#migrating-old-meta-api + https://code.djangoproject.com/ticket/12663 + https://github.com/django/django/pull/3848 + + :param opts: Options instance + :return: list of relations except many-to-many ones + """ + if django.VERSION < (1, 9): + return opts.get_all_related_objects() + else: + return [r for r in opts.related_objects if not r.field.many_to_many] + + +def get_all_related_many_to_many_objects(opts): + """ + Django 1.8 changed meta api, see docstr in compat.get_all_related_objects() + + :param opts: Options instance + :return: list of many-to-many relations + """ + if django.VERSION < (1, 9): + return opts.get_all_related_many_to_many_objects() + else: + return [r for r in opts.related_objects if r.field.many_to_many] diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py index 21de1acf..4c8bda39 100644 --- a/rest_framework/decorators.py +++ b/rest_framework/decorators.py @@ -7,10 +7,13 @@ based views, as well as the `@detail_route` and `@list_route` decorators, which used to annotate methods on viewsets that should be included by routers. """ from __future__ import unicode_literals -from django.utils import six -from rest_framework.views import APIView + import types +from django.utils import six + +from rest_framework.views import APIView + def api_view(http_method_names=None): diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index f954c13e..8447a9de 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -5,11 +5,16 @@ In addition Django's built in 403 and 404 exceptions are handled. (`django.http.Http404` and `django.core.exceptions.PermissionDenied`) """ from __future__ import unicode_literals + +import math + from django.utils import six from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _, ungettext +from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ungettext + from rest_framework import status -import math +from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList def _force_text_recursive(data): @@ -18,14 +23,20 @@ def _force_text_recursive(data): lazy translation strings into plain text. """ if isinstance(data, list): - return [ + ret = [ _force_text_recursive(item) for item in data ] + if isinstance(data, ReturnList): + return ReturnList(ret, serializer=data.serializer) + return data elif isinstance(data, dict): - return dict([ - (key, _force_text_recursive(value)) + ret = { + key: _force_text_recursive(value) for key, value in data.items() - ]) + } + if isinstance(data, ReturnDict): + return ReturnDict(ret, serializer=data.serializer) + return data return force_text(data) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index d9322ec2..8541bc43 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1,30 +1,39 @@ from __future__ import unicode_literals -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist -from django.core.exceptions import ValidationError as DjangoValidationError -from django.core.validators import RegexValidator, ip_address_validators -from django.forms import ImageField as DjangoImageField -from django.utils import six, timezone -from django.utils.dateparse import parse_date, parse_datetime, parse_time -from django.utils.encoding import is_protected_type, smart_text -from django.utils.translation import ugettext_lazy as _ -from django.utils.ipv6 import clean_ipv6_address -from rest_framework import ISO_8601 -from rest_framework.compat import ( - EmailValidator, MinValueValidator, MaxValueValidator, - MinLengthValidator, MaxLengthValidator, URLValidator, OrderedDict, - unicode_repr, unicode_to_repr, parse_duration, duration_string, -) -from rest_framework.exceptions import ValidationError -from rest_framework.settings import api_settings -from rest_framework.utils import html, representation, humanize_datetime + import collections import copy import datetime import decimal import inspect +import json import re import uuid +from collections import OrderedDict + +from django.conf import settings +from django.core.exceptions import ValidationError as DjangoValidationError +from django.core.exceptions import ObjectDoesNotExist +from django.core.validators import ( + EmailValidator, RegexValidator, URLValidator, ip_address_validators +) +from django.forms import FilePathField as DjangoFilePathField +from django.forms import ImageField as DjangoImageField +from django.utils import six, timezone +from django.utils.dateparse import parse_date, parse_datetime, parse_time +from django.utils.encoding import is_protected_type, smart_text +from django.utils.functional import cached_property +from django.utils.ipv6 import clean_ipv6_address +from django.utils.translation import ugettext_lazy as _ + +from rest_framework import ISO_8601 +from rest_framework.compat import ( + MaxLengthValidator, MaxValueValidator, MinLengthValidator, + MinValueValidator, duration_string, parse_duration, unicode_repr, + unicode_to_repr +) +from rest_framework.exceptions import ValidationError +from rest_framework.settings import api_settings +from rest_framework.utils import html, humanize_datetime, representation class empty: @@ -104,6 +113,100 @@ def set_value(dictionary, keys, value): dictionary[keys[-1]] = value +def to_choices_dict(choices): + """ + Convert choices into key/value dicts. + + pairwise_choices([1]) -> {1: 1} + pairwise_choices([(1, '1st'), (2, '2nd')]) -> {1: '1st', 2: '2nd'} + pairwise_choices([('Group', ((1, '1st'), 2))]) -> {'Group': {1: '1st', 2: '2nd'}} + """ + # Allow single, paired or grouped choices style: + # choices = [1, 2, 3] + # choices = [(1, 'First'), (2, 'Second'), (3, 'Third')] + # choices = [('Category', ((1, 'First'), (2, 'Second'))), (3, 'Third')] + ret = OrderedDict() + for choice in choices: + if (not isinstance(choice, (list, tuple))): + # single choice + ret[choice] = choice + else: + key, value = choice + if isinstance(value, (list, tuple)): + # grouped choices (category, sub choices) + ret[key] = to_choices_dict(value) + else: + # paired choice (key, display value) + ret[key] = value + return ret + + +def flatten_choices_dict(choices): + """ + Convert a group choices dict into a flat dict of choices. + + flatten_choices({1: '1st', 2: '2nd'}) -> {1: '1st', 2: '2nd'} + flatten_choices({'Group': {1: '1st', 2: '2nd'}}) -> {1: '1st', 2: '2nd'} + """ + ret = OrderedDict() + for key, value in choices.items(): + if isinstance(value, dict): + # grouped choices (category, sub choices) + for sub_key, sub_value in value.items(): + ret[sub_key] = sub_value + else: + # choice (key, display value) + ret[key] = value + return ret + + +def iter_options(grouped_choices, cutoff=None, cutoff_text=None): + """ + Helper function for options and option groups in templates. + """ + class StartOptionGroup(object): + start_option_group = True + end_option_group = False + + def __init__(self, label): + self.label = label + + class EndOptionGroup(object): + start_option_group = False + end_option_group = True + + class Option(object): + start_option_group = False + end_option_group = False + + def __init__(self, value, display_text, disabled=False): + self.value = value + self.display_text = display_text + self.disabled = disabled + + count = 0 + + for key, value in grouped_choices.items(): + if cutoff and count >= cutoff: + break + + if isinstance(value, dict): + yield StartOptionGroup(label=key) + for sub_key, sub_value in value.items(): + if cutoff and count >= cutoff: + break + yield Option(value=sub_key, display_text=sub_value) + count += 1 + yield EndOptionGroup() + else: + yield Option(value=key, display_text=value) + count += 1 + + if cutoff and count >= cutoff and cutoff_text: + cutoff_text = cutoff_text.format(count=cutoff) + yield Option(value='n/a', display_text=cutoff_text, disabled=True) + + class CreateOnlyDefault(object): """ This class may be used to provide default values that are only used @@ -196,9 +299,7 @@ class Field(object): self.allow_null = allow_null if self.default_empty_html is not empty: - if not required: - self.default_empty_html = empty - elif default is not empty: + if default is not empty: self.default_empty_html = default if validators is not None: @@ -288,6 +389,10 @@ class Field(object): # If the field is blank, and null is a valid value then # determine if we should use null instead. return '' if getattr(self, 'allow_blank', False) else None + elif ret == '' and not self.required: + # If the field is blank, and emptyness is valid then + # determine if we should use emptyness instead. + return '' if getattr(self, 'allow_blank', False) else empty return ret return dictionary.get(self.field_name, empty) @@ -417,10 +522,11 @@ class Field(object): Transform the *outgoing* native value into primitive data. """ raise NotImplementedError( - '{cls}.to_representation() must be implemented.\n' - 'If you are upgrading from REST framework version 2 ' - 'you might want `ReadOnlyField`.'.format( - cls=self.__class__.__name__ + '{cls}.to_representation() must be implemented for field ' + '{field_name}. If you do not need to support write operations ' + 'you probably want to subclass `ReadOnlyField` instead.'.format( + cls=self.__class__.__name__, + field_name=self.field_name, ) ) @@ -437,7 +543,7 @@ class Field(object): message_string = msg.format(**kwargs) raise ValidationError(message_string) - @property + @cached_property def root(self): """ Returns the top-level serializer for this field. @@ -447,7 +553,7 @@ class Field(object): root = root.parent return root - @property + @cached_property def context(self): """ Returns the context as passed to the root serializer on initialization. @@ -498,18 +604,21 @@ class BooleanField(Field): } default_empty_html = False initial = False - TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True)) - FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False)) + TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True} + FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False} def __init__(self, **kwargs): assert 'allow_null' not in kwargs, '`allow_null` is not a valid option. Use `NullBooleanField` instead.' super(BooleanField, self).__init__(**kwargs) def to_internal_value(self, data): - if data in self.TRUE_VALUES: - return True - elif data in self.FALSE_VALUES: - return False + try: + if data in self.TRUE_VALUES: + return True + elif data in self.FALSE_VALUES: + return False + except TypeError: # Input is an unhashable type + pass self.fail('invalid', input=data) def to_representation(self, value): @@ -525,9 +634,9 @@ class NullBooleanField(Field): 'invalid': _('"{input}" is not a valid boolean.') } initial = None - TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True)) - FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False)) - NULL_VALUES = set(('n', 'N', 'null', 'Null', 'NULL', '', None)) + TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True} + FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False} + NULL_VALUES = {'n', 'N', 'null', 'Null', 'NULL', '', None} def __init__(self, **kwargs): assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.' @@ -580,7 +689,7 @@ class CharField(Field): # Test for the empty string here so that it does not get validated, # and so that subclasses do not need to handle it explicitly # inside the `to_internal_value()` method. - if data == '': + if data == '' or (self.trim_whitespace and six.text_type(data).strip() == ''): if not self.allow_blank: self.fail('blank') return '' @@ -660,9 +769,11 @@ class UUIDField(Field): try: if isinstance(data, six.integer_types): return uuid.UUID(int=data) - else: + elif isinstance(data, six.string_types): return uuid.UUID(hex=data) - except (ValueError, TypeError): + else: + self.fail('invalid', value=data) + except (ValueError): self.fail('invalid', value=data) return data @@ -780,16 +891,20 @@ class DecimalField(Field): } MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs. - coerce_to_string = api_settings.COERCE_DECIMAL_TO_STRING - def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None, **kwargs): self.max_digits = max_digits self.decimal_places = decimal_places - self.coerce_to_string = coerce_to_string if (coerce_to_string is not None) else self.coerce_to_string + if coerce_to_string is not None: + self.coerce_to_string = coerce_to_string self.max_value = max_value self.min_value = min_value + if self.max_digits is not None and self.decimal_places is not None: + self.max_whole_digits = self.max_digits - self.decimal_places + else: + self.max_whole_digits = None + super(DecimalField, self).__init__(**kwargs) if self.max_value is not None: @@ -833,34 +948,41 @@ class DecimalField(Field): values or to enhance it in any way you need to. """ sign, digittuple, exponent = value.as_tuple() - decimals = exponent * decimal.Decimal(-1) if exponent < 0 else 0 - # digittuple doesn't include any leading zeros. - digits = len(digittuple) - if decimals > digits: - # We have leading zeros up to or past the decimal point. Count - # everything past the decimal point as a digit. We do not count - # 0 before the decimal point as a digit since that would mean - # we would not allow max_digits = decimal_places. - digits = decimals - whole_digits = digits - decimals + if exponent >= 0: + # 1234500.0 + total_digits = len(digittuple) + exponent + whole_digits = total_digits + decimal_places = 0 + elif len(digittuple) > abs(exponent): + # 123.45 + total_digits = len(digittuple) + whole_digits = total_digits - abs(exponent) + decimal_places = abs(exponent) + else: + # 0.001234 + total_digits = abs(exponent) + whole_digits = 0 + decimal_places = total_digits - if self.max_digits is not None and digits > self.max_digits: + if self.max_digits is not None and total_digits > self.max_digits: self.fail('max_digits', max_digits=self.max_digits) - if self.decimal_places is not None and decimals > self.decimal_places: + if self.decimal_places is not None and decimal_places > self.decimal_places: self.fail('max_decimal_places', max_decimal_places=self.decimal_places) - if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): - self.fail('max_whole_digits', max_whole_digits=self.max_digits - self.decimal_places) + if self.max_whole_digits is not None and whole_digits > self.max_whole_digits: + self.fail('max_whole_digits', max_whole_digits=self.max_whole_digits) return value def to_representation(self, value): + coerce_to_string = getattr(self, 'coerce_to_string', api_settings.COERCE_DECIMAL_TO_STRING) + if not isinstance(value, decimal.Decimal): value = decimal.Decimal(six.text_type(value).strip()) quantized = self.quantize(value) - if not self.coerce_to_string: + if not coerce_to_string: return quantized return '{0:f}'.format(quantized) @@ -882,14 +1004,15 @@ class DateTimeField(Field): 'invalid': _('Datetime has wrong format. Use one of these formats instead: {format}.'), 'date': _('Expected a datetime but got a date.'), } - format = api_settings.DATETIME_FORMAT - input_formats = api_settings.DATETIME_INPUT_FORMATS - default_timezone = timezone.get_default_timezone() if settings.USE_TZ else None + datetime_parser = datetime.datetime.strptime def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, **kwargs): - self.format = format if format is not empty else self.format - self.input_formats = input_formats if input_formats is not None else self.input_formats - self.default_timezone = default_timezone if default_timezone is not None else self.default_timezone + if format is not empty: + self.format = format + if input_formats is not None: + self.input_formats = input_formats + if default_timezone is not None: + self.timezone = default_timezone super(DateTimeField, self).__init__(*args, **kwargs) def enforce_timezone(self, value): @@ -897,21 +1020,28 @@ class DateTimeField(Field): When `self.default_timezone` is `None`, always return naive datetimes. When `self.default_timezone` is not `None`, always return aware datetimes. """ - if (self.default_timezone is not None) and not timezone.is_aware(value): - return timezone.make_aware(value, self.default_timezone) - elif (self.default_timezone is None) and timezone.is_aware(value): + field_timezone = getattr(self, 'timezone', self.default_timezone()) + + if (field_timezone is not None) and not timezone.is_aware(value): + return timezone.make_aware(value, field_timezone) + elif (field_timezone is None) and timezone.is_aware(value): return timezone.make_naive(value, timezone.UTC()) return value + def default_timezone(self): + return timezone.get_default_timezone() if settings.USE_TZ else None + def to_internal_value(self, value): + input_formats = getattr(self, 'input_formats', api_settings.DATETIME_INPUT_FORMATS) + if isinstance(value, datetime.date) and not isinstance(value, datetime.datetime): self.fail('date') if isinstance(value, datetime.datetime): return self.enforce_timezone(value) - for format in self.input_formats: - if format.lower() == ISO_8601: + for input_format in input_formats: + if input_format.lower() == ISO_8601: try: parsed = parse_datetime(value) except (ValueError, TypeError): @@ -921,25 +1051,27 @@ class DateTimeField(Field): return self.enforce_timezone(parsed) else: try: - parsed = datetime.datetime.strptime(value, format) + parsed = self.datetime_parser(value, input_format) except (ValueError, TypeError): pass else: return self.enforce_timezone(parsed) - humanized_format = humanize_datetime.datetime_formats(self.input_formats) + humanized_format = humanize_datetime.datetime_formats(input_formats) self.fail('invalid', format=humanized_format) def to_representation(self, value): - if self.format is None: + output_format = getattr(self, 'format', api_settings.DATETIME_FORMAT) + + if output_format is None: return value - if self.format.lower() == ISO_8601: + if output_format.lower() == ISO_8601: value = value.isoformat() if value.endswith('+00:00'): value = value[:-6] + 'Z' return value - return value.strftime(self.format) + return value.strftime(output_format) class DateField(Field): @@ -947,23 +1079,26 @@ class DateField(Field): 'invalid': _('Date has wrong format. Use one of these formats instead: {format}.'), 'datetime': _('Expected a date but got a datetime.'), } - format = api_settings.DATE_FORMAT - input_formats = api_settings.DATE_INPUT_FORMATS + datetime_parser = datetime.datetime.strptime def __init__(self, format=empty, input_formats=None, *args, **kwargs): - self.format = format if format is not empty else self.format - self.input_formats = input_formats if input_formats is not None else self.input_formats + if format is not empty: + self.format = format + if input_formats is not None: + self.input_formats = input_formats super(DateField, self).__init__(*args, **kwargs) def to_internal_value(self, value): + input_formats = getattr(self, 'input_formats', api_settings.DATE_INPUT_FORMATS) + if isinstance(value, datetime.datetime): self.fail('datetime') if isinstance(value, datetime.date): return value - for format in self.input_formats: - if format.lower() == ISO_8601: + for input_format in input_formats: + if input_format.lower() == ISO_8601: try: parsed = parse_date(value) except (ValueError, TypeError): @@ -973,20 +1108,22 @@ class DateField(Field): return parsed else: try: - parsed = datetime.datetime.strptime(value, format) + parsed = self.datetime_parser(value, input_format) except (ValueError, TypeError): pass else: return parsed.date() - humanized_format = humanize_datetime.date_formats(self.input_formats) + humanized_format = humanize_datetime.date_formats(input_formats) self.fail('invalid', format=humanized_format) def to_representation(self, value): + output_format = getattr(self, 'format', api_settings.DATE_FORMAT) + if not value: return None - if self.format is None: + if output_format is None: return value # Applying a `DateField` to a datetime value is almost always @@ -998,32 +1135,35 @@ class DateField(Field): 'read-only field and deal with timezone issues explicitly.' ) - if self.format.lower() == ISO_8601: + if output_format.lower() == ISO_8601: if (isinstance(value, str)): value = datetime.datetime.strptime(value, '%Y-%m-%d').date() return value.isoformat() - return value.strftime(self.format) + return value.strftime(output_format) class TimeField(Field): default_error_messages = { 'invalid': _('Time has wrong format. Use one of these formats instead: {format}.'), } - format = api_settings.TIME_FORMAT - input_formats = api_settings.TIME_INPUT_FORMATS + datetime_parser = datetime.datetime.strptime def __init__(self, format=empty, input_formats=None, *args, **kwargs): - self.format = format if format is not empty else self.format - self.input_formats = input_formats if input_formats is not None else self.input_formats + if format is not empty: + self.format = format + if input_formats is not None: + self.input_formats = input_formats super(TimeField, self).__init__(*args, **kwargs) def to_internal_value(self, value): + input_formats = getattr(self, 'input_formats', api_settings.TIME_INPUT_FORMATS) + if isinstance(value, datetime.time): return value - for format in self.input_formats: - if format.lower() == ISO_8601: + for input_format in input_formats: + if input_format.lower() == ISO_8601: try: parsed = parse_time(value) except (ValueError, TypeError): @@ -1033,17 +1173,19 @@ class TimeField(Field): return parsed else: try: - parsed = datetime.datetime.strptime(value, format) + parsed = self.datetime_parser(value, input_format) except (ValueError, TypeError): pass else: return parsed.time() - humanized_format = humanize_datetime.time_formats(self.input_formats) + humanized_format = humanize_datetime.time_formats(input_formats) self.fail('invalid', format=humanized_format) def to_representation(self, value): - if self.format is None: + output_format = getattr(self, 'format', api_settings.TIME_FORMAT) + + if output_format is None: return value # Applying a `TimeField` to a datetime value is almost always @@ -1055,9 +1197,9 @@ class TimeField(Field): 'read-only field and deal with timezone issues explicitly.' ) - if self.format.lower() == ISO_8601: + if output_format.lower() == ISO_8601: return value.isoformat() - return value.strftime(self.format) + return value.strftime(output_format) class DurationField(Field): @@ -1074,7 +1216,7 @@ class DurationField(Field): def to_internal_value(self, value): if isinstance(value, datetime.timedelta): return value - parsed = parse_duration(value) + parsed = parse_duration(six.text_type(value)) if parsed is not None: return parsed self.fail('invalid', format='[DD] [HH:[MM:]]ss[.uuuuuu]') @@ -1089,26 +1231,21 @@ class ChoiceField(Field): default_error_messages = { 'invalid_choice': _('"{input}" is not a valid choice.') } + html_cutoff = None + html_cutoff_text = _('More than {count} items...') def __init__(self, choices, **kwargs): - # Allow either single or paired choices style: - # choices = [1, 2, 3] - # choices = [(1, 'First'), (2, 'Second'), (3, 'Third')] - pairs = [ - isinstance(item, (list, tuple)) and len(item) == 2 - for item in choices - ] - if all(pairs): - self.choices = OrderedDict([(key, display_value) for key, display_value in choices]) - else: - self.choices = OrderedDict([(item, item) for item in choices]) + self.grouped_choices = to_choices_dict(choices) + self.choices = flatten_choices_dict(self.grouped_choices) + self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff) + self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text) # Map the string representation of choices to the underlying value. # Allows us to deal with eg. integer choices while supporting either # integer or string input, but still get the correct datatype out. - self.choice_strings_to_values = dict([ - (six.text_type(key), key) for key in self.choices.keys() - ]) + self.choice_strings_to_values = { + six.text_type(key): key for key in self.choices.keys() + } self.allow_blank = kwargs.pop('allow_blank', False) @@ -1128,38 +1265,71 @@ class ChoiceField(Field): return value return self.choice_strings_to_values.get(six.text_type(value), value) + def iter_options(self): + """ + Helper method for use with templates rendering select widgets. + """ + return iter_options( + self.grouped_choices, + cutoff=self.html_cutoff, + cutoff_text=self.html_cutoff_text + ) + class MultipleChoiceField(ChoiceField): default_error_messages = { 'invalid_choice': _('"{input}" is not a valid choice.'), - 'not_a_list': _('Expected a list of items but got type "{input_type}".') + 'not_a_list': _('Expected a list of items but got type "{input_type}".'), + 'empty': _('This selection may not be empty.') } default_empty_html = [] + def __init__(self, *args, **kwargs): + self.allow_empty = kwargs.pop('allow_empty', True) + super(MultipleChoiceField, self).__init__(*args, **kwargs) + def get_value(self, dictionary): + if self.field_name not in dictionary: + if getattr(self.root, 'partial', False): + return empty # We override the default field access in order to support # lists in HTML forms. if html.is_html_input(dictionary): - ret = dictionary.getlist(self.field_name) - if getattr(self.root, 'partial', False) and not ret: - ret = empty - return ret - + return dictionary.getlist(self.field_name) return dictionary.get(self.field_name, empty) def to_internal_value(self, data): if isinstance(data, type('')) or not hasattr(data, '__iter__'): self.fail('not_a_list', input_type=type(data).__name__) + if not self.allow_empty and len(data) == 0: + self.fail('empty') - return set([ + return { super(MultipleChoiceField, self).to_internal_value(item) for item in data - ]) + } def to_representation(self, value): - return set([ + return { self.choice_strings_to_values.get(six.text_type(item), item) for item in value - ]) + } + + +class FilePathField(ChoiceField): + default_error_messages = { + 'invalid_choice': _('"{input}" is not a valid path choice.') + } + + def __init__(self, path, match=None, recursive=False, allow_files=True, + allow_folders=False, required=None, **kwargs): + # Defer to Django's FilePathField implmentation to get the + # valid set of choices. + field = DjangoFilePathField( + path, match=match, recursive=recursive, allow_files=allow_files, + allow_folders=allow_folders, required=required + ) + kwargs['choices'] = field.choices + super(FilePathField, self).__init__(**kwargs) # File types... @@ -1172,12 +1342,12 @@ class FileField(Field): 'empty': _('The submitted file is empty.'), 'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'), } - use_url = api_settings.UPLOADED_FILES_USE_URL def __init__(self, *args, **kwargs): self.max_length = kwargs.pop('max_length', None) self.allow_empty_file = kwargs.pop('allow_empty_file', False) - self.use_url = kwargs.pop('use_url', self.use_url) + if 'use_url' in kwargs: + self.use_url = kwargs.pop('use_url') super(FileField, self).__init__(*args, **kwargs) def to_internal_value(self, data): @@ -1198,8 +1368,14 @@ class FileField(Field): return data def to_representation(self, value): - if self.use_url: - if not value: + use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL) + + if not value: + return None + + if use_url: + if not getattr(value, 'url', None): + # If the file has not been saved it may not have a URL. return None url = value.url request = self.context.get('request', None) @@ -1250,19 +1426,34 @@ class ListField(Field): child = _UnvalidatedField() initial = [] default_error_messages = { - 'not_a_list': _('Expected a list of items but got type "{input_type}".') + 'not_a_list': _('Expected a list of items but got type "{input_type}".'), + 'empty': _('This list may not be empty.') } def __init__(self, *args, **kwargs): self.child = kwargs.pop('child', copy.deepcopy(self.child)) + self.allow_empty = kwargs.pop('allow_empty', True) + assert not inspect.isclass(self.child), '`child` has not been instantiated.' + assert self.child.source is None, ( + "The `source` argument is not meaningful when applied to a `child=` field. " + "Remove `source=` from the field declaration." + ) + super(ListField, self).__init__(*args, **kwargs) self.child.bind(field_name='', parent=self) def get_value(self, dictionary): + if self.field_name not in dictionary: + if getattr(self.root, 'partial', False): + return empty # We override the default field access in order to support # lists in HTML forms. if html.is_html_input(dictionary): + val = dictionary.getlist(self.field_name, []) + if len(val) > 0: + # Support QueryDict lists in HTML input. + return val return html.parse_html_list(dictionary, prefix=self.field_name) return dictionary.get(self.field_name, empty) @@ -1272,8 +1463,10 @@ class ListField(Field): """ if html.is_html_input(data): data = html.parse_html_list(data) - if isinstance(data, type('')) or not hasattr(data, '__iter__'): + if isinstance(data, type('')) or isinstance(data, collections.Mapping) or not hasattr(data, '__iter__'): self.fail('not_a_list', input_type=type(data).__name__) + if not self.allow_empty and len(data) == 0: + self.fail('empty') return [self.child.run_validation(item) for item in data] def to_representation(self, data): @@ -1292,7 +1485,13 @@ class DictField(Field): def __init__(self, *args, **kwargs): self.child = kwargs.pop('child', copy.deepcopy(self.child)) + assert not inspect.isclass(self.child), '`child` has not been instantiated.' + assert self.child.source is None, ( + "The `source` argument is not meaningful when applied to a `child=` field. " + "Remove `source=` from the field declaration." + ) + super(DictField, self).__init__(*args, **kwargs) self.child.bind(field_name='', parent=self) @@ -1311,19 +1510,50 @@ class DictField(Field): data = html.parse_html_dict(data) if not isinstance(data, dict): self.fail('not_a_dict', input_type=type(data).__name__) - return dict([ - (six.text_type(key), self.child.run_validation(value)) + return { + six.text_type(key): self.child.run_validation(value) for key, value in data.items() - ]) + } def to_representation(self, value): """ List of object instances -> List of dicts of primitive datatypes. """ - return dict([ - (six.text_type(key), self.child.to_representation(val)) + return { + six.text_type(key): self.child.to_representation(val) for key, val in value.items() - ]) + } + + +class JSONField(Field): + default_error_messages = { + 'invalid': _('Value must be valid JSON.') + } + + def __init__(self, *args, **kwargs): + self.binary = kwargs.pop('binary', False) + super(JSONField, self).__init__(*args, **kwargs) + + def to_internal_value(self, data): + try: + if self.binary: + if isinstance(data, six.binary_type): + data = data.decode('utf-8') + return json.loads(data) + else: + json.dumps(data) + except (TypeError, ValueError): + self.fail('invalid') + return data + + def to_representation(self, value): + if self.binary: + value = json.dumps(value) + # On python 2.x the return type for json.dumps() is underspecified. + # On python 3.x json.dumps() returns unicode strings. + if isinstance(value, six.text_type): + value = bytes(value.encode('utf-8')) + return value # Miscellaneous field types... @@ -1337,7 +1567,7 @@ class ReadOnlyField(Field): For example, the following would call `get_expiry_date()` on the object: - class ExampleSerializer(self): + class ExampleSerializer(Serializer): expiry_date = ReadOnlyField(source='get_expiry_date') """ diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 9a84efa2..ff541ba1 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -4,15 +4,60 @@ returned by list views. """ from __future__ import unicode_literals +import operator +from functools import reduce + +from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import models +from django.template import loader from django.utils import six -from rest_framework.compat import django_filters, guardian, get_model_name -from rest_framework.settings import api_settings -from functools import reduce -import operator +from django.utils.translation import ugettext_lazy as _ -FilterSet = django_filters and django_filters.FilterSet or None +from rest_framework.compat import ( + crispy_forms, distinct, django_filters, guardian, template_render +) +from rest_framework.settings import api_settings + +if 'crispy_forms' in settings.INSTALLED_APPS and crispy_forms and django_filters: + # If django-crispy-forms is installed, use it to get a bootstrap3 rendering + # of the DjangoFilterBackend controls when displayed as HTML. + from crispy_forms.helper import FormHelper + from crispy_forms.layout import Layout, Submit + + class FilterSet(django_filters.FilterSet): + def __init__(self, *args, **kwargs): + super(FilterSet, self).__init__(*args, **kwargs) + for field in self.form.fields.values(): + field.help_text = None + + layout_components = list(self.form.fields.keys()) + [ + Submit('', _('Submit'), css_class='btn-default'), + ] + + helper = FormHelper() + helper.form_method = 'GET' + helper.template_pack = 'bootstrap3' + helper.layout = Layout(*layout_components) + + self.form.helper = helper + + filter_template = 'rest_framework/filters/django_filter_crispyforms.html' + +elif django_filters: + # If django-crispy-forms is not installed, use the standard + # 'form.as_p' rendering when DjangoFilterBackend is displayed as HTML. + class FilterSet(django_filters.FilterSet): + def __init__(self, *args, **kwargs): + super(FilterSet, self).__init__(*args, **kwargs) + for field in self.form.fields.values(): + field.help_text = None + + filter_template = 'rest_framework/filters/django_filter.html' + +else: + FilterSet = None + filter_template = None class BaseFilterBackend(object): @@ -32,6 +77,7 @@ class DjangoFilterBackend(BaseFilterBackend): A filter backend that uses django-filter. """ default_filter_set = FilterSet + template = filter_template def __init__(self): assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed' @@ -53,10 +99,11 @@ class DjangoFilterBackend(BaseFilterBackend): return filter_class if filter_fields: - class AutoFilterSet(self.default_filter_set): + class AutoFilterSet(FilterSet): class Meta: model = queryset.model fields = filter_fields + return AutoFilterSet return None @@ -69,10 +116,22 @@ class DjangoFilterBackend(BaseFilterBackend): return queryset + def to_html(self, request, queryset, view): + filter_class = self.get_filter_class(view, queryset) + if not filter_class: + return None + filter_instance = filter_class(request.query_params, queryset=queryset) + context = { + 'filter': filter_instance + } + template = loader.get_template(self.template) + return template_render(template, context) + class SearchFilter(BaseFilterBackend): # The URL query parameter used for the search. search_param = api_settings.SEARCH_PARAM + template = 'rest_framework/filters/search.html' def get_search_terms(self, request): """ @@ -89,30 +148,55 @@ class SearchFilter(BaseFilterBackend): return "%s__iexact" % field_name[1:] elif field_name.startswith('@'): return "%s__search" % field_name[1:] + if field_name.startswith('$'): + return "%s__iregex" % field_name[1:] else: return "%s__icontains" % field_name def filter_queryset(self, request, queryset, view): search_fields = getattr(view, 'search_fields', None) + search_terms = self.get_search_terms(request) - if not search_fields: + if not search_fields or not search_terms: return queryset - orm_lookups = [self.construct_search(six.text_type(search_field)) - for search_field in search_fields] + orm_lookups = [ + self.construct_search(six.text_type(search_field)) + for search_field in search_fields + ] - for search_term in self.get_search_terms(request): - or_queries = [models.Q(**{orm_lookup: search_term}) - for orm_lookup in orm_lookups] - queryset = queryset.filter(reduce(operator.or_, or_queries)).distinct() + base = queryset + for search_term in search_terms: + queries = [ + models.Q(**{orm_lookup: search_term}) + for orm_lookup in orm_lookups + ] + queryset = queryset.filter(reduce(operator.or_, queries)) - return queryset + # Filtering against a many-to-many field requires us to + # call queryset.distinct() in order to avoid duplicate items + # in the resulting queryset. + return distinct(queryset, base) + + def to_html(self, request, queryset, view): + if not getattr(view, 'search_fields', None): + return '' + + term = self.get_search_terms(request) + term = term[0] if term else '' + context = { + 'param': self.search_param, + 'term': term + } + template = loader.get_template(self.template) + return template_render(template, context) class OrderingFilter(BaseFilterBackend): # The URL query parameter used for the ordering. ordering_param = api_settings.ORDERING_PARAM ordering_fields = None + template = 'rest_framework/filters/ordering.html' def get_ordering(self, request, queryset, view): """ @@ -138,7 +222,7 @@ class OrderingFilter(BaseFilterBackend): return (ordering,) return ordering - def remove_invalid_fields(self, queryset, fields, view): + def get_valid_fields(self, queryset, view): valid_fields = getattr(view, 'ordering_fields', self.ordering_fields) if valid_fields is None: @@ -149,15 +233,30 @@ class OrderingFilter(BaseFilterBackend): "'serializer_class' or 'ordering_fields' attribute.") raise ImproperlyConfigured(msg % self.__class__.__name__) valid_fields = [ - field.source or field_name + (field.source or field_name, field.label) for field_name, field in serializer_class().fields.items() - if not getattr(field, 'write_only', False) + if not getattr(field, 'write_only', False) and not field.source == '*' ] elif valid_fields == '__all__': # View explicitly allows filtering on any model field - valid_fields = [field.name for field in queryset.model._meta.fields] - valid_fields += queryset.query.aggregates.keys() + valid_fields = [ + (field.name, getattr(field, 'label', field.name.title())) + for field in queryset.model._meta.fields + ] + valid_fields += [ + (key, key.title().split('__')) + for key in queryset.query.aggregates.keys() + ] + else: + valid_fields = [ + (item, item) if isinstance(item, six.string_types) else item + for item in valid_fields + ] + return valid_fields + + def remove_invalid_fields(self, queryset, fields, view): + valid_fields = [item[0] for item in self.get_valid_fields(queryset, view)] return [term for term in fields if term.lstrip('-') in valid_fields] def filter_queryset(self, request, queryset, view): @@ -168,6 +267,25 @@ class OrderingFilter(BaseFilterBackend): return queryset + def get_template_context(self, request, queryset, view): + current = self.get_ordering(request, queryset, view) + current = None if current is None else current[0] + options = [] + for key, label in self.get_valid_fields(queryset, view): + options.append((key, '%s - ascending' % label)) + options.append(('-' + key, '%s - descending' % label)) + return { + 'request': request, + 'current': current, + 'param': self.ordering_param, + 'options': options, + } + + def to_html(self, request, queryset, view): + template = loader.get_template(self.template) + context = self.get_template_context(request, queryset, view) + return template_render(template, context) + class DjangoObjectPermissionsFilter(BaseFilterBackend): """ @@ -180,11 +298,17 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend): perm_format = '%(app_label)s.view_%(model_name)s' def filter_queryset(self, request, queryset, view): + extra = {} user = request.user model_cls = queryset.model kwargs = { 'app_label': model_cls._meta.app_label, - 'model_name': get_model_name(model_cls) + 'model_name': model_cls._meta.model_name } permission = self.perm_format % kwargs - return guardian.shortcuts.get_objects_for_user(user, permission, queryset) + if guardian.VERSION >= (1, 3): + # Maintain behavior compatibility with versions prior to 1.3 + extra = {'accept_global_perms': False} + else: + extra = {} + return guardian.shortcuts.get_objects_for_user(user, permission, queryset, **extra) diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 61dcb84a..88438e8c 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -2,10 +2,12 @@ Generic views that provide commonly needed behaviour. """ from __future__ import unicode_literals + from django.db.models.query import QuerySet from django.http import Http404 from django.shortcuts import get_object_or_404 as _get_object_or_404 -from rest_framework import views, mixins + +from rest_framework import mixins, views from rest_framework.settings import api_settings diff --git a/rest_framework/locale/ach/LC_MESSAGES/django.mo b/rest_framework/locale/ach/LC_MESSAGES/django.mo new file mode 100644 index 00000000..a1e8e6bc Binary files /dev/null and b/rest_framework/locale/ach/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ach/LC_MESSAGES/django.po b/rest_framework/locale/ach/LC_MESSAGES/django.po new file mode 100644 index 00000000..0a6f2cce --- /dev/null +++ b/rest_framework/locale/ach/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Acoli (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ach/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ach\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/ar/LC_MESSAGES/django.mo b/rest_framework/locale/ar/LC_MESSAGES/django.mo index 8b2d94fa..6a32487e 100644 Binary files a/rest_framework/locale/ar/LC_MESSAGES/django.mo and b/rest_framework/locale/ar/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ar/LC_MESSAGES/django.po b/rest_framework/locale/ar/LC_MESSAGES/django.po index b264bc58..4dbeed9b 100644 --- a/rest_framework/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework/locale/ar/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Arabic (http://www.transifex.com/projects/p/django-rest-framework/language/ar/)\n" +"Language-Team: Arabic (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "اسم المستخدم/كلمة السر غير صحيحين." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "المستخدم غير مفعل او تم حذفه." @@ -46,7 +46,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -62,261 +67,309 @@ msgstr "تعذر تسجيل الدخول بالبيانات التي ادخلت msgid "Must include \"username\" and \"password\"." msgstr "يجب أن تتضمن \"اسم المستخدم\" و \"كلمة المرور\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "حدث خطأ في المخدم." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "بيانات الدخول غير صحيحة." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "لم يتم تزويد بيانات الدخول." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "ليس لديك صلاحية للقيام بهذا الإجراء." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "غير موجود." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "هذا الحقل مطلوب." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "لا يمكن لهذا الحقل ان يكون فارغاً null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" ليس قيمة منطقية." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "لا يمكن لهذا الحقل ان يكون فارغاً." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "تأكد ان الحقل لا يزيد عن {max_length} محرف." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "تأكد ان الحقل {min_length} محرف على الاقل." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "عليك ان تدخل بريد إلكتروني صالح." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "هذه القيمة لا تطابق النمط المطلوب." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "الرجاء إدخال رابط إلكتروني صالح." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "الرجاء إدخال رقم صحيح صالح." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "تأكد ان القيمة أقل أو تساوي {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "تأكد ان القيمة أكبر أو تساوي {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "الرجاء إدخال رقم صالح." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "تأكد ان القيمة لا تحوي أكثر من {max_digits} رقم." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "صيغة التاريخ و الوقت غير صحيحة. عليك أن تستخدم واحدة من هذه الصيغ التالية: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "صيغة التاريخ غير صحيحة. عليك أن تستخدم واحدة من هذه الصيغ التالية: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "صيغة الوقت غير صحيحة. عليك أن تستخدم واحدة من هذه الصيغ التالية: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" ليست واحدة من الخيارات الصالحة." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "لم يتم إرسال أي ملف." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "الملف الذي تم إرساله فارغ." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "تأكد ان اسم الملف لا يحوي أكثر من {max_length} محرف (الإسم المرسل يحوي {length} محرف)." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "رقم الصفحة \"{page_number}\" غير صالح : {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "معرف العنصر \"{pk_value}\" غير صالح - العنصر غير موجود." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "قيمة غير صالحة." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/be/LC_MESSAGES/django.mo b/rest_framework/locale/be/LC_MESSAGES/django.mo index 49f63ead..457e2947 100644 Binary files a/rest_framework/locale/be/LC_MESSAGES/django.mo and b/rest_framework/locale/be/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/be/LC_MESSAGES/django.po b/rest_framework/locale/be/LC_MESSAGES/django.po index b31fa5bd..8dd5a6e9 100644 --- a/rest_framework/locale/be/LC_MESSAGES/django.po +++ b/rest_framework/locale/be/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Belarusian (http://www.transifex.com/projects/p/django-rest-framework/language/be/)\n" +"Language-Team: Belarusian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/be/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: be\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/ca/LC_MESSAGES/django.mo b/rest_framework/locale/ca/LC_MESSAGES/django.mo new file mode 100644 index 00000000..06136491 Binary files /dev/null and b/rest_framework/locale/ca/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ca/LC_MESSAGES/django.po b/rest_framework/locale/ca/LC_MESSAGES/django.po new file mode 100644 index 00000000..ce74a5f4 --- /dev/null +++ b/rest_framework/locale/ca/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Catalan (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ca/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "Header Basic invàlid. No hi ha disponibles les credencials." + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "Header Basic invàlid. Les credencials no poden contenir espais." + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "Header Basic invàlid. Les credencials no estan codificades correctament en base64." + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "Usuari/Contrasenya incorrectes." + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "Usuari inactiu o esborrat." + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "Token header invàlid. No s'han indicat les credencials." + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "Token header invàlid. El token no ha de contenir espais." + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Token header invàlid. El token no pot contenir caràcters invàlids." + +#: authentication.py:185 +msgid "Invalid token." +msgstr "Token invàlid." + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "Compte d'usuari desactivat." + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "No es possible loguejar-se amb les credencials introduïdes." + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "S'ha d'incloure \"username\" i \"password\"." + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "S'ha produït un error en el servidor." + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "Request amb format incorrecte." + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "Credencials d'autenticació incorrectes." + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "Credencials d'autenticació no disponibles." + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "No té permisos per realitzar aquesta acció." + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "No trobat." + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "Mètode \"{method}\" no permès." + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "No s'ha pogut satisfer l'Accept header de la petició." + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "Media type \"{media_type}\" no suportat." + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "La petició ha estat limitada pel número màxim de peticions definit." + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "Aquest camp és obligatori." + +#: fields.py:267 +msgid "This field may not be null." +msgstr "Aquest camp no pot ser nul." + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "\"{input}\" no és un booleà." + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "Aquest camp no pot estar en blanc." + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "Aquest camp no pot tenir més de {max_length} caràcters." + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "Aquest camp ha de tenir un mínim de {min_length} caràcters." + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "Introdueixi una adreça de correu vàlida." + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "Aquest valor no compleix el patró requerit." + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "Introdueix un \"slug\" vàlid consistent en lletres, números, guions o guions baixos." + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "Introdueixi una URL vàlida." + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "\"{value}\" no és un UUID vàlid." + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Introdueixi una adreça IPv4 o IPv6 vàlida." + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "Es requereix un nombre enter vàlid." + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "Aquest valor ha de ser menor o igual a {max_value}." + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "Aquest valor ha de ser més gran o igual a {min_value}." + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "Valor del text massa gran." + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "Es requereix un nombre vàlid." + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "No pot haver-hi més de {max_digits} dígits en total." + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "No pot haver-hi més de {max_decimal_places} decimals." + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "No pot haver-hi més de {max_whole_digits} dígits abans del punt decimal." + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "El Datetime té un format incorrecte. Utilitzi un d'aquests formats: {format}." + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "S'espera un Datetime però s'ha rebut un Date." + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "El Date té un format incorrecte. Utilitzi un d'aquests formats: {format}." + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "S'espera un Date però s'ha rebut un Datetime." + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "El Time té un format incorrecte. Utilitzi un d'aquests formats: {format}." + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "La durada té un format incorrecte. Utilitzi un d'aquests formats: {format}." + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "\"{input}\" no és una opció vàlida." + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "S'espera una llista d'ítems però s'ha rebut el tipus \"{input_type}\"." + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Aquesta selecció no pot estar buida." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" no és un path vàlid." + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "No s'ha enviat cap fitxer." + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "Les dades enviades no són un fitxer. Comproveu l'encoding type del formulari." + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "No s'ha pogut determinar el nom del fitxer." + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "El fitxer enviat està buit." + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "El nom del fitxer ha de tenir com a màxim {max_length} caràcters (en té {length})." + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "Envieu una imatge vàlida. El fitxer enviat no és una imatge o és una imatge corrompuda." + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Aquesta llista no pot estar buida." + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "S'espera un diccionari però s'ha rebut el tipus \"{input_type}\"." + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "Pàgina invàlida \"{page_number}\": {message}." + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "Cursor invàlid." + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "PK invàlida \"{pk_value}\" - l'objecte no existeix." + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "Tipus incorrecte. S'espera el valor d'una PK, s'ha rebut {data_type}." + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "Hyperlink invàlid - Cap match d'URL." + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "Hyperlink invàlid - Match d'URL incorrecta." + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "Hyperlink invàlid - L'objecte no existeix." + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "Tipus incorrecte. S'espera una URL, s'ha rebut {data_type}." + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "L'objecte amb {slug_name}={value} no existeix." + +#: relations.py:392 +msgid "Invalid value." +msgstr "Valor invàlid." + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "Dades invàlides. S'espera un diccionari però s'ha rebut {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "Cap" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "Cap opció seleccionada." + +#: validators.py:24 +msgid "This field must be unique." +msgstr "Aquest camp ha de ser únic." + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "Aquests camps {field_names} han de constituir un conjunt únic." + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "Aquest camp ha de ser únic per a la data \"{date_field}\"." + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "Aquest camp ha de ser únic per al mes \"{date_field}\"." + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "Aquest camp ha de ser únic per a l'any \"{date_field}\"." + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "Versió invàlida al header \"Accept\"." + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "Versió invàlida a la URL." + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "Versió invàlida al hostname." + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "Versió invàlida al paràmetre de consulta." + +#: views.py:88 +msgid "Permission denied." +msgstr "Permís denegat." diff --git a/rest_framework/locale/ca_ES/LC_MESSAGES/django.mo b/rest_framework/locale/ca_ES/LC_MESSAGES/django.mo new file mode 100644 index 00000000..5c2dd5ba Binary files /dev/null and b/rest_framework/locale/ca_ES/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ca_ES/LC_MESSAGES/django.po b/rest_framework/locale/ca_ES/LC_MESSAGES/django.po new file mode 100644 index 00000000..fad1d902 --- /dev/null +++ b/rest_framework/locale/ca_ES/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Catalan (Spain) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ca_ES/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca_ES\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/cs/LC_MESSAGES/django.mo b/rest_framework/locale/cs/LC_MESSAGES/django.mo index 83363b39..f0dc3dfc 100644 Binary files a/rest_framework/locale/cs/LC_MESSAGES/django.mo and b/rest_framework/locale/cs/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/cs/LC_MESSAGES/django.po b/rest_framework/locale/cs/LC_MESSAGES/django.po index 037157e1..15cb86c8 100644 --- a/rest_framework/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework/locale/cs/LC_MESSAGES/django.po @@ -9,33 +9,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Czech (http://www.transifex.com/projects/p/django-rest-framework/language/cs/)\n" +"Language-Team: Czech (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Chybná hlavička. Nebyly poskytnuty přihlašovací údaje." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Chybná hlavička. Přihlašovací údaje by neměly obsahovat mezery." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Chybná hlavička. Přihlašovací údaje nebyly správně zakódovány pomocí base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Chybné uživatelské jméno nebo heslo." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Uživatelský účet je neaktivní nebo byl smazán." @@ -47,7 +47,12 @@ msgstr "Chybná hlavička tokenu. Nebyly zadány přihlašovací údaje." msgid "Invalid token header. Token string should not contain spaces." msgstr "Chybná hlavička tokenu. Přihlašovací údaje by neměly obsahovat mezery." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Chybný token." @@ -63,261 +68,309 @@ msgstr "Zadanými údaji se nebylo možné přihlásit." msgid "Must include \"username\" and \"password\"." msgstr "Musí obsahovat \"uživatelské jméno\" a \"heslo\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Chyba na straně serveru." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Neplatný formát požadavku." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Chybné přihlašovací údaje." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Nebyly zadány přihlašovací údaje." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "K této akci nemáte oprávnění." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Nenalezeno." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Metoda \"{method}\" není povolena." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Nelze vyhovět požadavku v hlavičce Accept." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Nepodporovaný media type \"{media_type}\" v požadavku." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Požadavek byl limitován kvůli omezení počtu požadavků za časovou periodu." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Toto pole je vyžadováno." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Toto pole nesmí být prázdné (null)." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" nelze použít jako typ boolean." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Toto pole nesmí být prázdné." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Zkontrolujte, že toto pole není delší než {max_length} znaků." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Zkontrolujte, že toto pole obsahuje alespoň {min_length} znaků." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Vložte platnou e-mailovou adresu." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Hodnota v tomto poli neodpovídá požadovanému formátu." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Vložte platnou \"zkrácenou formu\" obsahující pouze malá písmena, čísla, spojovník nebo podtržítko." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Vložte platný odkaz." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" není platné UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Je vyžadováno celé číslo." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Zkontrolujte, že hodnota je menší nebo rovna {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Zkontrolujte, že hodnota je větší nebo rovna {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Řetězec je příliš dlouhý." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Je vyžadováno číslo." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Zkontrolujte, že číslo neobsahuje více než {max_digits} čislic." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Zkontrolujte, že číslo nemá více než {max_decimal_places} desetinných míst." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Zkontrolujte, že číslo neobsahuje více než {max_whole_digits} čislic před desetinnou čárkou." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Chybný formát data a času. Použijte jeden z těchto formátů: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Bylo zadáno pouze datum bez času." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Chybný formát data. Použijte jeden z těchto formátů: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Bylo zadáno datum a čas, místo samotného data." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Chybný formát času. Použijte jeden z těchto formátů: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" není platnou možností." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Byl očekáván seznam položek ale nalezen \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Nebyl zaslán žádný soubor." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Zaslaná data neobsahují soubor. Zkontrolujte typ kódování ve formuláři." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Nebylo možné zjistit jméno souboru." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Zaslaný soubor je prázdný." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Zajistěte, aby jméno souboru obsahovalo maximálně {max_length} znaků (teď má {length} znaků)." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Nahrajte platný obrázek. Nahraný soubor buď není obrázkem nebo je poškozen." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Byl očekáván slovník položek ale nalezen \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Chybné čislo stránky \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Chybný kurzor." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Chybný primární klíč \"{pk_value}\" - objekt neexistuje." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Chybný typ. Byl přijat typ {data_type} místo hodnoty primárního klíče." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Chybný odkaz - nebyla nalezena žádní shoda." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Chybný odkaz - byla nalezena neplatná shoda." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Chybný odkaz - objekt neexistuje." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Chybný typ. Byl přijat typ {data_type} místo očekávaného odkazu." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objekt s {slug_name}={value} neexistuje." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Chybná hodnota." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Chybná data. Byl přijat typ {datatype} místo očekávaného slovníku." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -330,46 +383,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Tato položka musí být unikátní." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Položka {field_names} musí tvořit unikátní množinu." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Tato položka musí být pro datum \"{date_field}\" unikátní." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Tato položka musí být pro měsíc \"{date_field}\" unikátní." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Tato položka musí být pro rok \"{date_field}\" unikátní." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Chybné číslo verze v hlavičce Accept." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Chybné číslo verze v odkazu." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Chybné číslo verze v hostname." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Chybné čislo verze v URL parametru." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/da/LC_MESSAGES/django.mo b/rest_framework/locale/da/LC_MESSAGES/django.mo index 68b0687e..f6ac0f7d 100644 Binary files a/rest_framework/locale/da/LC_MESSAGES/django.mo and b/rest_framework/locale/da/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/da/LC_MESSAGES/django.po b/rest_framework/locale/da/LC_MESSAGES/django.po index 5cbafc92..95bd0cb9 100644 --- a/rest_framework/locale/da/LC_MESSAGES/django.po +++ b/rest_framework/locale/da/LC_MESSAGES/django.po @@ -3,38 +3,39 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Mads Jensen , 2015 # Mikkel Munch Mortensen <3xm@detfalskested.dk>, 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Danish (http://www.transifex.com/projects/p/django-rest-framework/language/da/)\n" +"Language-Team: Danish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Ugyldig basic header. Ingen legitimation angivet." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Ugyldig basic header. Legitimationsstrenge må ikke indeholde mellemrum." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Ugyldig basic header. Legitimationen er ikke base64 encoded på korrekt vis." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Ugyldigt brugernavn/kodeord." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Inaktiv eller slettet bruger." @@ -46,7 +47,12 @@ msgstr "Ugyldig token header." msgid "Invalid token header. Token string should not contain spaces." msgstr "Ugyldig token header. Token-strenge må ikke indeholde mellemrum." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Ugyldig token header. Token streng bør ikke indeholde ugyldige karakterer." + +#: authentication.py:185 msgid "Invalid token." msgstr "Ugyldigt token." @@ -62,261 +68,309 @@ msgstr "Kunne ikke logge ind med den angivne legitimation." msgid "Must include \"username\" and \"password\"." msgstr "Skal indeholde \"username\" og \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Der er sket en serverfejl." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Misdannet forespørgsel." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Ugyldig legitimation til autentificering." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Legitimation til autentificering blev ikke angivet." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Du har ikke lov til at udføre denne handling." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Ikke fundet." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Metoden \"{method}\" er ikke tilladt." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Kunne ikke efterkomme forespørgslens Accept header." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Forespørgslens media type, \"{media_type}\", er ikke understøttet." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Forespørgslen blev neddroslet." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Dette felt er påkrævet." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Dette felt må ikke være null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" er ikke en tilladt boolsk værdi." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Dette felt må ikke være tomt." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Tjek at dette felt ikke indeholder flere end {max_length} tegn." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Tjek at dette felt indeholder mindst {min_length} tegn." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Angiv en gyldig e-mailadresse." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Denne værdi passer ikke med det påkrævede mønster." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Indtast en gyldig \"slug\", bestående af bogstaver, tal, bund- og bindestreger." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Indtast en gyldig URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" er ikke et gyldigt UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Indtast en gyldig IPv4 eller IPv6 adresse." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Et gyldigt heltal er påkrævet." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Tjek at værdien er mindre end eller lig med {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Tjek at værdien er større end eller lig med {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Strengværdien er for stor." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Et gyldigt tal er påkrævet." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Tjek at der ikke er flere end {max_digits} cifre i alt." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Tjek at der ikke er flere end {max_decimal_places} cifre efter kommaet." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Tjek at der ikke er flere end {max_whole_digits} cifre før kommaet." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datotid har et forkert format. Brug i stedet et af disse formater: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Forventede en datotid, men fik en dato." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Dato har et forkert format. Brug i stedet et af disse formater: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Forventede en dato men fik en datotid." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Klokkeslæt har forkert format. Brug i stedet et af disse formater: {format}. " -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Varighed har forkert format. Brug istedet et af følgende formater: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" er ikke et gyldigt valg." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Flere end {count} objekter..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Forventede en liste, men fik noget af typen \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Dette valg kan være tomt." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" er ikke et gyldigt valg af adresse." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Ingen medsendt fil." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Det medsendte data var ikke en fil. Tjek typen af indkodning på formularen." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Filnavnet kunne ikke afgøres." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Den medsendte fil er tom." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Sørg for at filnavnet er højst {max_length} langt (det er {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Medsend et gyldigt billede. Den medsendte fil var enten ikke et billede eller billedfilen var ødelagt." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Denne liste er muligvis ikke tom." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Forventede en dictionary, men fik noget af typen \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Ugyldig side \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Ugyldig cursor" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Ugyldig primærnøgle \"{pk_value}\" - objektet findes ikke." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Ugyldig type. Forventet værdi er primærnøgle, fik {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Ugyldigt hyperlink - intet URL match." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Ugyldigt hyperlink - forkert URL match." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Ugyldigt hyperlink - objektet findes ikke." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Forkert type. Forventede en URL-streng, fik {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Object med {slug_name}={value} findes ikke." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Ugyldig værdi." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Ugyldig data. Forventede en dictionary, men fik {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +383,46 @@ msgstr "Ingen" msgid "No items to select." msgstr "Intet at vælge." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Dette felt skal være unikt." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Felterne {field_names} skal udgøre et unikt sæt." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Dette felt skal være unikt for \"{date_field}\"-datoen." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Dette felt skal være unikt for \"{date_field}\"-måneden." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Dette felt skal være unikt for \"{date_field}\"-året." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Ugyldig version i \"Accept\" headeren." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Ugyldig version i URL-stien." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Ugyldig version i hostname." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Ugyldig version i forespørgselsparameteren." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Adgang nægtet." diff --git a/rest_framework/locale/da_DK/LC_MESSAGES/django.mo b/rest_framework/locale/da_DK/LC_MESSAGES/django.mo new file mode 100644 index 00000000..78170eeb Binary files /dev/null and b/rest_framework/locale/da_DK/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/da_DK/LC_MESSAGES/django.po b/rest_framework/locale/da_DK/LC_MESSAGES/django.po new file mode 100644 index 00000000..c198cfdf --- /dev/null +++ b/rest_framework/locale/da_DK/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Danish (Denmark) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/da_DK/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: da_DK\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/de/LC_MESSAGES/django.mo b/rest_framework/locale/de/LC_MESSAGES/django.mo index 873b18f6..0c1034bb 100644 Binary files a/rest_framework/locale/de/LC_MESSAGES/django.mo and b/rest_framework/locale/de/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/de/LC_MESSAGES/django.po b/rest_framework/locale/de/LC_MESSAGES/django.po index eaa440a3..3fc38afb 100644 --- a/rest_framework/locale/de/LC_MESSAGES/django.po +++ b/rest_framework/locale/de/LC_MESSAGES/django.po @@ -4,39 +4,42 @@ # # Translators: # Fabian Büchler , 2015 +# Mads Jensen , 2015 +# Niklas P , 2015 # Thomas Tanner, 2015 +# Tom Jaster , 2015 # Xavier Ordoquy , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: German (http://www.transifex.com/projects/p/django-rest-framework/language/de/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 18:25+0000\n" +"Last-Translator: Fabian Büchler \n" +"Language-Team: German (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Ungültiger basic header. Keine Zugangsdaten angegeben." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Ungültiger basic header. Zugangsdaten sollen keine Leerzeichen enthalten." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Ungültiger basic header. Zugangsdaten sind nicht korrekt mit base64 kodiert." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Ungültiger Benutzername/Passwort" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Benutzer inaktiv oder gelöscht." @@ -48,7 +51,12 @@ msgstr "Ungültiger token header. Keine Zugangsdaten angegeben." msgid "Invalid token header. Token string should not contain spaces." msgstr "Ungültiger token header. Zugangsdaten sollen keine Leerzeichen enthalten." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Ungültiger Token Header. Tokens dürfen keine ungültigen Zeichen enthalten." + +#: authentication.py:185 msgid "Invalid token." msgstr "Ungültiges Token" @@ -64,313 +72,361 @@ msgstr "Kann nicht mit den angegeben Zugangsdaten anmelden." msgid "Must include \"username\" and \"password\"." msgstr "\"username\" und \"password\" sind erforderlich." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Ein Serverfehler ist aufgetreten." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Fehlerhafte Anfrage." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Falsche Anmeldedaten." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Anmeldedaten fehlen." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Sie sind nicht berechtigt, diese Aktion durchzuführen." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Nicht gefunden." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Methode \"{method}\" nicht erlaubt." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Kann die Accept Kopfzeile der Anfrage nicht erfüllen." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Nicht unterstützter Medientyp \"{media_type}\" in der Anfrage." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Die Anfrage wurde gedrosselt." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Dieses Feld ist erforderlich." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Dieses Feld darf nicht Null sein." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" ist kein gültiger Wahrheitswert." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Dieses Feld darf nicht leer sein." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Stelle sicher, dass dieses Feld nicht mehr als {max_length} Zeichen lang ist." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Stelle sicher, dass dieses Feld mindestens {min_length} Zeichen lang ist." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Gib eine gültige E-Mail Adresse an." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Dieser Wert passt nicht zu dem erforderlichen Muster." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Gib ein gültiges \"slug\" aus Buchstaben, Ziffern, Unterstrichen und Minuszeichen ein." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Gib eine gültige URL ein." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" ist keine gültige UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Geben Sie eine gültige UPv4 oder IPv6 Adresse an" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Eine gültige Ganzzahl ist erforderlich." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Stelle sicher, dass dieser Wert kleiner oder gleich {max_value} ist." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Stelle sicher, dass dieser Wert größer oder gleich {min_value} ist." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Zeichenkette zu lang." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Eine gültige Zahl ist erforderlich." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Stelle sicher, dass es insgesamt nicht mehr als {max_digits} Ziffern lang ist." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Stelle sicher, dass es nicht mehr als {max_decimal_places} Nachkommastellen lang ist." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Stelle sicher, dass es nicht mehr als {max_whole_digits} Stellen vor dem Komma lang ist." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datums- und Zeitangabe hat das falsche Format. Nutze stattdessen eines dieser Formate: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Erwarte eine Datums- und Zeitangabe, erhielt aber ein Datum." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Datum hat das falsche Format. Nutze stattdessen eines dieser Formate: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Erwarte ein Datum, erhielt aber eine Datums- und Zeitangabe." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Zeitangabe hat das falsche Format. Nutze stattdessen eines dieser Formate: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Laufzeit hat das falsche Format. Benutze stattdessen eines dieser Formate {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" ist keine gültige Option." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Mehr als {count} Ergebnisse" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Erwarte eine Liste von Elementen, erhielt aber den Typ \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Diese Auswahl darf nicht leer sein" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" ist ein ungültiger Pfad Wahl." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Es wurde keine Datei übermittelt." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Die übermittelten Daten stellen keine Datei dar. Prüfe den Kodierungstyp im Formular." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Der Dateiname konnte nicht ermittelt werden." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Die übermittelte Datei ist leer." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Stelle sicher, dass dieser Dateiname höchstens {max_length} Zeichen lang ist (er hat {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Lade ein gültiges Bild hoch. Die hochgeladene Datei ist entweder kein Bild oder ein beschädigtes Bild." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Diese Liste darf nicht leer sein." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Erwarte ein Dictionary mit Elementen, erhielt aber den Typ \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Wert muss gültiges JSON sein." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Abschicken" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Ungültige Seite \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Ungültiger Zeiger" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Ungültiger pk \"{pk_value}\" - Object existiert nicht." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Falscher Typ. Erwarte pk Wert, erhielt aber {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Ungültiger Hyperlink - entspricht keiner URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Ungültiger Hyperlink - URL stimmt nicht überein." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Ungültiger Hyperlink - Objekt existiert nicht." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Falscher Typ. Erwarte URL Zeichenkette, erhielt aber {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objekt mit {slug_name}={value} existiert nicht." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Ungültiger Wert." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Ungültige Daten. Dictionary erwartet, aber {datatype} erhalten." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filter" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Feldfilter" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Sortierung" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Suche" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "Nichts" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "Keine Elemente zum Auswählen." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Dieses Feld muss eindeutig sein." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Die Felder {field_names} müssen eine eindeutige Menge bilden." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Dieses Feld muss bezüglich des \"{date_field}\" Datums eindeutig sein." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Dieses Feld muss bezüglich des \"{date_field}\" Monats eindeutig sein." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Dieses Feld muss bezüglich des \"{date_field}\" Jahrs eindeutig sein." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Ungültige Version in der \"Accept\" Kopfzeile." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Ungültige Version im URL Pfad." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Ungültige Version im Hostname." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Ungültige Version im Anfrageparameter." -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "Zugriff verweigert." diff --git a/rest_framework/locale/en/LC_MESSAGES/django.mo b/rest_framework/locale/en/LC_MESSAGES/django.mo index 8af103de..6e464e9f 100644 Binary files a/rest_framework/locale/en/LC_MESSAGES/django.mo and b/rest_framework/locale/en/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/en/LC_MESSAGES/django.po b/rest_framework/locale/en/LC_MESSAGES/django.po index b52273b0..4e61be26 100644 --- a/rest_framework/locale/en/LC_MESSAGES/django.po +++ b/rest_framework/locale/en/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: English (http://www.transifex.com/projects/p/django-rest-framework/language/en/)\n" +"Language-Team: English (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/en/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: en\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Invalid basic header. No credentials provided." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Invalid basic header. Credentials string should not contain spaces." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Invalid basic header. Credentials not correctly base64 encoded." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Invalid username/password." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "User inactive or deleted." @@ -45,7 +45,12 @@ msgstr "Invalid token header. No credentials provided." msgid "Invalid token header. Token string should not contain spaces." msgstr "Invalid token header. Token string should not contain spaces." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Invalid token header. Token string should not contain invalid characters." + +#: authentication.py:185 msgid "Invalid token." msgstr "Invalid token." @@ -61,261 +66,309 @@ msgstr "Unable to log in with provided credentials." msgid "Must include \"username\" and \"password\"." msgstr "Must include \"username\" and \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "A server error occurred." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Malformed request." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Incorrect authentication credentials." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Authentication credentials were not provided." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "You do not have permission to perform this action." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Not found." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Method \"{method}\" not allowed." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Could not satisfy the request Accept header." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Unsupported media type \"{media_type}\" in request." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Request was throttled." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "This field is required." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "This field may not be null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" is not a valid boolean." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "This field may not be blank." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Ensure this field has no more than {max_length} characters." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Ensure this field has at least {min_length} characters." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Enter a valid email address." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "This value does not match the required pattern." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Enter a valid \"slug\" consisting of letters, numbers, underscores or hyphens." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Enter a valid URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" is not a valid UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Enter a valid IPv4 or IPv6 address." + +#: fields.py:816 msgid "A valid integer is required." msgstr "A valid integer is required." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Ensure this value is less than or equal to {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Ensure this value is greater than or equal to {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "String value too large." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "A valid number is required." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Ensure that there are no more than {max_digits} digits in total." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Ensure that there are no more than {max_decimal_places} decimal places." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Ensure that there are no more than {max_whole_digits} digits before the decimal point." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datetime has wrong format. Use one of these formats instead: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Expected a datetime but got a date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Date has wrong format. Use one of these formats instead: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Expected a date but got a datetime." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Time has wrong format. Use one of these formats instead: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "Duration has wrong format. Use one of these formats instead: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" is not a valid choice." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "More than {count} items..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Expected a list of items but got type \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "This selection may not be empty." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" is not a valid path choice." + +#: fields.py:1339 msgid "No file was submitted." msgstr "No file was submitted." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "The submitted data was not a file. Check the encoding type on the form." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "No filename could be determined." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "The submitted file is empty." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Ensure this filename has at most {max_length} characters (it has {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Upload a valid image. The file you uploaded was either not an image or a corrupted image." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "This list may not be empty." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Expected a dictionary of items but got type \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Value must be valid JSON." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Submit" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Invalid page \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Invalid cursor" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Invalid pk \"{pk_value}\" - object does not exist." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Incorrect type. Expected pk value, received {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Invalid hyperlink - No URL match." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Invalid hyperlink - Incorrect URL match." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Invalid hyperlink - Object does not exist." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Incorrect type. Expected URL string, received {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Object with {slug_name}={value} does not exist." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Invalid value." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Invalid data. Expected a dictionary, but got {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filters" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Field filters" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Ordering" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Search" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "None" msgid "No items to select." msgstr "No items to select." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "This field must be unique." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "The fields {field_names} must make a unique set." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "This field must be unique for the \"{date_field}\" date." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "This field must be unique for the \"{date_field}\" month." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "This field must be unique for the \"{date_field}\" year." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Invalid version in \"Accept\" header." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Invalid version in URL path." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Invalid version in hostname." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Invalid version in query parameter." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Permission denied." diff --git a/rest_framework/locale/en_AU/LC_MESSAGES/django.mo b/rest_framework/locale/en_AU/LC_MESSAGES/django.mo new file mode 100644 index 00000000..ffaa53bd Binary files /dev/null and b/rest_framework/locale/en_AU/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/en_AU/LC_MESSAGES/django.po b/rest_framework/locale/en_AU/LC_MESSAGES/django.po new file mode 100644 index 00000000..696396b2 --- /dev/null +++ b/rest_framework/locale/en_AU/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: English (Australia) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/en_AU/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en_AU\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/en_CA/LC_MESSAGES/django.mo b/rest_framework/locale/en_CA/LC_MESSAGES/django.mo new file mode 100644 index 00000000..bdf76870 Binary files /dev/null and b/rest_framework/locale/en_CA/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/en_CA/LC_MESSAGES/django.po b/rest_framework/locale/en_CA/LC_MESSAGES/django.po new file mode 100644 index 00000000..f23a59fb --- /dev/null +++ b/rest_framework/locale/en_CA/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: English (Canada) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/en_CA/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en_CA\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/en_US/LC_MESSAGES/django.mo b/rest_framework/locale/en_US/LC_MESSAGES/django.mo index 91676983..c99892e4 100644 Binary files a/rest_framework/locale/en_US/LC_MESSAGES/django.mo and b/rest_framework/locale/en_US/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/en_US/LC_MESSAGES/django.po b/rest_framework/locale/en_US/LC_MESSAGES/django.po index 50556485..afab87aa 100644 --- a/rest_framework/locale/en_US/LC_MESSAGES/django.po +++ b/rest_framework/locale/en_US/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,23 +17,23 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,259 +66,307 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -326,46 +379,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/es/LC_MESSAGES/django.mo b/rest_framework/locale/es/LC_MESSAGES/django.mo index b6dedaa0..287a7948 100644 Binary files a/rest_framework/locale/es/LC_MESSAGES/django.mo and b/rest_framework/locale/es/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/es/LC_MESSAGES/django.po b/rest_framework/locale/es/LC_MESSAGES/django.po index 1c41d37e..7dbed783 100644 --- a/rest_framework/locale/es/LC_MESSAGES/django.po +++ b/rest_framework/locale/es/LC_MESSAGES/django.po @@ -6,38 +6,39 @@ # nnrcschmdt , 2015 # José Padilla , 2015 # Miguel González , 2015 +# Miguel González , 2015 # Sergio Infante , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Spanish (http://www.transifex.com/projects/p/django-rest-framework/language/es/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 15:54+0000\n" +"Last-Translator: Miguel González \n" +"Language-Team: Spanish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Cabecera básica inválida. Las credenciales no fueron suministradas." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Cabecera básica inválida. La cadena con las credenciales no debe contener espacios." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Cabecera básica inválida. Las credenciales incorrectamente codificadas en base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Nombre de usuario/contraseña inválidos." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Usuario inactivo o borrado." @@ -49,7 +50,12 @@ msgstr "Cabecera token inválida. Las credenciales no fueron suministradas." msgid "Invalid token header. Token string should not contain spaces." msgstr "Cabecera token inválida. La cadena token no debe contener espacios." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Cabecera token inválida. La cadena token no debe contener caracteres inválidos." + +#: authentication.py:185 msgid "Invalid token." msgstr "Token inválido." @@ -65,261 +71,309 @@ msgstr "No puede iniciar sesión con las credenciales proporcionadas." msgid "Must include \"username\" and \"password\"." msgstr "Debe incluir \"username\" y \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Se ha producido un error en el servidor." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Solicitud con formato incorrecto." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Credenciales de autenticación incorrectas." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Las credenciales de autenticación no se proveyeron." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Usted no tiene permiso para realizar esta acción." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "No encontrado." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Método \"{method}\" no permitido." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "No se ha podido satisfacer la solicitud de cabecera de Accept." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Tipo de medio \"{media_type}\" incompatible en la solicitud." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Solicitud fue regulada (throttled)." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Este campo es requerido." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Este campo no puede ser nulo." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" no es un booleano válido." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Este campo no puede estar en blanco." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Asegúrese de que este campo no tenga más de {max_length} caracteres." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Asegúrese de que este campo tenga al menos {min_length} caracteres." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Introduzca una dirección de correo electrónico válida." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Este valor no coincide con el patrón requerido." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Introduzca un \"slug\" válido consistente en letras, números, guiones o guiones bajos." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Introduzca una URL válida." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" no es un UUID válido." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Introduzca una dirección IPv4 o IPv6 válida." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Introduzca un número entero válido." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Asegúrese de que este valor es menor o igual a {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Asegúrese de que este valor es mayor o igual a {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Cadena demasiado larga." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Se requiere un número válido." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Asegúrese de que no haya más de {max_digits} dígitos en total." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Asegúrese de que no haya más de {max_decimal_places} decimales." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Asegúrese de que no haya más de {max_whole_digits} dígitos en la parte entera." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Fecha/hora con formato erróneo. Use uno de los siguientes formatos en su lugar: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Se esperaba un fecha/hora en vez de una fecha." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Fecha con formato erróneo. Use uno de los siguientes formatos en su lugar: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Se esperaba una fecha en vez de una fecha/hora." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Hora con formato erróneo. Use uno de los siguientes formatos en su lugar: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Duración con formato erróneo. Use uno de los siguientes formatos en su lugar: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" no es una elección válida." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Más de {count} elementos..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Se esperaba una lista de elementos en vez del tipo \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Esta selección no puede estar vacía." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" no es una elección de ruta válida." + +#: fields.py:1339 msgid "No file was submitted." msgstr "No se envió ningún archivo." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "La información enviada no era un archivo. Compruebe el tipo de codificación del formulario." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "No se pudo determinar un nombre de archivo." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "El archivo enviado está vació." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Asegúrese de que el nombre de archivo no tenga más de {max_length} caracteres (tiene {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Adjunte una imagen válida. El archivo adjunto o bien no es una imagen o bien está dañado." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Esta lista no puede estar vacía." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Se esperaba un diccionario de elementos en vez del tipo \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "El valor debe ser JSON válido." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Enviar" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Página \"{page_number}\" inválida: {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Cursor inválido" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Clave primaria \"{pk_value}\" inválida - objeto no existe." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Tipo incorrecto. Se esperaba valor de clave primaria y se recibió {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Hiperenlace inválido - No hay URL coincidentes." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Hiperenlace inválido - Coincidencia incorrecta de la URL." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Hiperenlace inválido - Objeto no existe." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Tipo incorrecto. Se esperaba una URL y se recibió {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objeto con {slug_name}={value} no existe." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Valor inválido." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Datos inválidos. Se esperaba un diccionario pero es un {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtros" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Filtros de campo" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Ordenamiento" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Buscar" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -332,46 +386,46 @@ msgstr "Ninguno" msgid "No items to select." msgstr "No hay elementos para seleccionar." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Este campo debe ser único." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Los campos {field_names} deben formar un conjunto único." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Este campo debe ser único para el día \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Este campo debe ser único para el mes \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Este campo debe ser único para el año \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Versión inválida en la cabecera \"Accept\"." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Versión inválida en la ruta de la URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Versión inválida en el nombre de host." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Versión inválida en el parámetro de consulta." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Permiso denegado." diff --git a/rest_framework/locale/et/LC_MESSAGES/django.mo b/rest_framework/locale/et/LC_MESSAGES/django.mo index 9cb257a4..d0d064b1 100644 Binary files a/rest_framework/locale/et/LC_MESSAGES/django.mo and b/rest_framework/locale/et/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/et/LC_MESSAGES/django.po b/rest_framework/locale/et/LC_MESSAGES/django.po index 3c815219..da2db496 100644 --- a/rest_framework/locale/et/LC_MESSAGES/django.po +++ b/rest_framework/locale/et/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Estonian (http://www.transifex.com/projects/p/django-rest-framework/language/et/)\n" +"Language-Team: Estonian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/et/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: et\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Sobimatu lihtpäis. Kasutajatunnus on esitamata." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Sobimatu lihtpäis. Kasutajatunnus ei tohi sisaldada tühikuid." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Sobimatu lihtpäis. Kasutajatunnus pole korrektselt base64-kodeeritud." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Sobimatu kasutajatunnus/salasõna." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Kasutaja on inaktiivne või kustutatud." @@ -46,7 +46,12 @@ msgstr "Sobimatu lubakaardi päis. Kasutajatunnus on esitamata." msgid "Invalid token header. Token string should not contain spaces." msgstr "Sobimatu lubakaardi päis. Loa sõne ei tohi sisaldada tühikuid." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Sobimatu lubakaart." @@ -62,261 +67,309 @@ msgstr "Sisselogimine antud tunnusega ebaõnnestus." msgid "Must include \"username\" and \"password\"." msgstr "Peab sisaldama \"kasutajatunnust\" ja \"slasõna\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Viga serveril." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Väändunud päring." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Ebakorrektne autentimistunnus." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Autentimistunnus on esitamata." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Teil puuduvad piisavad õigused selle tegevuse teostamiseks." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Ei leidnud." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Meetod \"{method}\" pole lubatud." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Päringu Accept-päist ei suutnud täita." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Meedia tüüpi {media_type} päringus ei toetata." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Liiga palju päringuid." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Väli on kohustuslik." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Väli ei tohi olla tühi." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" pole kehtiv kahendarv." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "See väli ei tohi olla tühi." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Veendu, et see väli poleks pikem kui {max_length} tähemärki." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Veendu, et see väli oleks vähemalt {min_length} tähemärki pikk." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Sisestage kehtiv e-posti aadress." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Väärtus ei ühti etteantud mustriga." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Sisestage kehtiv \"slug\", mis koosneks tähtedest, numbritest, ala- või sidekriipsudest." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Sisestage korrektne URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" pole kehtiv UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Sisendiks peab olema täisarv." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Veenduge, et väärtus on väiksem kui või võrdne väärtusega {max_value}. " -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Veenduge, et väärtus on suurem kui või võrdne väärtusega {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Sõne on liiga pikk." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Sisendiks peab olema arv." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Veenduge, et kokku pole rohkem kui {max_digits} numbit." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Veenduge, et komakohti pole rohkem kui {max_decimal_places}. " -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Veenduge, et täiskohti poleks rohkem kui {max_whole_digits}." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Valesti formaaditud kuupäev-kellaaeg. Kasutage mõnda neist: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Ootasin kuupäev-kellaaeg andmetüüpi, kuid sain hoopis kuupäeva." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Valesti formaaditud kuupäev. Kasutage mõnda neist: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Ootasin kuupäeva andmetüüpi, kuid sain hoopis kuupäev-kellaaja." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Valesti formaaditud kellaaeg. Kasutage mõnda neist: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" on sobimatu valik." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Ootasin kirjete järjendit, kuid sain \"{input_type}\" - tüübi." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Ühtegi faili ei esitatud." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Esitatud andmetes ei olnud faili. Kontrollige vormi kodeeringut." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Ei suutnud tuvastada failinime." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Esitatud fail oli tühi." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Veenduge, et failinimi oleks maksimaalselt {max_length} tähemärki pikk (praegu on {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Laadige üles kehtiv pildifail. Üles laetud fail ei olnud pilt või oli see katki." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Ootasin kirjete sõnastikku, kuid sain \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Sobimatu lehekülg \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Sobimatu kursor." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Sobimatu primaarvõti \"{pk_value}\" - objekti pole olemas." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Sobimatu andmetüüp. Ootasin primaarvõtit, sain {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Sobimatu hüperlink - ei leidnud URLi vastet." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Sobimatu hüperlink - vale URLi vaste." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Sobimatu hüperlink - objekti ei eksisteeri." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Sobimatu andmetüüp. Ootasin URLi sõne, sain {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objekti {slug_name}={value} ei eksisteeri." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Sobimatu väärtus." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Sobimatud andmed. Ootasin sõnastikku, kuid sain {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Selle välja väärtus peab olema unikaalne." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Veerud {field_names} peavad moodustama unikaalse hulga." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Selle välja väärtus peab olema unikaalne veerus \"{date_field}\" märgitud kuupäeval." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Selle välja väärtus peab olema unikaalneveerus \"{date_field}\" märgitud kuul." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Selle välja väärtus peab olema unikaalneveerus \"{date_field}\" märgitud aastal." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Sobimatu versioon \"Accept\" päises." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Sobimatu versioon URLi rajas." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Sobimatu versioon hostinimes." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Sobimatu versioon päringu parameetris." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/fi/LC_MESSAGES/django.mo b/rest_framework/locale/fi/LC_MESSAGES/django.mo new file mode 100644 index 00000000..2b714481 Binary files /dev/null and b/rest_framework/locale/fi/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/fi/LC_MESSAGES/django.po b/rest_framework/locale/fi/LC_MESSAGES/django.po new file mode 100644 index 00000000..c6c24c64 --- /dev/null +++ b/rest_framework/locale/fi/LC_MESSAGES/django.po @@ -0,0 +1,428 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Aarni Koskela, 2015 +# Aarni Koskela, 2015 +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 16:26+0000\n" +"Last-Translator: Aarni Koskela\n" +"Language-Team: Finnish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "Epäkelpo perusotsake. Ei annettuja tunnuksia." + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "Epäkelpo perusotsake. Tunnusmerkkijono ei saa sisältää välilyöntejä." + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "Epäkelpo perusotsake. Tunnukset eivät ole base64-koodattu." + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "Epäkelpo käyttäjänimi tai salasana." + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "Käyttäjä ei-aktiivinen tai poistettu." + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "Epäkelpo Token-otsake. Ei annettuja tunnuksia." + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "Epäkelpo Token-otsake. Tunnusmerkkijono ei saa sisältää välilyöntejä." + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Epäkelpo Token-otsake. Tunnusmerkkijono ei saa sisältää epäkelpoja merkkejä." + +#: authentication.py:185 +msgid "Invalid token." +msgstr "Epäkelpo Token." + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "Käyttäjätili ei ole käytössä." + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "Ei voitu kirjautua annetuilla tunnuksilla." + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "Pitää sisältää \"username\" ja \"password\"." + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "Sattui palvelinvirhe." + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "Pyyntö on virheellisen muotoinen." + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "Väärät autentikaatiotunnukset." + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "Autentikaatiotunnuksia ei annettu." + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "Sinulla ei ole lupaa suorittaa tätä toimintoa." + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "Ei löydy." + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "Metodi \"{method}\" ei ole sallittu." + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "Ei voitu vastata pyynnön Accept-otsakkeen mukaisesti." + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "Pyynnön mediatyyppiä \"{media_type}\" ei tueta." + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "Pyyntö hidastettu." + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "Tämä kenttä vaaditaan." + +#: fields.py:267 +msgid "This field may not be null." +msgstr "Tämän kentän arvo ei voi olla \"null\"." + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "\"{input}\" ei ole kelvollinen totuusarvo." + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "Tämä kenttä ei voi olla tyhjä." + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "Arvo saa olla enintään {max_length} merkkiä pitkä." + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "Arvo tulee olla vähintään {min_length} merkkiä pitkä." + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "Syötä kelvollinen sähköpostiosoite." + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "Arvo ei täsmää vaadittuun kuvioon." + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "Tässä voidaan käyttää vain kirjaimia (a-z), numeroita (0-9) sekä ala- ja tavuviivoja (_ -)." + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "Syötä oikea URL-osoite." + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "{value} ei ole kelvollinen UUID." + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Syötä kelvollinen IPv4- tai IPv6-osoite." + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "Syötä kelvollinen kokonaisluku." + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "Tämän arvon on oltava enintään {max_value}." + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "Tämän luvun on oltava vähintään {min_value}." + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "Liian suuri merkkijonoarvo." + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "Kelvollinen luku vaaditaan." + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "Tässä luvussa voi olla yhteensä enintään {max_digits} numeroa." + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "Tässä luvussa saa olla enintään {max_decimal_places} desimaalia." + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "Tässä luvussa saa olla enintään {max_whole_digits} numeroa ennen desimaalipilkkua." + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "Virheellinen päivämäärän/ajan muotoilu. Käytä jotain näistä muodoista: {format}" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "Odotettiin päivämäärää ja aikaa, saatiin vain päivämäärä." + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "Virheellinen päivämäärän muotoilu. Käytä jotain näistä muodoista: {format}" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "Odotettiin päivämäärää, saatiin päivämäärä ja aika." + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "Virheellinen kellonajan muotoilu. Käytä jotain näistä muodoista: {format}" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "Virheellinen keston muotoilu. Käytä jotain näistä muodoista: {format}" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "\"{input}\" ei ole kelvollinen valinta." + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Enemmän kuin {count} kappaletta..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "Odotettiin listaa, saatiin tyyppi {input_type}." + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Valinta ei saa olla tyhjä." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" ei ole kelvollinen polku." + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "Yhtään tiedostoa ei ole lähetetty." + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "Tiedostoa ei lähetetty. Tarkista lomakkeen koodaus (encoding)." + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "Tiedostonimeä ei voitu päätellä." + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "Lähetetty tiedosto on tyhjä." + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "Varmista että tiedostonimi on enintään {max_length} merkkiä pitkä (nyt {length})." + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "Kuva ei kelpaa. Lähettämäsi tiedosto ei ole kuva, tai tiedosto on vioittunut." + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Lista ei saa olla tyhjä." + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "Odotettiin sanakirjaa, saatiin tyyppi {input_type}." + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Arvon pitää olla kelvollista JSONia." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Lähetä" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "Epäkelpo sivu ({page_number}): {message}" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "Epäkelpo kursori" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "Epäkelpo pääavain {pk_value} - objektia ei ole olemassa." + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "Väärä tyyppi. Odotettiin pääavainarvoa, saatiin {data_type}." + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "Epäkelpo linkki - URL ei täsmää." + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "Epäkelpo linkki - epäkelpo URL-osuma." + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "Epäkelpo linkki - objektia ei ole." + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "Epäkelpo tyyppi. Odotettiin URL-merkkijonoa, saatiin {data_type}." + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "Objektia ({slug_name}={value}) ei ole." + +#: relations.py:392 +msgid "Invalid value." +msgstr "Epäkelpo arvo." + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "Odotettiin sanakirjaa, saatiin tyyppi {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Suotimet" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Kenttäsuotimet" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Järjestys" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Haku" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "Ei mitään" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "Ei valittavia kohteita." + +#: validators.py:24 +msgid "This field must be unique." +msgstr "Arvon tulee olla uniikki." + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "Kenttien {field_names} tulee muodostaa uniikki joukko." + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "Kentän tulee olla uniikki päivämäärän {date_field} suhteen." + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "Kentän tulee olla uniikki kuukauden {date_field} suhteen." + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "Kentän tulee olla uniikki vuoden {date_field} suhteen." + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "Epäkelpo versio Accept-otsakkeessa." + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "Epäkelpo versio URL-polussa." + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "Epäkelpo versio palvelinosoitteessa." + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "Epäkelpo versio kyselyparametrissa." + +#: views.py:88 +msgid "Permission denied." +msgstr "Pääsy evätty." diff --git a/rest_framework/locale/fr/LC_MESSAGES/django.mo b/rest_framework/locale/fr/LC_MESSAGES/django.mo index ced2145c..03bcfa94 100644 Binary files a/rest_framework/locale/fr/LC_MESSAGES/django.mo and b/rest_framework/locale/fr/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/fr/LC_MESSAGES/django.po b/rest_framework/locale/fr/LC_MESSAGES/django.po index 8116be03..17bff26b 100644 --- a/rest_framework/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework/locale/fr/LC_MESSAGES/django.po @@ -11,33 +11,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 19:53+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: French (http://www.transifex.com/projects/p/django-rest-framework/language/fr/)\n" +"Language-Team: French (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "En-tête « basic » non valide. Informations d'identification non fournies." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "En-tête « basic » non valide. Les informations d'identification ne doivent pas contenir d'espaces." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "En-tête « basic » non valide. Encodage base64 des informations d'identification incorrect." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Nom d'utilisateur et/ou mot de passe non valide(s)." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Utilisateur inactif ou supprimé." @@ -49,7 +49,12 @@ msgstr "En-tête « token » non valide. Informations d'identification non fourn msgid "Invalid token header. Token string should not contain spaces." msgstr "En-tête « token » non valide. Un token ne doit pas contenir d'espaces." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "En-tête « token » non valide. Un token ne doit pas contenir de caractères invalides." + +#: authentication.py:185 msgid "Invalid token." msgstr "Token non valide." @@ -65,261 +70,309 @@ msgstr "Impossible de se connecter avec les informations d'identification fourni msgid "Must include \"username\" and \"password\"." msgstr "\"username\" et \"password\" doivent être inclus." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Une erreur du serveur est survenue." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Requête malformée" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Informations d'authentification incorrectes." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Informations d'authentification non fournies." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Vous n'avez pas la permission d'effectuer cette action." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Pas trouvé." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Méthode \"{method}\" non autorisée." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "L'en-tête « Accept » n'a pas pu être satisfaite." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Type de média \"{media_type}\" non supporté." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Requête ralentie." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Ce champ est obligatoire." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." -msgstr "Ce champ ne peut être null." +msgstr "Ce champ ne peut être nul." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" n'est pas un booléen valide." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Ce champ ne peut être vide." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Assurez-vous que ce champ comporte au plus {max_length} caractères." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Assurez-vous que ce champ comporte au moins {min_length} caractères." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Saisissez une adresse email valable." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Cette valeur ne satisfait pas le motif imposé." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Saisissez une URL valide." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" n'est pas un UUID valide." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Saisissez une adresse IPv4 ou IPv6 valide." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Un nombre entier valide est requis." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Assurez-vous que cette valeur est inférieure ou égale à {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Assurez-vous que cette valeur est supérieure ou égale à {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Chaîne de caractères trop longue." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Un nombre valide est requis." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Assurez-vous qu'il n'y a pas plus de {max_digits} chiffres au total." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Assurez-vous qu'il n'y a pas plus de {max_decimal_places} chiffres après la virgule." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Assurez-vous qu'il n'y a pas plus de {max_whole_digits} chiffres avant la virgule." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "La date + heure n'a pas le bon format. Utilisez un des formats suivants : {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Attendait une date + heure mais a reçu une date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "La date n'a pas le bon format. Utilisez un des formats suivants : {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Attendait une date mais a reçu une date + heure." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "L'heure n'a pas le bon format. Utilisez un des formats suivants : {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "La durée n'a pas le bon format. Utilisez l'un des formats suivants: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" n'est pas un choix valide." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Plus de {count} éléments..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Attendait une liste d'éléments mais a reçu \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Cette sélection ne peut être vide." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" n'est pas un choix de chemin valide." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Aucun fichier n'a été soumis." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "La donnée soumise n'est pas un fichier. Vérifiez le type d'encodage du formulaire." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Le nom de fichier n'a pu être déterminé." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Le fichier soumis est vide." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Assurez-vous que le nom de fichier comporte au plus {max_length} caractères (il en comporte {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Transférez une image valide. Le fichier que vous avez transféré n'est pas une image, ou il est corrompu." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Cette liste ne peut pas être vide." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Attendait un dictionnaire d'éléments mais a reçu \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "La valeur doit être un JSON valide." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Envoyer" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Page \"{page_number}\" non valide : {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Curseur non valide" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Clé primaire \"{pk_value}\" non valide - l'objet n'existe pas." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Type incorrect. Attendait une clé primaire, a reçu {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Lien non valide : pas d'URL correspondante." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Lien non valide : URL correspondante incorrecte." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Lien non valide : l'objet n'existe pas." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Type incorrect. Attendait une URL, a reçu {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "L'object avec {slug_name}={value} n'existe pas." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Valeur non valide." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Donnée non valide. Attendait un dictionnaire, a reçu {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtres" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Filtres de champ" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Ordre" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Recherche" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -332,46 +385,46 @@ msgstr "Aucune" msgid "No items to select." msgstr "Aucun élément à sélectionner." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Ce champ doit être unique." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Les champs {field_names} doivent former un ensemble unique." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Ce champ doit être unique pour la date \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Ce champ doit être unique pour le mois \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Ce champ doit être unique pour l'année \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Version non valide dans l'en-tête « Accept »." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Version non valide dans l'URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Version non valide dans le nom d'hôte." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Version non valide dans le paramètre de requête." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Permission refusée." diff --git a/rest_framework/locale/fr_CA/LC_MESSAGES/django.mo b/rest_framework/locale/fr_CA/LC_MESSAGES/django.mo new file mode 100644 index 00000000..eb0b496d Binary files /dev/null and b/rest_framework/locale/fr_CA/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/fr_CA/LC_MESSAGES/django.po b/rest_framework/locale/fr_CA/LC_MESSAGES/django.po new file mode 100644 index 00000000..62a559dc --- /dev/null +++ b/rest_framework/locale/fr_CA/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: French (Canada) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/fr_CA/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr_CA\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/gl/LC_MESSAGES/django.mo b/rest_framework/locale/gl/LC_MESSAGES/django.mo index 5ffad714..b8c3db30 100644 Binary files a/rest_framework/locale/gl/LC_MESSAGES/django.mo and b/rest_framework/locale/gl/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/gl/LC_MESSAGES/django.po b/rest_framework/locale/gl/LC_MESSAGES/django.po index e9c20d3c..f7e11d4d 100644 --- a/rest_framework/locale/gl/LC_MESSAGES/django.po +++ b/rest_framework/locale/gl/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Galician (http://www.transifex.com/projects/p/django-rest-framework/language/gl/)\n" +"Language-Team: Galician (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/gl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: gl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/gl_ES/LC_MESSAGES/django.mo b/rest_framework/locale/gl_ES/LC_MESSAGES/django.mo index 282cfc94..0e5a00ac 100644 Binary files a/rest_framework/locale/gl_ES/LC_MESSAGES/django.mo and b/rest_framework/locale/gl_ES/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/gl_ES/LC_MESSAGES/django.po b/rest_framework/locale/gl_ES/LC_MESSAGES/django.po index 6ba18cf3..363d4946 100644 --- a/rest_framework/locale/gl_ES/LC_MESSAGES/django.po +++ b/rest_framework/locale/gl_ES/LC_MESSAGES/django.po @@ -3,37 +3,38 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Carlos Goce , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Galician (Spain) (http://www.transifex.com/projects/p/django-rest-framework/language/gl_ES/)\n" +"Language-Team: Galician (Spain) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/gl_ES/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: gl_ES\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +46,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,266 +67,314 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." -msgstr "" +msgstr "Valor non válido." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "Ningún" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 @@ -328,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "Permiso denegado." diff --git a/rest_framework/locale/he_IL/LC_MESSAGES/django.mo b/rest_framework/locale/he_IL/LC_MESSAGES/django.mo new file mode 100644 index 00000000..53ecccd1 Binary files /dev/null and b/rest_framework/locale/he_IL/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/he_IL/LC_MESSAGES/django.po b/rest_framework/locale/he_IL/LC_MESSAGES/django.po new file mode 100644 index 00000000..b2162a4d --- /dev/null +++ b/rest_framework/locale/he_IL/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Hebrew (Israel) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/he_IL/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: he_IL\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/hu/LC_MESSAGES/django.mo b/rest_framework/locale/hu/LC_MESSAGES/django.mo index f3ef2f4a..a35f7321 100644 Binary files a/rest_framework/locale/hu/LC_MESSAGES/django.mo and b/rest_framework/locale/hu/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/hu/LC_MESSAGES/django.po b/rest_framework/locale/hu/LC_MESSAGES/django.po index 401bc994..d37e1042 100644 --- a/rest_framework/locale/hu/LC_MESSAGES/django.po +++ b/rest_framework/locale/hu/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Hungarian (http://www.transifex.com/projects/p/django-rest-framework/language/hu/)\n" +"Language-Team: Hungarian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/hu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Érvénytelen basic fejlécmező. Nem voltak megadva azonosítók." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Érvénytelen basic fejlécmező. Az azonosító karakterlánc nem tartalmazhat szóközöket." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Érvénytelen basic fejlécmező. Az azonosítók base64 kódolása nem megfelelő." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Érvénytelen felhasználónév/jelszó." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "A felhasználó nincs aktiválva vagy törölve lett." @@ -46,7 +46,12 @@ msgstr "Érvénytelen token fejlécmező. Nem voltak megadva azonosítók." msgid "Invalid token header. Token string should not contain spaces." msgstr "Érvénytelen token fejlécmező. A token karakterlánc nem tartalmazhat szóközöket." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Érvénytelen token." @@ -62,261 +67,309 @@ msgstr "A megadott azonosítókkal nem lehet bejelentkezni." msgid "Must include \"username\" and \"password\"." msgstr "Tartalmaznia kell a \"felhasználónevet\" és a \"jelszót\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Szerver oldali hiba történt." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Hibás kérés." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Hibás azonosítók." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Nem voltak megadva azonosítók." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Nincs jogosultsága a művelet végrehajtásához." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Nem található." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "A \"{method}\" metódus nem megengedett." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "A kérés Accept fejlécmezőjét nem lehetett kiszolgálni." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Nem támogatott média típus \"{media_type}\" a kérésben." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "A kérés korlátozva lett." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Ennek a mezőnek a megadása kötelező." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Ez a mező nem lehet null értékű." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "Az \"{input}\" nem egy érvényes logikai érték." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Ez a mező nem lehet üres." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Bizonyosodjon meg arról, hogy ez a mező legfeljebb {max_length} karakterből áll." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Bizonyosodjon meg arról, hogy ez a mező legalább {min_length} karakterből áll." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Adjon meg egy érvényes e-mail címet!" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Ez az érték nem illeszkedik a szükséges mintázatra." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Az URL barát cím csak betűket, számokat, aláhúzásokat és kötőjeleket tartalmazhat." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Adjon meg egy érvényes URL-t!" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Egy érvényes egész szám megadása szükséges." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Bizonyosodjon meg arról, hogy ez az érték legfeljebb {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Bizonyosodjon meg arról, hogy ez az érték legalább {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "A karakterlánc túl hosszú." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Egy érvényes szám megadása szükséges." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Bizonyosodjon meg arról, hogy a számjegyek száma összesen legfeljebb {max_digits}." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Bizonyosodjon meg arról, hogy a tizedes tört törtrészében levő számjegyek száma összesen legfeljebb {max_decimal_places}." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Bizonyosodjon meg arról, hogy a tizedes tört egész részében levő számjegyek száma összesen legfeljebb {max_whole_digits}." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "A dátum formátuma hibás. Használja ezek valamelyikét helyette: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Időt is tartalmazó dátum helyett egy időt nem tartalmazó dátum lett elküldve." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "A dátum formátuma hibás. Használja ezek valamelyikét helyette: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Időt nem tartalmazó dátum helyett egy időt is tartalmazó dátum lett elküldve." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Az idő formátuma hibás. Használja ezek valamelyikét helyette: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "Az \"{input}\" nem egy érvényes elem." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Elemek listája helyett \"{input_type}\" lett elküldve." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Semmilyen fájl sem került feltöltésre." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Az elküldött adat nem egy fájl volt. Ellenőrizze a kódolás típusát az űrlapon!" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "A fájlnév nem megállapítható." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "A küldött fájl üres." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Bizonyosodjon meg arról, hogy a fájlnév legfeljebb {max_length} karakterből áll (jelenlegi hossza: {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Töltsön fel egy érvényes képfájlt! A feltöltött fájl nem kép volt, vagy megsérült." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Érvénytelen oldal \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Érvénytelen pk \"{pk_value}\" - az objektum nem létezik." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Helytelen típus. pk érték helyett {data_type} lett elküldve." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Érvénytelen link - Nem illeszkedő URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Érvénytelen link. - Eltérő URL illeszkedés." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Érvénytelen link - Az objektum nem létezik." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Helytelen típus. URL karakterlánc helyett {data_type} lett elküldve." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Nem létezik olyan objektum, amelynél {slug_name}={value}." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Érvénytelen érték." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Érvénytelen adat. Egy dictionary helyett {datatype} lett elküldve." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Ennek a mezőnek egyedinek kell lennie." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "A {field_names} mezőnevek nem tartalmazhatnak duplikátumot." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "A mezőnek egyedinek kell lennie a \"{date_field}\" dátumra." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "A mezőnek egyedinek kell lennie a \"{date_field}\" hónapra." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "A mezőnek egyedinek kell lennie a \"{date_field}\" évre." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Érvénytelen verzió az \"Accept\" fejlécmezőben." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Érvénytelen verzió az URL elérési útban." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Érvénytelen verzió a hosztnévben." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Érvénytelen verzió a lekérdezési paraméterben." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/id/LC_MESSAGES/django.mo b/rest_framework/locale/id/LC_MESSAGES/django.mo index 74ef4261..ac3fe2c0 100644 Binary files a/rest_framework/locale/id/LC_MESSAGES/django.mo and b/rest_framework/locale/id/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/id/LC_MESSAGES/django.po b/rest_framework/locale/id/LC_MESSAGES/django.po index 34c0ae55..5e02437e 100644 --- a/rest_framework/locale/id/LC_MESSAGES/django.po +++ b/rest_framework/locale/id/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Indonesian (http://www.transifex.com/projects/p/django-rest-framework/language/id/)\n" +"Language-Team: Indonesian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/id/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: id\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/it/LC_MESSAGES/django.mo b/rest_framework/locale/it/LC_MESSAGES/django.mo index 010556ec..fde0bde4 100644 Binary files a/rest_framework/locale/it/LC_MESSAGES/django.mo and b/rest_framework/locale/it/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/it/LC_MESSAGES/django.po b/rest_framework/locale/it/LC_MESSAGES/django.po index 63fe0d4a..4889f61b 100644 --- a/rest_framework/locale/it/LC_MESSAGES/django.po +++ b/rest_framework/locale/it/LC_MESSAGES/django.po @@ -5,38 +5,39 @@ # Translators: # Antonio Mancina , 2015 # Mattia Procopio , 2015 +# Sergio Morstabilini , 2015 # Xavier Ordoquy , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Italian (http://www.transifex.com/projects/p/django-rest-framework/language/it/)\n" +"Language-Team: Italian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Header di base invalido. Credenziali non fornite." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Header di base invalido. Le credenziali non dovrebbero contenere spazi." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Credenziali non correttamente codificate in base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Nome utente/password non validi" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Utente inattivo o eliminato." @@ -48,7 +49,12 @@ msgstr "Header del token non valido. Credenziali non fornite." msgid "Invalid token header. Token string should not contain spaces." msgstr "Header del token non valido. Il contenuto del token non dovrebbe contenere spazi." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Token invalido." @@ -58,319 +64,367 @@ msgstr "L'account dell'utente è disabilitato" #: authtoken/serializers.py:23 msgid "Unable to log in with provided credentials." -msgstr "Impossibile eseguire il log in con le credenziali immesse." +msgstr "Impossibile eseguire il login con le credenziali immesse." #: authtoken/serializers.py:26 msgid "Must include \"username\" and \"password\"." msgstr "Deve includere \"nome utente\" e \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Errore del server." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Richiesta malformata." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Credenziali di autenticazione incorrette." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Non sono state immesse le credenziali di autenticazione." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Non hai l'autorizzazione per eseguire questa azione." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Non trovato." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Metodo \"{method}\" non consentito" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Impossibile soddisfare l'header \"Accept\" presente nella richiesta." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Tipo di media \"{media_type}\"non supportato." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "La richiesta è stata limitata (throttled)." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Campo obbligatorio." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." -msgstr "Il campo non puà essere nullo." +msgstr "Il campo non può essere nullo." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" non è un valido valore booleano." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Questo campo non può essere omesso." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Assicurati che questo campo non abbia più di {max_length} caratteri." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Assicurati che questo campo abbia almeno {min_length} caratteri." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Inserisci un indirizzo email valido." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Questo valore non corrisponde alla sequenza richiesta." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Immetti uno \"slug\" valido che consista di lettere, numeri, underscore o trattini." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Inserisci un URL valido" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" non è un UUID valido." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "È richiesto un numero intero valido." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Assicurati che il valore sia minore o uguale a {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Assicurati che il valore sia maggiore o uguale a {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Stringa troppo lunga." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "È richiesto un numero valido." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Assicurati che non ci siano più di {max_digits} cifre in totale." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Assicurati che non ci siano più di {max_decimal_places} cifre decimali." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Assicurati che non ci siano più di {max_whole_digits} cifre prima del separatore decimale." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "L'oggetto di tipo datetime è in un formato errato. Usa uno dei seguenti formati: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Atteso un oggetto di tipo datetime ma l'oggetto ricevuto è di tipo date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "La data è in un formato errato. Usa uno dei seguenti formati: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Atteso un oggetto di tipo date ma l'oggetto ricevuto è di tipo datetime." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "L'orario ha un formato errato. Usa uno dei seguenti formati: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "La durata è in un formato errato. Usa uno dei seguenti formati: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" non è una scelta valida." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Attesa una lista di oggetti ma l'oggetto ricevuto è di tipo \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Non è stato inviato alcun file." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "I dati inviati non corrispondono ad un file. Si prega di controllare il tipo di codifica nel form." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Il nome del file non può essere determinato." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Il file inviato è vuoto." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Assicurati che il nome del file abbia, al più, {max_length} caratteri (attualmente ne ha {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Invia un'immagine valida. Il file che hai inviato non era un'immagine o era corrotto." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Era atteso un dizionario di oggetti ma il dato ricevuto è di tipo \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Pagina \"{page_number}\" non valida: {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Cursore non valido" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Pk \"{pk_value}\" non valido - l'oggetto non esiste." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Tipo non corretto. Era atteso un valore pk, ma è stato ricevuto {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Collegamento non valido - Nessuna corrispondenza di URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Collegamento non valido - Corrispondenza di URL non corretta." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Collegamento non valido - L'oggetto non esiste." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Tipo non corretto. Era attesa una stringa URL, ma è stato ricevuto {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "L'oggetto con {slug_name}={value} non esiste." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Valore non valido." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Dati non validi. Era atteso un dizionario, ma si è ricevuto {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "Nessuno" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "Nessun elemento da selezionare." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Questo campo deve essere unico." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "I campi {field_names} devono costituire un insieme unico." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Questo campo deve essere unico per la data \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Questo campo deve essere unico per il mese \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Questo campo deve essere unico per l'anno \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Versione non valida nell'header \"Accept\"." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Versione non valida nella sequenza URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Versione non valida nel nome dell'host." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Versione non valida nel parametro della query." -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "Permesso negato." diff --git a/rest_framework/locale/ja/LC_MESSAGES/django.mo b/rest_framework/locale/ja/LC_MESSAGES/django.mo new file mode 100644 index 00000000..4a583925 Binary files /dev/null and b/rest_framework/locale/ja/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ja/LC_MESSAGES/django.po b/rest_framework/locale/ja/LC_MESSAGES/django.po new file mode 100644 index 00000000..ea9ba172 --- /dev/null +++ b/rest_framework/locale/ja/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Japanese (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ja/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "不正な基本ヘッダです。認証情報が含まれていません。" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "不正な基本ヘッダです。認証情報文字列に空白を含めてはいけません。" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "不正な基本ヘッダです。認証情報がBASE64で正しくエンコードされていません。" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "ユーザ名かパスワードが違います。" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "ユーザが無効か削除されています。" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "不正なトークンヘッダです。認証情報が含まれていません。" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "不正なトークンヘッダです。トークン文字列に空白を含めてはいけません。" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "不正なトークンヘッダです。トークン文字列に不正な文字を含めてはいけません。" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "不正なトークンです。" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "ユーザアカウントが無効化されています。" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "提供された認証情報でログインできません。" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "\"username\"と\"password\"を含まなければなりません。" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "サーバエラーが発生しました。" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "不正な形式のリクエストです。" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "認証情報が正しくありません。" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "認証情報が含まれていません。" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "このアクションを実行する権限がありません。" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "見つかりませんでした。" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "メソッド \"{method}\" は許されていません。" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "リクエストのAcceptヘッダを満たすことができませんでした。" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "リクエストのメディアタイプ \"{media_type}\" はサポートされていません。" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "リクエストの処理は絞られました。" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "この項目は必須です。" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "この項目はnullにできません。" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "\"{input}\" は有効なブーリアンではありません。" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "この項目は空にできません。" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "この項目が{max_length}文字より長くならないようにしてください。" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "この項目は少なくとも{min_length}文字以上にしてください。" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "有効なメールアドレスを入力してください。" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "この値は所要のパターンにマッチしません。" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "文字、数字、アンダースコア、またはハイフンから成る有効な \"slug\" を入力してください。" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "有効なURLを入力してください。" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "\"{value}\" は有効なUUIDではありません。" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "有効なIPv4またはIPv6アドレスを入力してください。" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "有効な整数を入力してください。" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "この値は{max_value}以下にしてください。" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "この値は{min_value}以上にしてください。" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "文字列が長過ぎます。" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "有効な数値を入力してください。" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "合計で最大{max_digits}桁以下になるようにしてください。" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "小数点以下の桁数を{max_decimal_places}を超えないようにしてください。" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "整数部の桁数を{max_whole_digits}を超えないようにしてください。" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "日時の形式が違います。以下のどれかの形式にしてください: {format}。" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "日付ではなく日時を入力してください。" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "日付の形式が違います。以下のどれかの形式にしてください: {format}。" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "日時ではなく日付を入力してください。" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "時刻の形式が違います。以下のどれかの形式にしてください: {format}。" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "機関の形式が違います。以下のどれかの形式にしてください: {format}。" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "\"{input}\"は有効な選択肢ではありません。" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "\"{input_type}\" 型のデータではなく項目のリストを入力してください。" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "空でない項目を選択してください。" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\"は有効なパスの選択肢ではありません。" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "ファイルが添付されていません。" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "添付されたデータはファイルではありません。フォームのエンコーディングタイプを確認してください。" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "ファイル名が取得できませんでした。" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "添付ファイルの中身が空でした。" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "ファイル名は最大{max_length}文字にしてください({length}文字でした)。" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "有効な画像をアップロードしてください。アップロードされたファイルは画像でないか壊れた画像です。" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "リストは空ではいけません。" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "\"{input_type}\" 型のデータではなく項目の辞書を入力してください。" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "ページ番号 \"{page_number}\" は不正です: {message}。" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "カーソルが不正です。" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "主キー \"{pk_value}\" は不正です - データが存在しません。" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "不正な型です。{data_type} 型ではなく主キーの値を入力してください。" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "ハイパーリンクが不正です - URLにマッチしません。" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "ハイパーリンクが不正です - 不正なURLにマッチします。" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "ハイパーリンクが不正です - リンク先が存在しません。" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "不正なデータ型です。{data_type} 型ではなくURL文字列を入力してください。" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "{slug_name}={value} のデータが存在しません。" + +#: relations.py:392 +msgid "Invalid value." +msgstr "不正な値です。" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "不正なデータです。{datatype} 型ではなく辞書を入力してください。" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "なし" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "選択する項目がありません。" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "この項目は一意でなければなりません。" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "項目 {field_names} は一意な組でなければなりません。" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "この項目は \"{date_field}\" の日に対して一意でなければなりません。" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "この項目は \"{date_field}\" の月に対して一意でなければなりません。" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "この項目は \"{date_field}\" の年に対して一意でなければなりません。" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "\"Accept\" 内のバージョンが不正です。" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "URLパス内のバージョンが不正です。" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "ホスト名内のバージョンが不正です。" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "クエリパラメータ内のバージョンが不正です。" + +#: views.py:88 +msgid "Permission denied." +msgstr "権限がありません。" diff --git a/rest_framework/locale/ko_KR/LC_MESSAGES/django.mo b/rest_framework/locale/ko_KR/LC_MESSAGES/django.mo index bd84d42e..f9a7261f 100644 Binary files a/rest_framework/locale/ko_KR/LC_MESSAGES/django.mo and b/rest_framework/locale/ko_KR/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework/locale/ko_KR/LC_MESSAGES/django.po index c1b1f7e1..901907c8 100644 --- a/rest_framework/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework/locale/ko_KR/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Korean (Korea) (http://www.transifex.com/projects/p/django-rest-framework/language/ko_KR/)\n" +"Language-Team: Korean (Korea) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ko_KR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ko_KR\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "기본 헤더(basic header)가 유효하지 않습니다. 인증데이터(credentials)가 제공되지 않았습니다." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "기본 헤더(basic header)가 유효하지 않습니다. 인증데이터(credentials) 문자열은 빈칸(spaces)을 포함하지 않아야 합니다." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "기본 헤더(basic header)가 유효하지 않습니다. 인증데이터(credentials)가 base64로 적절히 부호화(encode)되지 않았습니다." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "아이디/비밀번호가 유효하지 않습니다." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "계정이 중지되었거나 삭제되었습니다." @@ -46,7 +46,12 @@ msgstr "토큰 헤더가 유효하지 않습니다. 인증데이터(credentials) msgid "Invalid token header. Token string should not contain spaces." msgstr "토큰 헤더가 유효하지 않습니다. 토큰 문자열은 빈칸(spaces)를 포함하지 않아야 합니다." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "토큰 헤더가 유효하지 않습니다. 토큰 문자열은 유효하지 않은 문자를 포함하지 않아야 합니다." + +#: authentication.py:185 msgid "Invalid token." msgstr "토큰이 유효하지 않습니다." @@ -62,261 +67,309 @@ msgstr "제공된 인증데이터(credentials)로는 로그인할 수 없습니 msgid "Must include \"username\" and \"password\"." msgstr "\"아이디\"와 \"비밀번호\"를 포함해야 합니다." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "서버 장애가 발생했습니다." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "잘못된 요청입니다." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "자격 인증데이터(authentication credentials)가 정확하지 않습니다." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "자격 인증데이터(authentication credentials)가 제공되지 않았습니다." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "이 작업을 " -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "찾을 수 없습니다." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "메소드(Method) \"{method}\"는 허용되지 않습니다." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Accept header 요청을 만족할 수 없습니다." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "요청된 \"{media_type}\"가 지원되지 않는 미디어 형태입니다." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "요청이 지연(throttled)되었습니다." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "이 항목을 채워주십시오." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "이 칸은 null일 수 없습니다." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\"이 유효하지 않은 부울(boolean)입니다." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "이 칸은 blank일 수 없습니다." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "이 칸이 글자 수가 {max_length} 이하인지 확인하십시오." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "이 칸이 글자 수가 적어도 {min_length} 이상인지 확인하십시오." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "유효한 이메일 주소를 입력하십시오." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "형식에 맞지 않는 값입니다." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "문자, 숫자, 밑줄( _ ) 또는 하이픈( - )으로 이루어진 유효한 \"slug\"를 입력하십시오." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "유효한 URL을 입력하십시오." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\"가 유효하지 않은 UUID 입니다." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "유효한 IPv4 또는 IPv6 주소를 입력하십시오." + +#: fields.py:816 msgid "A valid integer is required." msgstr "유효한 정수(integer)를 넣어주세요." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "이 값이 {max_value}보다 작거나 같은지 확인하십시오." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "이 값이 {min_value}보다 크거나 같은지 확인하십시오." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "문자열 값이 너무 큽니다." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "유효한 숫자를 넣어주세요." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "전체 숫자(digits)가 {max_digits} 이하인지 확인하십시오." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "소수점 자릿수가 {max_decimal_places} 이하인지 확인하십시오." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "소수점 자리 앞에 숫자(digits)가 {max_whole_digits} 이하인지 확인하십시오." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datetime의 포멧이 잘못되었습니다. 이 형식들 중 한가지를 사용하세요: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "예상된 datatime 대신 date를 받았습니다." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Date의 포멧이 잘못되었습니다. 이 형식들 중 한가지를 사용하세요: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "예상된 date 대신 datetime을 받았습니다." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Time의 포멧이 잘못되었습니다. 이 형식들 중 한가지를 사용하세요: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\"이 유효하지 않은 선택(choice)입니다." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "아이템 리스트가 예상되었으나 \"{input_type}\"를 받았습니다." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "파일이 제출되지 않았습니다." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "제출된 데이터는 파일이 아닙니다. 제출된 서식의 인코딩 형식을 확인하세요." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "파일명을 알 수 없습니다." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "제출된 파일이 비어있습니다." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "이 파일명의 글자수가 최대 {max_length}를 넘지 않는지 확인하십시오. (이것은 {length}가 있습니다)." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "유효한 이미지 파일을 업로드 하십시오. 업로드 하신 파일은 이미지 파일이 아니거나 손상된 이미지 파일입니다." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "아이템 딕셔너리가 예상되었으나 \"{input_type}\" 타입을 받았습니다." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "유효하지 않은 page \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "커서(cursor)가 유효하지 않습니다." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "유효하지 않은 pk \"{pk_value}\" - 객체가 존재하지 않습니다." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "잘못된 형식입니다. pk 값 대신 {data_type}를 받았습니다." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "유효하지 않은 하이퍼링크 - 일치하는 URL이 없습니다." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "유효하지 않은 하이퍼링크 - URL이 일치하지 않습니다." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "유효하지 않은 하이퍼링크 - 객체가 존재하지 않습니다." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "잘못된 형식입니다. URL 문자열을 예상했으나 {data_type}을 받았습니다." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "{slug_name}={value} 객체가 존재하지 않습니다." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "값이 유효하지 않습니다." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "유효하지 않은 데이터. 딕셔너리(dictionary)대신 {datatype}를 받았습니다." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -327,48 +380,48 @@ msgstr "" #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "선택할 아이템이 없습니다." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "이 칸은 반드시 고유해야 합니다." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "\"Accept\" header내 버전이 유효하지 않습니다." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "URL path내 버전이 유효하지 않습니다." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "hostname내 버전이 유효하지 않습니다." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "쿼리 파라메터내 버전이 유효하지 않습니다." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/mk/LC_MESSAGES/django.mo b/rest_framework/locale/mk/LC_MESSAGES/django.mo index c69475fc..64ef673c 100644 Binary files a/rest_framework/locale/mk/LC_MESSAGES/django.mo and b/rest_framework/locale/mk/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/mk/LC_MESSAGES/django.po b/rest_framework/locale/mk/LC_MESSAGES/django.po index b8f830bb..554460c6 100644 --- a/rest_framework/locale/mk/LC_MESSAGES/django.po +++ b/rest_framework/locale/mk/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Macedonian (http://www.transifex.com/projects/p/django-rest-framework/language/mk/)\n" +"Language-Team: Macedonian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/mk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: mk\n" "Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Невалиден основен header. Не се внесени податоци за автентикација." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Невалиден основен header. Автентикационата низа не треба да содржи празни места." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Невалиден основен header. Податоците за автентикација не се енкодирани со base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Невалидно корисничко име/лозинка." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Корисникот е деактивиран или избришан." @@ -46,7 +46,12 @@ msgstr "Невалиден токен header. Не се внесени пода msgid "Invalid token header. Token string should not contain spaces." msgstr "Невалиден токен во header. Токенот не треба да содржи празни места." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Невалиден токен." @@ -62,261 +67,309 @@ msgstr "Не може да се најавите со податоците за msgid "Must include \"username\" and \"password\"." msgstr "Мора да се внесе „username“ и „password“." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Настана серверска грешка." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Неправилен request." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Неточни податоци за најава." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Не се внесени податоци за најава." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Немате дозвола да го сторите ова." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Не е пронајдено ништо." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Методата \"{method}\" не е дозволена." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Не може да се исполни барањето на Accept header-от." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Media типот „{media_type}“ не е поддржан." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Request-от е забранет заради ограничувања." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Ова поле е задолжително." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Ова поле не смее да биде недефинирано." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" не е валиден boolean." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Ова поле не смее да биде празно." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Ова поле не смее да има повеќе од {max_length} знаци." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Ова поле мора да има барем {min_length} знаци." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Внесете валидна email адреса." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Ова поле не е по правилната шема/барање." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Внесете валидно име што содржи букви, бројки, долни црти или црти." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Внесете валиден URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Задолжителен е валиден цел број." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Вредноста треба да биде помала или еднаква на {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Вредноста треба да биде поголема или еднаква на {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Вредноста е преголема." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Задолжителен е валиден број." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Не смее да има повеќе од {max_digits} цифри вкупно." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Не смее да има повеќе од {max_decimal_places} децимални места." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Не смее да има повеќе од {max_whole_digits} цифри пред децималната точка." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Датата и времето се со погрешен формат. Користете го овој формат: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Очекувано беше дата и време, а внесено беше само дата." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Датата е со погрешен формат. Користете го овој формат: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Очекувана беше дата, а внесени беа и дата и време." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Времето е со погрешен формат. Користете го овој формат: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "„{input}“ не е валиден избор." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Очекувана беше листа, а внесено беше „{input_type}“." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Ниеден фајл не е качен (upload-иран)." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Испратените податоци не се фајл. Проверете го encoding-от на формата." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Не може да се открие име на фајлот." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Качениот (upload-иран) фајл е празен." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Името на фајлот треба да има највеќе {max_length} знаци (а има {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Качете (upload-ирајте) валидна слика. Фајлот што го качивте не е валидна слика или е расипан." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Невалидна страна „{page_number}“: {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Невалиден pk „{pk_value}“ - објектот не постои." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Неточен тип. Очекувано беше pk, а внесено {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Невалиден хиперлинк - не е внесен URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Невалиден хиперлинк - внесен е неправилен URL." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Невалиден хиперлинк - Објектот не постои." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Неточен тип. Очекувано беше URL, a внесено {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Објектот со {slug_name}={value} не постои." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Невалидна вредност." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Невалидни податоци. Очекуван беше dictionary, а внесен {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Ова поле мора да биде уникатно." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Полињата {field_names} заедно мора да формираат уникатен збир." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Ова поле мора да биде уникатно за „{date_field}“ датата." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Ова поле мора да биде уникатно за „{date_field}“ месецот." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Ова поле мора да биде уникатно за „{date_field}“ годината." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Невалидна верзија во „Accept“ header-от." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Невалидна верзија во URL патеката." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Невалидна верзија во hostname-от." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Невалидна верзија во query параметарот." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/nb/LC_MESSAGES/django.mo b/rest_framework/locale/nb/LC_MESSAGES/django.mo index 74b592f9..56b7a969 100644 Binary files a/rest_framework/locale/nb/LC_MESSAGES/django.mo and b/rest_framework/locale/nb/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/nb/LC_MESSAGES/django.po b/rest_framework/locale/nb/LC_MESSAGES/django.po index e2110d90..34b52715 100644 --- a/rest_framework/locale/nb/LC_MESSAGES/django.po +++ b/rest_framework/locale/nb/LC_MESSAGES/django.po @@ -3,371 +3,425 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Petter Kjelkenes , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Norwegian Bokmål (http://www.transifex.com/projects/p/django-rest-framework/language/nb/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 15:34+0000\n" +"Last-Translator: Petter Kjelkenes \n" +"Language-Team: Norwegian Bokmål (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/nb/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." -msgstr "" +msgstr "Ugyldig basic header. Ingen legitimasjon gitt." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." -msgstr "" +msgstr "Ugylid basic header. Legitimasjonsstreng bør ikke inneholde mellomrom." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." -msgstr "" +msgstr "Ugyldig basic header. Legitimasjonen ikke riktig Base64 kodet." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." -msgstr "" +msgstr "Ugyldig brukernavn eller passord." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." -msgstr "" +msgstr "Bruker inaktiv eller slettet." #: authentication.py:167 msgid "Invalid token header. No credentials provided." -msgstr "" +msgstr "Ugyldig token header. Ingen legitimasjon gitt." #: authentication.py:170 msgid "Invalid token header. Token string should not contain spaces." -msgstr "" +msgstr "Ugyldig token header. Token streng skal ikke inneholde mellomrom." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Ugyldig token header. Tokenstrengen skal ikke inneholde ugyldige tegn." + +#: authentication.py:185 msgid "Invalid token." -msgstr "" +msgstr "Ugyldig token." #: authtoken/serializers.py:20 msgid "User account is disabled." -msgstr "" +msgstr "Brukerkonto er deaktivert." #: authtoken/serializers.py:23 msgid "Unable to log in with provided credentials." -msgstr "" +msgstr "Kan ikke logge inn med gitt legitimasjon." #: authtoken/serializers.py:26 msgid "Must include \"username\" and \"password\"." -msgstr "" +msgstr "Må inkludere \"username\" og \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." -msgstr "" +msgstr "En serverfeil skjedde." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." -msgstr "" +msgstr "Misformet forespørsel." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." -msgstr "" +msgstr "Ugyldig autentiseringsinformasjon." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." -msgstr "" +msgstr "Manglende autentiseringsinformasjon." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." -msgstr "" +msgstr "Du har ikke tilgang til å utføre denne handlingen." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." -msgstr "" - -#: exceptions.py:98 -#, python-brace-format -msgid "Method \"{method}\" not allowed." -msgstr "" +msgstr "Ikke funnet." #: exceptions.py:109 -msgid "Could not satisfy the request Accept header." -msgstr "" +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "Metoden \"{method}\" ikke gyldig." -#: exceptions.py:121 +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "Kunne ikke tilfredsstille request Accept header." + +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." -msgstr "" +msgstr "Ugyldig media type \"{media_type}\" i request." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." -msgstr "" +msgstr "Forespørselen ble strupet." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." -msgstr "" +msgstr "Dette feltet er påkrevd." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." -msgstr "" +msgstr "Dette feltet må ikke være tomt." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." -msgstr "" +msgstr "\"{input}\" er ikke en gyldig bolsk verdi." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." -msgstr "" +msgstr "Dette feltet må ikke være blankt." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." -msgstr "" +msgstr "Forsikre deg om at dette feltet ikke har mer enn {max_length} tegn." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." -msgstr "" +msgstr "Forsikre deg at dette feltet har minst {min_length} tegn." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." -msgstr "" +msgstr "Oppgi en gyldig epost-adresse." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." -msgstr "" +msgstr "Denne verdien samsvarer ikke med de påkrevde mønsteret." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." -msgstr "" +msgstr "Skriv inn en gyldig \"slug\" som består av bokstaver, tall, understrek eller bindestrek." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." -msgstr "" +msgstr "Skriv inn en gyldig URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." -msgstr "" +msgstr "\"{value}\" er ikke en gyldig UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Skriv inn en gyldig IPv4 eller IPv6-adresse." + +#: fields.py:816 msgid "A valid integer is required." -msgstr "" +msgstr "En gyldig heltall er nødvendig." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." -msgstr "" +msgstr "Sikre denne verdien er mindre enn eller lik {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." -msgstr "" +msgstr "Sikre denne verdien er større enn eller lik {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." -msgstr "" +msgstr "Strengverdien for stor." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." -msgstr "" +msgstr "Et gyldig nummer er nødvendig." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." -msgstr "" +msgstr "Pass på at det ikke er flere enn {max_digits} siffer totalt." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." -msgstr "" +msgstr "Pass på at det ikke er flere enn {max_decimal_places} desimaler." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." -msgstr "" +msgstr "Pass på at det ikke er flere enn {max_whole_digits} siffer før komma." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Datetime har feil format. Bruk et av disse formatene i stedet: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." -msgstr "" +msgstr "Forventet en datetime, men fikk en date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Dato har feil format. Bruk et av disse formatene i stedet: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." -msgstr "" +msgstr "Forventet en date, men fikk en datetime." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Tid har feil format. Bruk et av disse formatene i stedet: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Varighet har feil format. Bruk et av disse formatene i stedet: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." -msgstr "" +msgstr "\"{input}\" er ikke et gyldig valg." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Mer enn {count} elementer ..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." -msgstr "" +msgstr "Forventet en liste over elementer, men fikk type \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Dette valget kan ikke være tomt." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" er ikke en gyldig bane valg." + +#: fields.py:1339 msgid "No file was submitted." -msgstr "" +msgstr "Ingen fil ble sendt." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." -msgstr "" +msgstr "De innsendte data var ikke en fil. Kontroller kodingstypen på skjemaet." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." -msgstr "" +msgstr "Kunne ikke finne filnavn." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." -msgstr "" +msgstr "Den innsendte filen er tom." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." -msgstr "" +msgstr "Sikre dette filnavnet har på det meste {max_length} tegn (det har {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." -msgstr "" +msgstr "Last opp et gyldig bilde. Filen du lastet opp var enten ikke et bilde eller en ødelagt bilde." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Denne listen kan ikke være tom." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." -msgstr "" +msgstr "Forventet en dictionary av flere ting, men fikk typen \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Verdien må være gyldig JSON." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Send inn" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." -msgstr "" +msgstr "Ugyldig side \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" -msgstr "" +msgstr "Ugyldig markør" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." -msgstr "" +msgstr "Ugyldig pk \"{pk_value}\" - objektet eksisterer ikke." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." -msgstr "" +msgstr "Feil type. Forventet pk verdi, fikk {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." -msgstr "" +msgstr "Ugyldig hyperkobling - No URL match." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." -msgstr "" +msgstr "Ugyldig hyperkobling - Incorrect URL match." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." -msgstr "" +msgstr "Ugyldig hyperkobling - Objektet eksisterer ikke." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." -msgstr "" +msgstr "Feil type. Forventet URL streng, fikk {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." -msgstr "" +msgstr "Objekt med {slug_name}={value} finnes ikke." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." -msgstr "" +msgstr "Ugyldig verdi." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." -msgstr "" +msgstr "Ugyldige data. Forventet en dicitonary, men fikk {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtre" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Feltfiltre" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Sortering" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Søk" #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "Ingen" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "Ingenting å velge." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." -msgstr "" +msgstr "Dette feltet må være unikt." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." -msgstr "" +msgstr "Feltene {field_names} må gjøre et unikt sett." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." -msgstr "" +msgstr "Dette feltet må være unikt for \"{date_field}\" dato." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." -msgstr "" +msgstr "Dette feltet må være unikt for \"{date_field}\" måned." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." -msgstr "" +msgstr "Dette feltet må være unikt for \"{date_field}\" år." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." -msgstr "" +msgstr "Ugyldig versjon på \"Accept\" header." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." -msgstr "" +msgstr "Ugyldig versjon i URL-banen." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." -msgstr "" +msgstr "Ugyldig versjon i vertsnavn." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." -msgstr "" +msgstr "Ugyldig versjon i søkeparameter." -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "Tillatelse avslått." diff --git a/rest_framework/locale/nl/LC_MESSAGES/django.mo b/rest_framework/locale/nl/LC_MESSAGES/django.mo index 594bf502..7cb2a85e 100644 Binary files a/rest_framework/locale/nl/LC_MESSAGES/django.mo and b/rest_framework/locale/nl/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/nl/LC_MESSAGES/django.po b/rest_framework/locale/nl/LC_MESSAGES/django.po index 36903254..f53b6097 100644 --- a/rest_framework/locale/nl/LC_MESSAGES/django.po +++ b/rest_framework/locale/nl/LC_MESSAGES/django.po @@ -3,371 +3,425 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# mikedingjan , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Dutch (http://www.transifex.com/projects/p/django-rest-framework/language/nl/)\n" +"Language-Team: Dutch (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." -msgstr "" +msgstr "Ongeldige basic header. Geen login gegevens opgegeven." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." -msgstr "" +msgstr "Ongeldige basic header. login gegevens kunnen geen spaties bevatten." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." -msgstr "" +msgstr "Ongeldige basic header. login gegevens zijn niet correct base64 versleuteld." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." -msgstr "" +msgstr "Ongeldige gebruikersnaam/wachtwoord." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." -msgstr "" +msgstr "Gebruiker inactief of verwijderd." #: authentication.py:167 msgid "Invalid token header. No credentials provided." -msgstr "" +msgstr "Ongeldige token header. Geen login gegevens opgegeven" #: authentication.py:170 msgid "Invalid token header. Token string should not contain spaces." +msgstr "Ongeldige token header. Token kan geen spaties bevatten." + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." msgstr "" -#: authentication.py:179 +#: authentication.py:185 msgid "Invalid token." -msgstr "" +msgstr "Ongeldige token." #: authtoken/serializers.py:20 msgid "User account is disabled." -msgstr "" +msgstr "Gebruikers account is inactief." #: authtoken/serializers.py:23 msgid "Unable to log in with provided credentials." -msgstr "" +msgstr "Kan niet inloggen met opgegeven gegevens." #: authtoken/serializers.py:26 msgid "Must include \"username\" and \"password\"." -msgstr "" +msgstr "Moet een \"gebruikersnaam\" en \"wachtwoord\" bevatten." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." -msgstr "" +msgstr "Er is een server fout opgetreden." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." -msgstr "" +msgstr "Ongeldig samengestelde request." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." -msgstr "" +msgstr "Ongeldige authenticatie gegevens." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." -msgstr "" +msgstr "Authenticatie gegevens zijn niet opgegeven." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." -msgstr "" +msgstr "Je hebt geen toegang om deze actie uit te voeren." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." -msgstr "" - -#: exceptions.py:98 -#, python-brace-format -msgid "Method \"{method}\" not allowed." -msgstr "" +msgstr "Niet gevonden." #: exceptions.py:109 -msgid "Could not satisfy the request Accept header." -msgstr "" +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "Methode \"{method}\" niet toegestaan." -#: exceptions.py:121 +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "Kan niet voldoen aan de opgegeven \"Accept\" header." + +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." -msgstr "" +msgstr "Ongeldig media type \"{media_type}\" in aanvraag." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." -msgstr "" +msgstr "Aanvraag was verstikt." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." -msgstr "" +msgstr "Dit veld is verplicht." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." -msgstr "" +msgstr "Dit veld mag niet leeg zijn." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." -msgstr "" +msgstr "\"{input}\" is een ongeldige boolean waarde." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." -msgstr "" +msgstr "Dit veld mag niet leeg zijn." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." -msgstr "" +msgstr "Zorg ervoor dat dit veld niet meer dan {max_length} karakters bevat." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." -msgstr "" +msgstr "Zorg ervoor dat dit veld minimaal {min_length} karakters bevat." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." -msgstr "" +msgstr "Voer een geldig e-mailadres in." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." -msgstr "" +msgstr "Deze waarde voldoet niet aan het benodigde formaat." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." -msgstr "" +msgstr "Voer een geldige \"slug\" in bestaande uit letters, cijfers, underscore of streepjes." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." -msgstr "" +msgstr "Voer een geldige URL in." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." +msgstr "\"{value}\" in een ongeldige UUID." + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." msgstr "" -#: fields.py:679 +#: fields.py:816 msgid "A valid integer is required." -msgstr "" +msgstr "Een geldig getal is vereist." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." -msgstr "" +msgstr "Zorg ervoor dat deze waarde minder of gelijk is aan {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." -msgstr "" +msgstr "Zorg ervoor dat deze waarde groter of gelijk is aan {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." -msgstr "" +msgstr "Tekstuele waarde is te lang." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." -msgstr "" +msgstr "Een geldig nummer is verplicht." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." -msgstr "" +msgstr "Zorg ervoor dat er niet meer dan {max_digits} getallen zijn in totaal." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." -msgstr "" +msgstr "zorg ervoor dat er niet meer dan {max_decimal_places} getallen achter de komma zijn." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." -msgstr "" +msgstr "Zorg ervoor dat er niet meer dan {max_whole_digits} getallen voor de komma zijn." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Datetime heeft een ongeldig formaat, gebruik 1 van de volgende formaten: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." -msgstr "" +msgstr "Verwacht een datetime, in plaats kreeg een date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Date heeft het verkeerde formaat, gebruik 1 van de onderstaande formaten: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." -msgstr "" +msgstr "Verwacht een date, in plaats kreeg een datetime" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Time heeft het verkeerde formaat, gebruik 1 van onderstaande formaten: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Tijdsduur heeft een verkeerd formaat, gebruik 1 van onderstaande formaten: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." +msgstr "\"{input}\" is een ongeldige keuze." + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "Verwacht een lijst met items, kreeg een type \"{input_type}\" in plaats." + +#: fields.py:1283 +msgid "This selection may not be empty." msgstr "" -#: fields.py:1129 +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." -msgstr "" +msgstr "Er is geen bestand opgestuurd" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." -msgstr "" +msgstr "De verstuurde data was geen bestand. Controleer de encoding type op het formulier." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." -msgstr "" +msgstr "Bestandsnaam kan niet vastgesteld worden." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." -msgstr "" +msgstr "Het verstuurde bestand is leeg." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." -msgstr "" +msgstr "Zorg ervoor dat deze bestandsnaam minstens {max_length} karakters heeft (momenteel {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." +msgstr "Upload een geldige afbeelding, de geüploade afbeelding is geen afbeelding of mogelijk corrupt geraakt," + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." msgstr "" -#: fields.py:1250 +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "Verwacht een dictionary van items, in plaats kreeg een type \"{input_type}\"." + +#: fields.py:1530 +msgid "Value must be valid JSON." msgstr "" -#: pagination.py:231 +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." -msgstr "" +msgstr "Ongeldige pagina \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" -msgstr "" +msgstr "Ongeldige cursor." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." -msgstr "" +msgstr "Ongeldige pk \"{pk_value}\" - object bestaat niet." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." -msgstr "" +msgstr "Ongeldig type. Verwacht een pk waarde, ontving {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." -msgstr "" +msgstr "Ongeldige hyperlink - Geen overeenkomende URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." -msgstr "" +msgstr "Ongeldige hyperlink - Ongeldige URL" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." -msgstr "" +msgstr "Ongeldige hyperlink - Object bestaat niet." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." -msgstr "" +msgstr "Ongeldig type. Verwacht een URL, ontving {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." -msgstr "" +msgstr "Object met {slug_name}={value} bestaat niet." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." -msgstr "" +msgstr "Ongeldige waarde." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "Ongeldige data. Verwacht een dictionary, kreeg een {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" msgstr "" #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "Geen" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "Geen items geselecteerd." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." -msgstr "" +msgstr "Dit veld moet uniek zijn." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." -msgstr "" +msgstr "De velden {field_names} moeten een unieke set zijn." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." -msgstr "" +msgstr "Dit veld moet uniek zijn voor de \"{date_field}\" datum." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." -msgstr "" +msgstr "Dit veld moet uniek zijn voor de \"{date_field}\" maand." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." -msgstr "" +msgstr "Dit veld moet uniek zijn voor de \"{date_field}\" year." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." -msgstr "" +msgstr "Ongeldige versie in \"Accept\" header." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." -msgstr "" +msgstr "Ongeldige versie in URL pad." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." -msgstr "" +msgstr "Ongeldige versie in host naam." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." -msgstr "" +msgstr "Ongeldige versie in query parameter." -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "Toegang niet toegestaan." diff --git a/rest_framework/locale/nn/LC_MESSAGES/django.mo b/rest_framework/locale/nn/LC_MESSAGES/django.mo new file mode 100644 index 00000000..fd5f5ec2 Binary files /dev/null and b/rest_framework/locale/nn/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/nn/LC_MESSAGES/django.po b/rest_framework/locale/nn/LC_MESSAGES/django.po new file mode 100644 index 00000000..a23d8d25 --- /dev/null +++ b/rest_framework/locale/nn/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Norwegian Nynorsk (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/nn/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nn\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/no/LC_MESSAGES/django.mo b/rest_framework/locale/no/LC_MESSAGES/django.mo new file mode 100644 index 00000000..00f5db6b Binary files /dev/null and b/rest_framework/locale/no/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/no/LC_MESSAGES/django.po b/rest_framework/locale/no/LC_MESSAGES/django.po new file mode 100644 index 00000000..4342b2bd --- /dev/null +++ b/rest_framework/locale/no/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Norwegian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/no/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: no\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/pl/LC_MESSAGES/django.mo b/rest_framework/locale/pl/LC_MESSAGES/django.mo index de680d45..30e60225 100644 Binary files a/rest_framework/locale/pl/LC_MESSAGES/django.mo and b/rest_framework/locale/pl/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/pl/LC_MESSAGES/django.po b/rest_framework/locale/pl/LC_MESSAGES/django.po index 9a66c2e9..9254cb73 100644 --- a/rest_framework/locale/pl/LC_MESSAGES/django.po +++ b/rest_framework/locale/pl/LC_MESSAGES/django.po @@ -10,33 +10,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Polish (http://www.transifex.com/projects/p/django-rest-framework/language/pl/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 19:44+0000\n" +"Last-Translator: Janusz Harkot \n" +"Language-Team: Polish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Niepoprawny podstawowy nagłówek. Brak danych uwierzytelniających." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Niepoprawny podstawowy nagłówek. Ciąg znaków danych uwierzytelniających nie powinien zawierać spacji." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Niepoprawny podstawowy nagłówek. Niewłaściwe kodowanie base64 danych uwierzytelniających." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Niepoprawna nazwa użytkownika lub hasło." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Użytkownik nieaktywny lub usunięty." @@ -48,7 +48,12 @@ msgstr "Niepoprawny nagłówek tokena. Brak danych uwierzytelniających." msgid "Invalid token header. Token string should not contain spaces." msgstr "Niepoprawny nagłówek tokena. Token nie może zawierać odstępów." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Błędny nagłówek z tokenem. Token nie może zawierać błędnych znaków." + +#: authentication.py:185 msgid "Invalid token." msgstr "Niepoprawny token." @@ -64,261 +69,309 @@ msgstr "Podane dane uwierzytelniające nie pozwalają na zalogowanie." msgid "Must include \"username\" and \"password\"." msgstr "Musi zawierać \"username\" i \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Wystąpił błąd serwera." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Zniekształcone żądanie." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Błędne dane uwierzytelniające." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Nie podano danych uwierzytelniających." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Nie masz uprawnień, by wykonać tę czynność." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Nie znaleziono." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Niedozwolona metoda \"{method}\"." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Nie można zaspokoić nagłówka Accept żądania." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Brak wsparcia dla żądanego typu danych \"{media_type}\"." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Żądanie zostało zdławione." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "To pole jest wymagane." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Pole nie może mieć wartości null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" nie jest poprawną wartością logiczną." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "To pole nie może być puste." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Upewnij się, że to pole ma nie więcej niż {max_length} znaków." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Upewnij się, że pole ma co najmniej {min_length} znaków." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Podaj poprawny adres e-mail." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Ta wartość nie pasuje do wymaganego wzorca." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Wprowadź poprawną wartość pola typu \"slug\", składającą się ze znaków łacińskich, cyfr, podkreślenia lub myślnika." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Wprowadź poprawny adres URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" nie jest poprawnym UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Wprowadź poprawny adres IPv4 lub IPv6." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Wymagana poprawna liczba całkowita." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Upewnij się, że ta wartość jest mniejsza lub równa {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Upewnij się, że ta wartość jest większa lub równa {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Za długi ciąg znaków." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Wymagana poprawna liczba." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Upewnij się, że liczba ma nie więcej niż {max_digits} cyfr." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Upewnij się, że liczba ma nie więcej niż {max_decimal_places} cyfr dziesiętnych." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Upewnij się, że liczba ma nie więcej niż {max_whole_digits} cyfr całkowitych." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Wartość daty z czasem ma zły format. Użyj jednego z dostępnych formatów: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Oczekiwano datę z czasem, otrzymano tylko datę." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Data ma zły format. Użyj jednego z tych formatów: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Oczekiwano daty a otrzymano datę z czasem." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Błędny format czasu. Użyj jednego z dostępnych formatów: {format}" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Czas trwania ma zły format. Użyj w zamian jednego z tych formatów: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" nie jest poprawnym wyborem." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Więcej niż {count} elementów..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Oczekiwano listy elementów, a otrzymano dane typu \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Zaznaczenie nie może być puste." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" nie jest poprawną ścieżką." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Nie przesłano pliku." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Przesłane dane nie były plikiem. Sprawdź typ kodowania formatki." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Nie można określić nazwy pliku." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Przesłany plik jest pusty." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Upewnij się, że nazwa pliku ma długość co najwyżej {max_length} znaków (aktualnie ma {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Prześlij poprawny plik graficzny. Przesłany plik albo nie jest grafiką lub jest uszkodzony." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Lista nie może być pusta." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Oczekiwano słownika, ale otrzymano \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Wartość musi być poprawnym ciągiem znaków JSON" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Wyślij" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Niepoprawna strona \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Niepoprawny wskaźnik" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Błędny klucz główny \"{pk_value}\" - obiekt nie istnieje." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Błędny typ danych. Oczekiwano wartość klucza głównego, otrzymano {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Błędny hyperlink - nie znaleziono pasującego adresu URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Błędny hyperlink - błędne dopasowanie adresu URL." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Błędny hyperlink - obiekt nie istnieje." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Błędny typ danych. Oczekiwano adresu URL, otrzymano {data_type}" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Obiekt z polem {slug_name}={value} nie istnieje" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Niepoprawna wartość." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Niepoprawne dane. Oczekiwano słownika, otrzymano {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtry" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Pola filtrów" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Kolejność" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Szukaj" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -331,46 +384,46 @@ msgstr "None" msgid "No items to select." msgstr "Nie wybrano wartości." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Wartość dla tego pola musi być unikalna." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Pola {field_names} muszą tworzyć unikalny zestaw." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "To pole musi mieć unikalną wartość dla jednej daty z pola \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "To pole musi mieć unikalną wartość dla konkretnego miesiąca z pola \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "To pole musi mieć unikalną wartość dla konkretnego roku z pola \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Błędna wersja w nagłówku \"Accept\"." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Błędna wersja w ścieżce URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Błędna wersja w nazwie hosta." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Błędna wersja w parametrach zapytania." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Brak uprawnień." diff --git a/rest_framework/locale/pt/LC_MESSAGES/django.mo b/rest_framework/locale/pt/LC_MESSAGES/django.mo index 94357990..476e4149 100644 Binary files a/rest_framework/locale/pt/LC_MESSAGES/django.mo and b/rest_framework/locale/pt/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/pt/LC_MESSAGES/django.po b/rest_framework/locale/pt/LC_MESSAGES/django.po index f5ef5f6d..31cf0c2d 100644 --- a/rest_framework/locale/pt/LC_MESSAGES/django.po +++ b/rest_framework/locale/pt/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Portuguese (http://www.transifex.com/projects/p/django-rest-framework/language/pt/)\n" +"Language-Team: Portuguese (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/pt/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/pt_BR/LC_MESSAGES/django.mo b/rest_framework/locale/pt_BR/LC_MESSAGES/django.mo index 17918ac9..0f2dac61 100644 Binary files a/rest_framework/locale/pt_BR/LC_MESSAGES/django.mo and b/rest_framework/locale/pt_BR/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework/locale/pt_BR/LC_MESSAGES/django.po index 31a6c45e..ce372f32 100644 --- a/rest_framework/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework/locale/pt_BR/LC_MESSAGES/django.po @@ -4,38 +4,40 @@ # # Translators: # Craig Blaszczyk , 2015 +# Ederson Mota Pereira , 2015 # Filipe Rinaldi , 2015 +# Hugo Leonardo Chalhoub Mendonça , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/django-rest-framework/language/pt_BR/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 16:20+0000\n" +"Last-Translator: Craig Blaszczyk \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Cabeçalho básico inválido. Credenciais não fornecidas." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Cabeçalho básico inválido. String de credenciais não deve incluir espaços." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Cabeçalho básico inválido. Credenciais codificadas em base64 incorretamente." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." -msgstr "Usário ou senha inválido." +msgstr "Usuário ou senha inválido." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Usuário inativo ou removido." @@ -47,13 +49,18 @@ msgstr "Cabeçalho de token inválido. Credenciais não fornecidas." msgid "Invalid token header. Token string should not contain spaces." msgstr "Cabeçalho de token inválido. String de token não deve incluir espaços." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Cabeçalho de token inválido. String de token não deve possuir caracteres inválidos." + +#: authentication.py:185 msgid "Invalid token." msgstr "Token inválido." #: authtoken/serializers.py:20 msgid "User account is disabled." -msgstr "Conta de usário desabilitada." +msgstr "Conta de usuário desabilitada." #: authtoken/serializers.py:23 msgid "Unable to log in with provided credentials." @@ -63,260 +70,308 @@ msgstr "Impossível fazer login com as credenciais fornecidas." msgid "Must include \"username\" and \"password\"." msgstr "Obrigatório incluir \"usuário\" e \"senha\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Ocorreu um erro de servidor." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Pedido malformado." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Credenciais de autenticação incorretas." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "As credenciais de autenticação não foram fornecidas." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." -msgstr "Você não tem persmissao para executar essa ação." +msgstr "Você não tem permissão para executar essa ação." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Não encontrado." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Método \"{method}\" não é permitido." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Não foi possível satisfazer a requisição do cabeçalho Accept." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." -msgstr "Media type \"{media_type}\" no pedido não é suportado." +msgstr "Tipo de mídia \"{media_type}\" no pedido não é suportado." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Pedido foi limitado." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Este campo é obrigatório." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Este campo não pode ser nulo." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" não é um valor boleano válido." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Este campo não pode ser em branco." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Certifique-se de que este campo não tenha mais de {max_length} caracteres." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Certifique-se de que este campo tenha mais de {min_length} caracteres." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Insira um endereço de email válido." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Este valor não corresponde ao padrão exigido." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Entrar um \"slug\" válido que consista de letras, números, sublinhados ou hífens." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Entrar um URL válido." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." -msgstr "\"{value}\" não é um UUID valid." +msgstr "\"{value}\" não é um UUID válido." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Informe um endereço IPv4 ou IPv6 válido." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Um número inteiro válido é exigido." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Certifique-se de que este valor seja inferior ou igual a {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Certifque-se de que este valor seja maior ou igual a {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Valor da string é muito grande." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Um número válido é necessário." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Certifique-se de que não haja mais de {max_digits} dígitos no total." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Certifique-se de que não haja mais de {max_decimal_places} casas decimais." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Certifique-se de que não haja mais de {max_whole_digits} dígitos antes do ponto decimal." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Formato inválido para data e hora. Use um dos formatos a seguir: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." -msgstr "Data e hora são necessários mas apenas data foi encontrada." +msgstr "Necessário uma data e hora mas recebeu uma data." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Formato inválido para data. Use um dos formatos a seguir: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Necessário uma data mas recebeu uma data e hora." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." -msgstr "Tempo tem formato errado. Usa um desses em vez disso: {format}." +msgstr "Formato inválido para Tempo. Use um dos formatos a seguir: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Formato inválido para Duração. Use um dos formatos a seguir: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" não é um escolha válido." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Mais de {count} itens..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Necessário uma lista de itens, mas recebeu tipo \"{input_type}\"." -#: fields.py:1129 -msgid "No file was submitted." -msgstr "Ficheiro não foi submetido." +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Esta seleção não pode estar vazia." -#: fields.py:1130 +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" não é uma escolha válida para um caminho." + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "Nenhum arquivo foi submetido." + +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." -msgstr "Os dados submetidos nao foram um ficheiro. Certifique-se do tipo de codificação no formulário." +msgstr "O dado submetido não é um arquivo. Certifique-se do tipo de codificação no formulário." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Nome do arquivo não pode ser determinado." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." -msgstr "O arquivo submetido ésta vázio." +msgstr "O arquivo submetido está vázio." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." -msgstr "Certifique-se de que o nome do ficheiro tem menos de {max_length} caracteres (tem {length})." +msgstr "Certifique-se de que o nome do arquivo tem menos de {max_length} caracteres (tem {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." -msgstr "Fazer upload de um imagem válido. O arquivo mandou não foi um imagem ou foi corrupto." +msgstr "Fazer upload de uma imagem válida. O arquivo enviado não é um arquivo de imagem ou está corrompido." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Esta lista não pode estar vazia." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." -msgstr "Esperou um dicionário de itens mas recebeu tipo \"{input_type}\"." +msgstr "Esperado um dicionário de itens mas recebeu tipo \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Valor devo ser JSON válido." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Enviar" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." -msgstr "Página inválido \"{page_number}\": {message}." +msgstr "Página inválida \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" -msgstr "Cursor invalído" +msgstr "Cursor inválido" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Pk inválido \"{pk_value}\" - objeto não existe." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." -msgstr "Tipo incorreto. Necessário valor pk, recebeu {data_type}." +msgstr "Tipo incorreto. Esperado valor pk, recebeu {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." -msgstr "Hyperlink inválido - URL não combinou." +msgstr "Hyperlink inválido - Sem combinação para a URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." -msgstr "Hyperlink inválido - URL combinou errado." +msgstr "Hyperlink inválido - Combinação URL incorreta." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." -msgstr "Hyperlink inválido - objeto não existe." +msgstr "Hyperlink inválido - Objeto não existe." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Tipo incorreto. Necessário string URL, recebeu {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objeto com {slug_name}={value} não existe." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Valor inválido." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." -msgstr "Data inválido. Necessário um dicionário mas recebeu {datatype}." +msgstr "Dado inválido. Necessário um dicionário mas recebeu {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtra" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Filtra de campo" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Ordenando" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Buscar" #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 @@ -328,48 +383,48 @@ msgstr "Nenhum(a/as)" #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "Nenhum itens para escholher." +msgstr "Nenhum item para escholher." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." -msgstr "Esse campo deve ser unico." +msgstr "Esse campo deve ser único." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." -msgstr "Os campos {field_names} devem criar um set unico." +msgstr "Os campos {field_names} devem criar um set único." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." -msgstr "O campo deve ser unico pela data \"{date_field}\"." +msgstr "O campo \"{date_field}\" deve ser único para a data." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." -msgstr "O campo deve ser unico pelo anô \"{date_field}\"." +msgstr "O campo \"{date_field}\" deve ser único para o mês." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." -msgstr "O campo deve ser unico pela mês \"{date_field}\"." +msgstr "O campo \"{date_field}\" deve ser único para o ano." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." -msgstr "Versão inválido no cabeçalho \"Accept\"." +msgstr "Versão inválida no cabeçalho \"Accept\"." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." -msgstr "Versão inválido no caminho de URL." +msgstr "Versão inválida no caminho de URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." -msgstr "Versão inválido no hostname." +msgstr "Versão inválida no hostname." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Versão inválida no parâmetro de query." -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "Permissão negado." +msgstr "Permissão negada." diff --git a/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo b/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo index b5ebc169..e5484560 100644 Binary files a/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo and b/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/pt_PT/LC_MESSAGES/django.po b/rest_framework/locale/pt_PT/LC_MESSAGES/django.po index 515ae582..32cdd5c4 100644 --- a/rest_framework/locale/pt_PT/LC_MESSAGES/django.po +++ b/rest_framework/locale/pt_PT/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/django-rest-framework/language/pt_PT/)\n" +"Language-Team: Portuguese (Portugal) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/pt_PT/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_PT\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/ro/LC_MESSAGES/django.mo b/rest_framework/locale/ro/LC_MESSAGES/django.mo new file mode 100644 index 00000000..11567edc Binary files /dev/null and b/rest_framework/locale/ro/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ro/LC_MESSAGES/django.po b/rest_framework/locale/ro/LC_MESSAGES/django.po new file mode 100644 index 00000000..6d0d3d55 --- /dev/null +++ b/rest_framework/locale/ro/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Romanian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ro/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ro\n" +"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/ru/LC_MESSAGES/django.mo b/rest_framework/locale/ru/LC_MESSAGES/django.mo index 4fe15d2c..063bf0b7 100644 Binary files a/rest_framework/locale/ru/LC_MESSAGES/django.mo and b/rest_framework/locale/ru/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/ru/LC_MESSAGES/django.po b/rest_framework/locale/ru/LC_MESSAGES/django.po index f4067b4c..eae0fe28 100644 --- a/rest_framework/locale/ru/LC_MESSAGES/django.po +++ b/rest_framework/locale/ru/LC_MESSAGES/django.po @@ -10,33 +10,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Russian (http://www.transifex.com/projects/p/django-rest-framework/language/ru/)\n" +"Language-Team: Russian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Недопустимый заголовок. Не предоставлены учетные данные." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Недопустимый заголовок. Учетные данные не должны содержать пробелов." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Недопустимый заголовок. Учетные данные некорректно закодированны в base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Недопустимые имя пользователя или пароль." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Пользователь неактивен или удален." @@ -48,7 +48,12 @@ msgstr "Недопустимый заголовок токена. Не пред msgid "Invalid token header. Token string should not contain spaces." msgstr "Недопустимый заголовок токена. Токен не должен содержать пробелов." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Недопустимый токен." @@ -64,261 +69,309 @@ msgstr "Невозможно войти с предоставленными уч msgid "Must include \"username\" and \"password\"." msgstr "Должен включать \"username\" и \"password\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Произошла ошибка сервера." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Искаженный запрос." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Некорректные учетные данные." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Учетные данные не были предоставлены." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "У вас нет прав для выполнения этой операции." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Не найдено." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Метод \"{method}\" не разрешен." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Невозможно удовлетворить \"Accept\" заголовок запроса." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Неподдерживаемый тип данных \"{media_type}\" в запросе." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Запрос был проигнорирован." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Это поле обязательно." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Это поле не может быть null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" не является корректным булевым значением." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Это поле не может быть пустым." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Убедитесь что в этом поле не больше {max_length} символов." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Убедитесь что в этом поле как минимум {min_length} символов." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Введите корректный адрес электронной почты." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Значение не соответствует требуемому паттерну." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Введите корректный \"slug\", состоящий из букв, цифр, знаков подчеркивания или дефисов." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Введите корректный URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" не является корректным UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Требуется целочисленное значение." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Убедитесь что значение меньше или равно {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Убедитесь что значение больше или равно {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Слишком длинное значение." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Требуется численное значение." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Убедитесь что в числе не больше {max_digits} знаков." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Убедитесь что в числе не больше {max_decimal_places} знаков в дробной части." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Убедитесь что в цисле не больше {max_whole_digits} знаков в целой части." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Неправильный формат datetime. Используйте один из этих форматов: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Ожидался datetime, но был получен date." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Неправильный формат date. Используйте один из этих форматов: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Ожидался date, но был получен datetime." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Неправильный формат времени. Используйте один из этих форматов: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" не является корректным значением." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Ожидался list со значениями, но был получен \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Не был загружен файл." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Загруженный файл не является корректным файлом. " -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Невозможно определить имя файла." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Загруженный файл пуст." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Убедитесь что имя файла меньше {max_length} символов (сейчас {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Загрузите корректное изображение. Загруженный файл не является изображением, либо является испорченным." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Ожидался словарь со значениями, но был получен \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Недопустимая страница \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Не корректный курсор" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Недопустимый первичный ключ \"{pk_value}\" - объект не существует." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Некорректный тип. Ожилалось значение первичного ключа, получен {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Недопустимая ссылка - нет совпадения по URL." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Недопустимая ссылка - некорректное совпадение по URL," -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Недопустимая ссылка - объект не существует." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Некорректный тип. Ожидался URL, получен {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Объект с {slug_name}={value} не существует." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Недопустимое значение." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Недопустимые данные. Ожидался dictionary, но был получен {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -331,46 +384,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Это поле должно быть уникально." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Поля {field_names} должны производить массив с уникальными значениями." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Это поле должно быть уникально для даты \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Это поле должно быть уникально для месяца \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Это поле должно быть уникально для года \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Недопустимая версия в заголовке \"Accept\"." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Недопустимая версия в пути URL." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Недопустимая версия в имени хоста." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Недопустимая версия в параметре запроса." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/sk/LC_MESSAGES/django.mo b/rest_framework/locale/sk/LC_MESSAGES/django.mo index 5b23fe59..89c3f462 100644 Binary files a/rest_framework/locale/sk/LC_MESSAGES/django.mo and b/rest_framework/locale/sk/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/sk/LC_MESSAGES/django.po b/rest_framework/locale/sk/LC_MESSAGES/django.po index 10f3899c..cdd82c10 100644 --- a/rest_framework/locale/sk/LC_MESSAGES/django.po +++ b/rest_framework/locale/sk/LC_MESSAGES/django.po @@ -8,33 +8,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Slovak (http://www.transifex.com/projects/p/django-rest-framework/language/sk/)\n" +"Language-Team: Slovak (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/sk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sk\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Nesprávna hlavička. Neboli poskytnuté prihlasovacie údaje." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Nesprávna hlavička. Prihlasovacie údaje nesmú obsahovať medzery." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Nesprávna hlavička. Prihlasovacie údaje nie sú správne zakódované pomocou metódy base64." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Nesprávne prihlasovacie údaje." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Daný používateľ je neaktívny, alebo zmazaný." @@ -46,7 +46,12 @@ msgstr "Nesprávna token hlavička. Neboli poskytnuté prihlasovacie údaje." msgid "Invalid token header. Token string should not contain spaces." msgstr "Nesprávna token hlavička. Token hlavička nesmie obsahovať medzery." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "Nesprávny token." @@ -62,261 +67,309 @@ msgstr "S danými prihlasovacími údajmi nebolo možné sa prihlásiť." msgid "Must include \"username\" and \"password\"." msgstr "Musí obsahovať parametre \"používateľské meno\" a \"heslo\"." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Vyskytla sa chyba na strane servera." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Požiadavok má nesprávny formát, alebo je poškodený." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Nesprávne prihlasovacie údaje." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Prihlasovacie údaje neboli zadané." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "K danej akcii nemáte oprávnenie." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Nebolo nájdené." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Metóda \"{method}\" nie je povolená." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Nie je možné vyhovieť požiadavku v hlavičke \"Accept\"." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Požiadavok obsahuje nepodporovaný media type: \"{media_type}\"." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Požiadavok bol obmedzený, z dôvodu prekročenia limitu." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Toto pole je povinné." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Toto pole nemôže byť nulové." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" je validný boolean." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Toto pole nemože byť prázdne." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Uistite sa, že toto pole nemá viac ako {max_length} znakov." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Uistite sa, že toto pole má viac ako {min_length} znakov." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Vložte správnu emailovú adresu." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Toto pole nezodpovedá požadovanému formátu." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Zadajte platný \"slug\", ktorý obsahuje len malé písmená, čísla, spojovník alebopodtržítko." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Zadajte platnú URL adresu." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" nie je platné UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "Je vyžadované celé číslo." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Uistite sa, že hodnota je menšia alebo rovná {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Uistite sa, že hodnota je väčšia alebo rovná {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Zadaný textový reťazec je príliš dlhý." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Je vyžadované číslo." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Uistite sa, že hodnota neobsahuje viac ako {max_digits} cifier." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Uistite sa, že hodnota neobsahuje viac ako {max_decimal_places} desatinných miest." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Uistite sa, že hodnota neobsahuje viac ako {max_whole_digits} cifier pred desatinnou čiarkou." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Nesprávny formát dátumu a času. Prosím použite jeden z nasledujúcich formátov: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Vložený len dátum - date namiesto dátumu a času - datetime." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Nesprávny formát dátumu. Prosím použite jeden z nasledujúcich formátov: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Vložený dátum a čas - datetime namiesto jednoduchého dátumu - date." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Nesprávny formát času. Prosím použite jeden z nasledujúcich formátov: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" je nesprávny výber z daných možností." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Bol očakávaný zoznam položiek, no namiesto toho bol nájdený \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "Nebol odoslaný žiadny súbor." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Odoslané dáta neobsahujú súbor. Prosím skontrolujte kódovanie - encoding type daného formuláru." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Nebolo možné určiť meno súboru." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Odoslaný súbor je prázdny." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Uistite sa, že meno súboru neobsahuje viac ako {max_length} znakov. (V skutočnosti ich má {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Uploadujte prosím obrázok. Súbor, ktorý ste uploadovali buď nie je obrázok, alebo daný obrázok je poškodený." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Bol očakávaný slovník položiek, no namiesto toho bol nájdený \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Nesprávne číslo stránky \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Nesprávny kurzor." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Nesprávny primárny kľúč \"{pk_value}\" - objekt s daným primárnym kľúčom neexistuje." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Nesprávny typ. Bol prijatý {data_type} namiesto primárneho kľúča." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Nesprávny hypertextový odkaz - žiadna zhoda." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Nesprávny hypertextový odkaz - chybná URL." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Nesprávny hypertextový odkaz - požadovný objekt neexistuje." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Nesprávny typ {data_type}. Požadovaný typ: hypertextový odkaz." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objekt, ktorého atribút \"{slug_name}\" je \"{value}\" neexistuje." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Nesprávna hodnota." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Bol očakávaný slovník položiek, no namiesto toho bol nájdený \"{datatype}\"." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -329,46 +382,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Táto položka musí byť unikátna." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Dané položky: {field_names} musia tvoriť musia spolu tvoriť unikátnu množinu." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Položka musí byť pre špecifický deň \"{date_field}\" unikátna." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Položka musí byť pre mesiac \"{date_field}\" unikátna." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Položka musí byť pre rok \"{date_field}\" unikátna." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Nesprávna verzia v \"Accept\" hlavičke." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Nesprávna verzia v URL adrese." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Nesprávna verzia v \"hostname\"." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Nesprávna verzia v parametri požiadavku." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/sv/LC_MESSAGES/django.mo b/rest_framework/locale/sv/LC_MESSAGES/django.mo index 1f9c717e..a6c04ef4 100644 Binary files a/rest_framework/locale/sv/LC_MESSAGES/django.mo and b/rest_framework/locale/sv/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/sv/LC_MESSAGES/django.po b/rest_framework/locale/sv/LC_MESSAGES/django.po index 33865cda..91ee9d7a 100644 --- a/rest_framework/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework/locale/sv/LC_MESSAGES/django.po @@ -9,33 +9,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Swedish (http://www.transifex.com/projects/p/django-rest-framework/language/sv/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 16:16+0000\n" +"Last-Translator: Joakim Soderlund\n" +"Language-Team: Swedish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Ogiltig \"basic\"-header. Inga användaruppgifter tillhandahölls." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Ogiltig \"basic\"-header. Strängen för användaruppgifterna ska inte innehålla mellanslag." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Ogiltig \"basic\"-header. Användaruppgifterna är inte korrekt base64-kodade." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Ogiltigt användarnamn/lösenord." -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Användaren borttagen eller inaktiv." @@ -45,9 +45,14 @@ msgstr "Ogiltig \"token\"-header. Inga användaruppgifter tillhandahölls." #: authentication.py:170 msgid "Invalid token header. Token string should not contain spaces." -msgstr "Ogiltig \"token\"-header. Strängen för referensen ska inte innehålla mellanslag." +msgstr "Ogiltig \"token\"-header. Strängen ska inte innehålla mellanslag." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Ogiltig \"token\"-header. Strängen ska inte innehålla ogiltiga tecken." + +#: authentication.py:185 msgid "Invalid token." msgstr "Ogiltig \"token\"." @@ -63,261 +68,309 @@ msgstr "Kunde inte logga in med de angivna inloggningsuppgifterna." msgid "Must include \"username\" and \"password\"." msgstr "Användarnamn och lösenord måste anges." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Ett serverfel inträffade." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Ogiltig förfrågan." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Ogiltiga inloggningsuppgifter. " -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Autentiseringsuppgifter ej tillhandahållna." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Du har inte tillåtelse att utföra denna förfrågan." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Hittades inte." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "Metoden \"{method}\" tillåts inte." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "Kunde inte tillfredsställa förfrågans \"Accept\"-header." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "Medietypen \"{media_type}\" stöds inte." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Förfrågan stoppades eftersom du har skickat för många." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Det här fältet är obligatoriskt." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Det här fältet får inte vara null." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" är inte ett giltigt booleskt värde." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Det här fältet får inte vara blankt." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Se till att detta fält inte har fler än {max_length} tecken." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Se till att detta fält har minst {min_length} tecken." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Ange en giltig mejladress." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Det här värdet matchar inte mallen." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Ange en giltig \"slug\" bestående av bokstäver, nummer, understreck eller bindestreck." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Ange en giltig URL." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value} är inte ett giltigt UUID." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Ange en giltig IPv4- eller IPv6-adress." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Ett giltigt heltal krävs." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Se till att detta värde är mindre än eller lika med {max_value}." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Se till att detta värde är större än eller lika med {min_value}." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "Textvärdet är för långt." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Ett giltigt nummer krävs." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Se till att det inte finns fler än totalt {max_digits} siffror." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Se till att det inte finns fler än {max_decimal_places} decimaler." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Se till att det inte finns fler än {max_whole_digits} siffror före decimalpunkten." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datumtiden har fel format. Använd ett av dessa format istället: {format}." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Förväntade en datumtid men fick ett datum." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Datumet har fel format. Använde ett av dessa format istället: {format}." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Förväntade ett datum men fick en datumtid." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Tiden har fel format. Använd ett av dessa format istället: {format}." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Perioden har fel format. Använd ett av dessa format istället: {format}." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" är inte ett giltigt val." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "Fler än {count} objekt..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Förväntade en lista med element men fick typen \"{input_type}\"." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Det här valet får inte vara tomt." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" är inte ett giltigt val för en sökväg." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Ingen fil skickades." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Den skickade informationen var inte en fil. Kontrollera formulärets kodningstyp." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Inget filnamn kunde bestämmas." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Den skickade filen var tom." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Se till att det här filnamnet har högst {max_length} tecken (det har {length})." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Ladda upp en giltig bild. Filen du laddade upp var antingen inte en bild eller en skadad bild." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Den här listan får inte vara tom." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Förväntade en \"dictionary\" med element men fick typen \"{input_type}\"." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Värdet måste vara giltig JSON." + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Skicka" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Ogiltigt sida \"{page_number}\": {message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Ogiltig cursor." -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Ogiltigt pk \"{pk_value}\" - Objektet finns inte." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Felaktig typ. Förväntade pk-värde, fick {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Ogiltig hyperlänk - Ingen URL matchade." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Ogiltig hyperlänk - Felaktig URL-matching." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Ogiltig hyperlänk - Objektet finns inte." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Felaktig typ. Förväntade URL-sträng, fick {data_type}." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "Objekt med {slug_name}={value} finns inte." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Ogiltigt värde." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Ogiltig data. Förväntade en dictionary, men fick {datatype}." +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filter" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Fältfilter" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Ordning" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Sök" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -330,46 +383,46 @@ msgstr "Inget" msgid "No items to select." msgstr "Inga valbara objekt." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Det här fältet måste vara unikt." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "Fälten {field_names} måste skapa ett unikt set." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Det här fältet måste vara unikt för datumet \"{date_field}\"." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Det här fältet måste vara unikt för månaden \"{date_field}\"." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Det här fältet måste vara unikt för året \"{date_field}\"." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "Ogiltig version i \"Accept\"-headern." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "Ogiltig version i URL-resursen." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Ogiltig version i värdnamnet." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Ogiltig version i förfrågningsparametern." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Åtkomst nekad." diff --git a/rest_framework/locale/tr/LC_MESSAGES/django.mo b/rest_framework/locale/tr/LC_MESSAGES/django.mo index 7da6bcbb..c3412b33 100644 Binary files a/rest_framework/locale/tr/LC_MESSAGES/django.mo and b/rest_framework/locale/tr/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/tr/LC_MESSAGES/django.po b/rest_framework/locale/tr/LC_MESSAGES/django.po index 1c554db1..0d3efc20 100644 --- a/rest_framework/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework/locale/tr/LC_MESSAGES/django.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Dogukan Tufekci , 2015 # Emrah BİLBAY , 2015 # Ertaç Paprat , 2015 # Mesut Can Gürle , 2015 @@ -13,33 +14,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Turkish (http://www.transifex.com/projects/p/django-rest-framework/language/tr/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-08 16:12+0000\n" +"Last-Translator: Recep KIRMIZI \n" +"Language-Team: Turkish (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: tr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "Geçersiz yetkilendirme başlığı. Gerekli uygunluk kriterleri sağlanmamış." -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "Geçersiz yetkilendirme başlığı. Uygunluk kriterine ait veri boşluk karakteri içermemeli." -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "Geçersiz yetkilendirme başlığı. Uygunluk kriterleri base64 formatına uygun olarak kodlanmamış." -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "Geçersiz kullanıcı adı/parola" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "Kullanıcı aktif değil ya da silinmiş." @@ -51,7 +52,12 @@ msgstr "Geçersiz token başlığı. Kimlik bilgileri eksik." msgid "Invalid token header. Token string should not contain spaces." msgstr "Geçersiz token başlığı. Token'da boşluk olmamalı." -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "Geçersiz token başlığı. Token geçersiz karakter içermemeli." + +#: authentication.py:185 msgid "Invalid token." msgstr "Geçersiz token." @@ -67,261 +73,309 @@ msgstr "Verilen bilgiler ile giriş sağlanamadı." msgid "Must include \"username\" and \"password\"." msgstr "\"Kullanıcı Adı\" ve \"Parola\" eklenmeli." -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "Sunucu hatası oluştu." -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "Bozuk istek." -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "Giriş bilgileri hatalı." -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "Giriş bilgileri verilmedi." -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "Bu işlemi yapmak için izniniz bulunmuyor." -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "Bulunamadı." -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "\"{method}\" metoduna izin verilmiyor." -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "İsteğe ait Accept başlık bilgisi yanıt verilecek başlık bilgileri arasında değil." -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "İstekte desteklenmeyen medya tipi: \"{media_type}\"." -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "Üst üste çok fazla istek yapıldı." -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "Bu alan zorunlu." -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "Bu alan boş bırakılmamalı." -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "\"{input}\" geçerli bir boolean değil." -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "Bu alan boş bırakılmamalı." -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "Bu alanın {max_length} karakterden fazla karakter barındırmadığından emin olun." -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "Bu alanın en az {min_length} karakter barındırdığından emin olun." -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "Geçerli bir e-posta adresi girin." -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "Bu değer gereken düzenli ifade deseni ile uyuşmuyor." -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "Harf, rakam, altçizgi veya tireden oluşan geçerli bir \"slug\" giriniz." -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "Geçerli bir URL girin." -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "\"{value}\" geçerli bir UUID değil." -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "Geçerli bir IPv4 ya da IPv6 adresi girin." + +#: fields.py:816 msgid "A valid integer is required." msgstr "Geçerli bir tam sayı girin." -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "Değerin {max_value} değerinden küçük ya da eşit olduğundan emin olun." -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "Değerin {min_value} değerinden büyük ya da eşit olduğundan emin olun." -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "String değeri çok uzun." -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "Geçerli bir numara gerekiyor." -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "Toplamda {max_digits} haneden fazla hane olmadığından emin olun." -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "Ondalık basamak değerinin {max_decimal_places} haneden fazla olmadığından emin olun." -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "Ondalık ayracından önce {max_whole_digits} basamaktan fazla olmadığından emin olun." -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "Datetime alanı yanlış biçimde. {format} biçimlerinden birini kullanın." -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "Datetime değeri bekleniyor, ama date değeri geldi." -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "Tarih biçimi yanlış. {format} biçimlerinden birini kullanın." -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "Date tipi beklenmekteydi, fakat datetime tipi geldi." -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "Time biçimi yanlış. {format} biçimlerinden birini kullanın." -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "Duration biçimi yanlış. {format} biçimlerinden birini kullanın." -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" geçerli bir seçim değil." -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "{count} elemandan daha fazla..." + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "Elemanların listesi beklenirken \"{input_type}\" alındı." -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "Bu seçim boş bırakılmamalı." + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\" geçerli bir yol seçimi değil." + +#: fields.py:1339 msgid "No file was submitted." msgstr "Hiçbir dosya verilmedi." -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "Gönderilen veri dosya değil. Formdaki kodlama tipini kontrol edin." -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "Hiçbir dosya adı belirlenemedi." -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "Gönderilen dosya boş." -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "Bu dosya adının en fazla {max_length} karakter uzunluğunda olduğundan emin olun. (şu anda {length} karakter)." -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "Geçerli bir resim yükleyin. Yüklediğiniz dosya resim değil ya da bozuk." -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "Bu liste boş olmamalı." + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "Sözlük tipi bir değişken beklenirken \"{input_type}\" tipi bir değişken alındı." -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "Değer geçerli bir JSON olmalı" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "Gönder" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "Geçersiz sayfa \"{page_number}\":{message}." -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "Sayfalandırma imleci geçersiz" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "Geçersiz pk \"{pk_value}\" - obje bulunamadı." -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "Hatalı tip. Pk değeri beklenirken, alınan {data_type}." -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "Geçersiz bağlantı - Hiçbir URL eşleşmedi." -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "Geçersiz bağlantı - Yanlış URL eşleşmesi." -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "Geçersiz bağlantı - Obje bulunamadı." -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "Hatalı tip. URL metni bekleniyor, {data_type} alındı." -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "{slug_name}={value} değerini taşıyan obje bulunamadı." -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "Geçersiz değer." -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "Geçersiz veri. Sözlük bekleniyordu fakat {datatype} geldi. " +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "Filtreler" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "Alan filtreleri" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "Sıralama" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "Arama" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -334,46 +388,46 @@ msgstr "Hiçbiri" msgid "No items to select." msgstr "Seçenek yok." -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "Bu alan eşsiz olmalı." -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "{field_names} hep birlikte eşsiz bir küme oluşturmalılar." -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "Bu alan \"{date_field}\" tarihine göre eşsiz olmalı." -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "Bu alan \"{date_field}\" ayına göre eşsiz olmalı." -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "Bu alan \"{date_field}\" yılına göre eşsiz olmalı." -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "\"Accept\" başlığındaki sürüm geçersiz." -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "URL dizininde geçersiz versiyon." -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "Host adında geçersiz versiyon." -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "Sorgu parametresinde geçersiz versiyon." -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "Erişim engellendi." diff --git a/rest_framework/locale/tr_TR/LC_MESSAGES/django.mo b/rest_framework/locale/tr_TR/LC_MESSAGES/django.mo new file mode 100644 index 00000000..1d3475bb Binary files /dev/null and b/rest_framework/locale/tr_TR/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/tr_TR/LC_MESSAGES/django.po b/rest_framework/locale/tr_TR/LC_MESSAGES/django.po new file mode 100644 index 00000000..a5f7d420 --- /dev/null +++ b/rest_framework/locale/tr_TR/LC_MESSAGES/django.po @@ -0,0 +1,427 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# José Alaguna , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Turkish (Turkey) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/tr_TR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tr_TR\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "Geçersiz kullanıcı adı / şifre." + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "Geçersiz simge." + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "Bulunamadı." + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "Geçersiz imleç." + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "Geçersiz hyper link - URL maçı yok." + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "Geçersiz hyper link - Yanlış URL maçı." + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "Geçersiz hyper link - Nesne yok.." + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "Geçersiz değer." + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "Geçersiz veri. Bir sözlük bekleniyor, ama var {datatype}." + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "Hiç kimse" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "Bu alan benzersiz olmalıdır." + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "{field_names} alanları benzersiz bir set yapmak gerekir." + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "\"Kabul et\" başlığında geçersiz sürümü." + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "URL yolu geçersiz sürümü." + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "Hostname geçersiz sürümü." + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "Sorgu parametresi geçersiz sürümü." + +#: views.py:88 +msgid "Permission denied." +msgstr "İzin reddedildi." diff --git a/rest_framework/locale/uk/LC_MESSAGES/django.mo b/rest_framework/locale/uk/LC_MESSAGES/django.mo index f15352c8..7af39663 100644 Binary files a/rest_framework/locale/uk/LC_MESSAGES/django.mo and b/rest_framework/locale/uk/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/uk/LC_MESSAGES/django.po b/rest_framework/locale/uk/LC_MESSAGES/django.po index 20f1ebd2..cbf1b0f2 100644 --- a/rest_framework/locale/uk/LC_MESSAGES/django.po +++ b/rest_framework/locale/uk/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Ukrainian (http://www.transifex.com/projects/p/django-rest-framework/language/uk/)\n" +"Language-Team: Ukrainian (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/vi/LC_MESSAGES/django.mo b/rest_framework/locale/vi/LC_MESSAGES/django.mo index 09be15af..0be6ed25 100644 Binary files a/rest_framework/locale/vi/LC_MESSAGES/django.mo and b/rest_framework/locale/vi/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/vi/LC_MESSAGES/django.po b/rest_framework/locale/vi/LC_MESSAGES/django.po index 63825d9b..8d0e5d3d 100644 --- a/rest_framework/locale/vi/LC_MESSAGES/django.po +++ b/rest_framework/locale/vi/LC_MESSAGES/django.po @@ -7,33 +7,33 @@ msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" "Last-Translator: Xavier Ordoquy \n" -"Language-Team: Vietnamese (http://www.transifex.com/projects/p/django-rest-framework/language/vi/)\n" +"Language-Team: Vietnamese (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/vi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: vi\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." msgstr "" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "" @@ -45,7 +45,12 @@ msgstr "" msgid "Invalid token header. Token string should not contain spaces." msgstr "" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 msgid "Invalid token." msgstr "" @@ -61,261 +66,309 @@ msgstr "" msgid "Must include \"username\" and \"password\"." msgstr "" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." msgstr "" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." msgstr "" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." msgstr "" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 msgid "A valid integer is required." msgstr "" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." msgstr "" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 msgid "No file was submitted." msgstr "" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 @@ -328,46 +381,46 @@ msgstr "" msgid "No items to select." msgstr "" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "" -#: views.py:85 +#: views.py:88 msgid "Permission denied." msgstr "" diff --git a/rest_framework/locale/zh-Hans/LC_MESSAGES/django.mo b/rest_framework/locale/zh-Hans/LC_MESSAGES/django.mo new file mode 100644 index 00000000..892ed149 Binary files /dev/null and b/rest_framework/locale/zh-Hans/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/zh-Hans/LC_MESSAGES/django.po b/rest_framework/locale/zh-Hans/LC_MESSAGES/django.po new file mode 100644 index 00000000..983ff1ba --- /dev/null +++ b/rest_framework/locale/zh-Hans/LC_MESSAGES/django.po @@ -0,0 +1,429 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Ping , 2015 +# hunter007 , 2015 +# nypisces , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-11 03:03+0000\n" +"Last-Translator: hunter007 \n" +"Language-Team: Chinese Simplified (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/zh-Hans/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh-Hans\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "无效的Basic认证头,没有提供认证信息。" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "认证字符串不应该包含空格(基本认证HTTP头无效)。" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "认证字符串base64编码错误(基本认证HTTP头无效)。" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "用户名或者密码错误。" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "用户未激活或者已删除。" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "没有提供认证信息(认证令牌HTTP头无效)。" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "认证令牌字符串不应该包含空格(无效的认证令牌HTTP头)。" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "无效的Token。Token字符串不能包含非法的字符。" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "认证令牌无效。" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "用户账户已禁用。" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "无法使用提供的认证信息登录。" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "必须包含 “用户名” 和 “密码”。" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "服务器出现了错误。" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "错误的请求。" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "不正确的身份认证信息。" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "身份认证信息未提供。" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "您没有执行该操作的权限。" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "未找到。" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "方法 “{method}” 不被允许。" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "无法满足Accept HTTP头的请求。" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "不支持请求中的媒体类型 “{media_type}”。" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "请求超过了限速。" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "该字段是必填项。" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "该字段不能为 null。" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "“{input}” 不是合法的布尔值。" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "该字段不能为空。" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "请确保这个字段不能超过 {max_length} 个字符。" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "请确保这个字段至少包含 {min_length} 个字符。" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "请输入合法的邮件地址。" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "输入值不匹配要求的模式。" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "请输入合法的“短语“,只能包含字母,数字,下划线或者中划线。" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "请输入合法的URL。" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "“{value}”不是合法的UUID。" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "请输入一个有效的IPv4或IPv6地址。" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "请填写合法的整数值。" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "请确保该值小于或者等于 {max_value}。" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "请确保该值大于或者等于 {min_value}。" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "字符串值太长。" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "请填写合法的数字。" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "请确保总计不超过 {max_digits} 个数字。" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "请确保总计不超过 {max_decimal_places} 个小数位。" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "请确保小数点前不超过 {max_whole_digits} 个数字。" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "日期时间格式错误。请从这些格式中选择:{format}。" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "期望为日期时间,获得的是日期。" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "日期格式错误。请从这些格式中选择:{format}。" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "期望为日期,获得的是日期时间。" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "时间格式错误。请从这些格式中选择:{format}。" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "持续时间的格式错误。使用这些格式中的一个:{format}。" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "“{input}” 不是合法选项。" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "多于{count}条记录。" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "期望为一个包含物件的列表,得到的类型是“{input_type}”。" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "这项选择不能为空。" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "\"{input}\"不是一个有效路径选项。" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "没有提交任何文件。" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "提交的数据不是一个文件。请检查表单的编码类型。" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "无法检测到文件名。" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "提交的是空文件。" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "确保该文件名最多包含 {max_length} 个字符 ( 当前长度为{length} ) 。" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "请上传有效图片。您上传的该文件不是图片或者图片已经损坏。" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "列表不能为空。" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "期望是包含类目的字典,得到类型为 “{input_type}”。" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "值必须是有效的 JSON 数据。" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "提交" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "无效页面 “{page_number}”:{message}。" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "无效游标" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "无效主键 “{pk_value}” - 对象不存在。" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "类型错误。期望为主键,获得的类型为 {data_type}。" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "无效超链接 -没有匹配的URL。" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "无效超链接 -错误的URL匹配。" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "无效超链接 -对象不存在。" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "类型错误。期望为URL字符串,实际的类型是 {data_type}。" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "属性 {slug_name} 为 {value} 的对象不存在。" + +#: relations.py:392 +msgid "Invalid value." +msgstr "无效值。" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "无效数据。期待为字典类型,得到的是 {datatype} 。" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "过滤器" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "过滤器字段" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "排序" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr " 搜索" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "无" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "没有可选项。" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "该字段必须唯一。" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "字段 {field_names} 必须能构成唯一集合。" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "该字段必须在日期 “{date_field}” 唯一。" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "该字段必须在月份 “{date_field}” 唯一。" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "该字段必须在年 “{date_field}” 唯一。" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "“Accept” HTTP头包含无效版本。" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "URL路径包含无效版本。" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "主机名包含无效版本。" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "请求参数里包含无效版本。" + +#: views.py:88 +msgid "Permission denied." +msgstr "没有权限。" diff --git a/rest_framework/locale/zh-Hant/LC_MESSAGES/django.mo b/rest_framework/locale/zh-Hant/LC_MESSAGES/django.mo new file mode 100644 index 00000000..0e9d3a33 Binary files /dev/null and b/rest_framework/locale/zh-Hant/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/zh-Hant/LC_MESSAGES/django.po b/rest_framework/locale/zh-Hant/LC_MESSAGES/django.po new file mode 100644 index 00000000..a04ed527 --- /dev/null +++ b/rest_framework/locale/zh-Hant/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Chinese Traditional (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/zh-Hant/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh-Hant\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/locale/zh_CN/LC_MESSAGES/django.mo b/rest_framework/locale/zh_CN/LC_MESSAGES/django.mo index 5d7d7edc..c1552b71 100644 Binary files a/rest_framework/locale/zh_CN/LC_MESSAGES/django.mo and b/rest_framework/locale/zh_CN/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/zh_CN/LC_MESSAGES/django.po b/rest_framework/locale/zh_CN/LC_MESSAGES/django.po index 3f26840d..a5e6cde2 100644 --- a/rest_framework/locale/zh_CN/LC_MESSAGES/django.po +++ b/rest_framework/locale/zh_CN/LC_MESSAGES/django.po @@ -3,39 +3,40 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# hunter007 , 2015 # Lele Long , 2015 # Ming Chen , 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-03 17:30+0100\n" -"PO-Revision-Date: 2015-06-03 16:30+0000\n" -"Last-Translator: Xavier Ordoquy \n" -"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/django-rest-framework/language/zh_CN/)\n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-11 03:00+0000\n" +"Last-Translator: hunter007 \n" +"Language-Team: Chinese (China) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:70 +#: authentication.py:72 msgid "Invalid basic header. No credentials provided." -msgstr "没有提供认证信息(基本认证HTTP头无效)。" +msgstr "无效的Basic认证头,没有提供认证信息。" -#: authentication.py:73 +#: authentication.py:75 msgid "Invalid basic header. Credentials string should not contain spaces." msgstr "认证字符串不应该包含空格(基本认证HTTP头无效)。" -#: authentication.py:79 +#: authentication.py:81 msgid "Invalid basic header. Credentials not correctly base64 encoded." msgstr "认证字符串base64编码错误(基本认证HTTP头无效)。" -#: authentication.py:97 +#: authentication.py:98 msgid "Invalid username/password." msgstr "用户名或者密码错误。" -#: authentication.py:100 authentication.py:182 +#: authentication.py:101 authentication.py:188 msgid "User inactive or deleted." msgstr "用户未激活或者已删除。" @@ -47,7 +48,12 @@ msgstr "没有提供认证信息(认证令牌HTTP头无效)。" msgid "Invalid token header. Token string should not contain spaces." msgstr "认证令牌字符串不应该包含空格(无效的认证令牌HTTP头)。" -#: authentication.py:179 +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "无效的Token。Token字符串不能包含非法的字符。" + +#: authentication.py:185 msgid "Invalid token." msgstr "认证令牌无效。" @@ -63,313 +69,361 @@ msgstr "无法使用提供的认证信息登录。" msgid "Must include \"username\" and \"password\"." msgstr "必须包含 “用户名” 和 “密码”。" -#: exceptions.py:38 +#: exceptions.py:49 msgid "A server error occurred." msgstr "服务器出现了错误。" -#: exceptions.py:73 +#: exceptions.py:84 msgid "Malformed request." msgstr "错误的请求。" -#: exceptions.py:78 +#: exceptions.py:89 msgid "Incorrect authentication credentials." msgstr "不正确的身份认证信息。" -#: exceptions.py:83 +#: exceptions.py:94 msgid "Authentication credentials were not provided." msgstr "身份认证信息未提供。" -#: exceptions.py:88 +#: exceptions.py:99 msgid "You do not have permission to perform this action." msgstr "您没有执行该操作的权限。" -#: exceptions.py:93 views.py:78 +#: exceptions.py:104 views.py:81 msgid "Not found." msgstr "未找到。" -#: exceptions.py:98 +#: exceptions.py:109 #, python-brace-format msgid "Method \"{method}\" not allowed." msgstr "方法 “{method}” 不被允许。" -#: exceptions.py:109 +#: exceptions.py:120 msgid "Could not satisfy the request Accept header." msgstr "无法满足Accept HTTP头的请求。" -#: exceptions.py:121 +#: exceptions.py:132 #, python-brace-format msgid "Unsupported media type \"{media_type}\" in request." msgstr "不支持请求中的媒体类型 “{media_type}”。" -#: exceptions.py:134 +#: exceptions.py:145 msgid "Request was throttled." msgstr "请求超过了限速。" -#: fields.py:162 relations.py:132 relations.py:156 validators.py:77 -#: validators.py:160 +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 msgid "This field is required." -msgstr "这个字段是必填项。" +msgstr "该字段是必填项。" -#: fields.py:163 +#: fields.py:267 msgid "This field may not be null." -msgstr "这个值不能为 null。" +msgstr "该字段不能为 null。" -#: fields.py:496 fields.py:524 +#: fields.py:603 fields.py:634 #, python-brace-format msgid "\"{input}\" is not a valid boolean." msgstr "“{input}” 不是合法的布尔值。" -#: fields.py:559 +#: fields.py:669 msgid "This field may not be blank." -msgstr "此字段不能为空。" +msgstr "该字段不能为空。" -#: fields.py:560 fields.py:1386 +#: fields.py:670 fields.py:1656 #, python-brace-format msgid "Ensure this field has no more than {max_length} characters." msgstr "请确保这个字段不能超过 {max_length} 个字符。" -#: fields.py:561 +#: fields.py:671 #, python-brace-format msgid "Ensure this field has at least {min_length} characters." msgstr "请确保这个字段至少包含 {min_length} 个字符。" -#: fields.py:598 +#: fields.py:708 msgid "Enter a valid email address." msgstr "请输入合法的邮件地址。" -#: fields.py:609 +#: fields.py:719 msgid "This value does not match the required pattern." msgstr "输入值不匹配要求的模式。" -#: fields.py:620 +#: fields.py:730 msgid "" "Enter a valid \"slug\" consisting of letters, numbers, underscores or " "hyphens." msgstr "请输入合法的“短语“,只能包含字母,数字,下划线或者中划线。" -#: fields.py:632 +#: fields.py:742 msgid "Enter a valid URL." msgstr "请输入合法的URL。" -#: fields.py:645 +#: fields.py:755 #, python-brace-format msgid "\"{value}\" is not a valid UUID." msgstr "“{value}”不是合法的UUID。" -#: fields.py:679 +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "请输入一个有效的IPv4或IPv6地址。" + +#: fields.py:816 msgid "A valid integer is required." msgstr "请填写合法的整数值。" -#: fields.py:680 fields.py:715 fields.py:748 +#: fields.py:817 fields.py:852 fields.py:885 #, python-brace-format msgid "Ensure this value is less than or equal to {max_value}." msgstr "请确保该值小于或者等于 {max_value}。" -#: fields.py:681 fields.py:716 fields.py:749 +#: fields.py:818 fields.py:853 fields.py:886 #, python-brace-format msgid "Ensure this value is greater than or equal to {min_value}." msgstr "请确保该值大于或者等于 {min_value}。" -#: fields.py:682 fields.py:717 fields.py:753 +#: fields.py:819 fields.py:854 fields.py:890 msgid "String value too large." msgstr "字符串值太长。" -#: fields.py:714 fields.py:747 +#: fields.py:851 fields.py:884 msgid "A valid number is required." msgstr "请填写合法的数字。" -#: fields.py:750 +#: fields.py:887 #, python-brace-format msgid "Ensure that there are no more than {max_digits} digits in total." msgstr "请确保总计不超过 {max_digits} 个数字。" -#: fields.py:751 +#: fields.py:888 #, python-brace-format msgid "" "Ensure that there are no more than {max_decimal_places} decimal places." msgstr "请确保总计不超过 {max_decimal_places} 个小数位。" -#: fields.py:752 +#: fields.py:889 #, python-brace-format msgid "" "Ensure that there are no more than {max_whole_digits} digits before the " "decimal point." msgstr "请确保小数点前不超过 {max_whole_digits} 个数字。" -#: fields.py:842 +#: fields.py:1004 #, python-brace-format msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgstr "日期时间格式错误。请从这些格式中选择:{format}。" -#: fields.py:843 +#: fields.py:1005 msgid "Expected a datetime but got a date." msgstr "期望为日期时间,得到的是日期。" -#: fields.py:907 +#: fields.py:1079 #, python-brace-format msgid "Date has wrong format. Use one of these formats instead: {format}." msgstr "日期格式错误。请从这些格式中选择:{format}。" -#: fields.py:908 +#: fields.py:1080 msgid "Expected a date but got a datetime." msgstr "期望为日期,得到的是日期时间。" -#: fields.py:971 +#: fields.py:1148 #, python-brace-format msgid "Time has wrong format. Use one of these formats instead: {format}." msgstr "时间格式错误。请从这些格式中选择:{format}。" -#: fields.py:1025 +#: fields.py:1207 #, python-brace-format msgid "Duration has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "持续时间的格式错误。使用这些格式中的一个:{format}。" -#: fields.py:1050 fields.py:1094 +#: fields.py:1232 fields.py:1281 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "“{input}” 不是合法选项。" -#: fields.py:1095 fields.py:1213 serializers.py:487 +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "多于{count}条记录。" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 #, python-brace-format msgid "Expected a list of items but got type \"{input_type}\"." msgstr "期望为一个包含物件的列表,得到的类型是“{input_type}”。" -#: fields.py:1129 +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "这项选择不能为空。" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "“{input}” 不是有效路径选项。" + +#: fields.py:1339 msgid "No file was submitted." msgstr "没有提交任何文件。" -#: fields.py:1130 +#: fields.py:1340 msgid "" "The submitted data was not a file. Check the encoding type on the form." msgstr "提交的数据不是一个文件。请检查表单的编码类型。" -#: fields.py:1131 +#: fields.py:1341 msgid "No filename could be determined." msgstr "无法检测到文件名。" -#: fields.py:1132 +#: fields.py:1342 msgid "The submitted file is empty." msgstr "提交的是空文件。" -#: fields.py:1133 +#: fields.py:1343 #, python-brace-format msgid "" "Ensure this filename has at most {max_length} characters (it has {length})." msgstr "确保该文件名最多包含 {max_length} 个字符 ( 当前长度为{length} ) 。" -#: fields.py:1175 +#: fields.py:1391 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "请上传有效图片。您上传的该文件不是图片或者图片已经损坏。" -#: fields.py:1250 +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "列表字段不能为空值。" + +#: fields.py:1483 #, python-brace-format msgid "Expected a dictionary of items but got type \"{input_type}\"." msgstr "期望是包含类目的字典,得到类型为 “{input_type}”。" -#: pagination.py:231 +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "值必须是有效的 JSON 数据。" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "保存" + +#: pagination.py:189 #, python-brace-format msgid "Invalid page \"{page_number}\": {message}." msgstr "无效页面 “{page_number}”:{message}。" -#: pagination.py:492 +#: pagination.py:407 msgid "Invalid cursor" msgstr "无效游标" -#: relations.py:133 +#: relations.py:196 #, python-brace-format msgid "Invalid pk \"{pk_value}\" - object does not exist." msgstr "无效主键 “{pk_value}” - 对象不存在。" -#: relations.py:134 +#: relations.py:197 #, python-brace-format msgid "Incorrect type. Expected pk value, received {data_type}." msgstr "类型错误。期望为主键,得到的类型为 {data_type}。" -#: relations.py:157 +#: relations.py:229 msgid "Invalid hyperlink - No URL match." msgstr "无效超链接 -没有匹配的URL。" -#: relations.py:158 +#: relations.py:230 msgid "Invalid hyperlink - Incorrect URL match." msgstr "无效超链接 -错误的URL匹配。" -#: relations.py:159 +#: relations.py:231 msgid "Invalid hyperlink - Object does not exist." msgstr "无效超链接 -对象不存在。" -#: relations.py:160 +#: relations.py:232 #, python-brace-format msgid "Incorrect type. Expected URL string, received {data_type}." msgstr "类型错误。期望为URL字符串,实际的类型是 {data_type}。" -#: relations.py:302 +#: relations.py:391 #, python-brace-format msgid "Object with {slug_name}={value} does not exist." msgstr "属性 {slug_name} 为 {value} 的对象不存在。" -#: relations.py:303 +#: relations.py:392 msgid "Invalid value." msgstr "无效值。" -#: serializers.py:304 +#: serializers.py:326 #, python-brace-format msgid "Invalid data. Expected a dictionary, but got {datatype}." msgstr "无效数据。期待为字典类型,得到的是 {datatype} 。" +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "过滤器" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "过滤器字段" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "排序" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "查找" + #: templates/rest_framework/horizontal/radio.html:2 #: templates/rest_framework/inline/radio.html:2 #: templates/rest_framework/vertical/radio.html:2 msgid "None" -msgstr "" +msgstr "无" #: templates/rest_framework/horizontal/select_multiple.html:2 #: templates/rest_framework/inline/select_multiple.html:2 #: templates/rest_framework/vertical/select_multiple.html:2 msgid "No items to select." -msgstr "" +msgstr "没有可选项。" -#: validators.py:22 +#: validators.py:24 msgid "This field must be unique." msgstr "该字段必须唯一。" -#: validators.py:76 +#: validators.py:78 #, python-brace-format msgid "The fields {field_names} must make a unique set." msgstr "字段 {field_names} 必须能构成唯一集合。" -#: validators.py:224 +#: validators.py:226 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" date." msgstr "该字段必须在日期 “{date_field}” 唯一。" -#: validators.py:239 +#: validators.py:241 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" month." msgstr "该字段必须在月份 “{date_field}” 唯一。" -#: validators.py:252 +#: validators.py:254 #, python-brace-format msgid "This field must be unique for the \"{date_field}\" year." msgstr "该字段必须在年 “{date_field}” 唯一。" -#: versioning.py:39 +#: versioning.py:42 msgid "Invalid version in \"Accept\" header." msgstr "“Accept” HTTP头包含无效版本。" -#: versioning.py:70 versioning.py:112 +#: versioning.py:73 versioning.py:115 msgid "Invalid version in URL path." msgstr "URL路径包含无效版本。" -#: versioning.py:141 +#: versioning.py:144 msgid "Invalid version in hostname." msgstr "主机名包含无效版本。" -#: versioning.py:163 +#: versioning.py:166 msgid "Invalid version in query parameter." msgstr "请求参数里包含无效版本。" -#: views.py:85 +#: views.py:88 msgid "Permission denied." -msgstr "" +msgstr "没有权限。" diff --git a/rest_framework/locale/zh_TW/LC_MESSAGES/django.mo b/rest_framework/locale/zh_TW/LC_MESSAGES/django.mo new file mode 100644 index 00000000..e202136e Binary files /dev/null and b/rest_framework/locale/zh_TW/LC_MESSAGES/django.mo differ diff --git a/rest_framework/locale/zh_TW/LC_MESSAGES/django.po b/rest_framework/locale/zh_TW/LC_MESSAGES/django.po new file mode 100644 index 00000000..5ca07eea --- /dev/null +++ b/rest_framework/locale/zh_TW/LC_MESSAGES/django.po @@ -0,0 +1,426 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-07 18:53+0100\n" +"PO-Revision-Date: 2015-12-07 17:55+0000\n" +"Last-Translator: Xavier Ordoquy \n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/django-rest-framework-1/django-rest-framework/language/zh_TW/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_TW\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:72 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:75 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:81 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:98 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:101 authentication.py:188 +msgid "User inactive or deleted." +msgstr "" + +#: authentication.py:167 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:170 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:176 +msgid "" +"Invalid token header. Token string should not contain invalid characters." +msgstr "" + +#: authentication.py:185 +msgid "Invalid token." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" + +#: exceptions.py:49 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:84 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:89 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:94 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:99 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:104 views.py:81 +msgid "Not found." +msgstr "" + +#: exceptions.py:109 +#, python-brace-format +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:120 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:132 +#, python-brace-format +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:145 +msgid "Request was throttled." +msgstr "" + +#: fields.py:266 relations.py:195 relations.py:228 validators.py:79 +#: validators.py:162 +msgid "This field is required." +msgstr "" + +#: fields.py:267 +msgid "This field may not be null." +msgstr "" + +#: fields.py:603 fields.py:634 +#, python-brace-format +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:669 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:670 fields.py:1656 +#, python-brace-format +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:671 +#, python-brace-format +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:708 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:719 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:730 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:742 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:755 +#, python-brace-format +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:791 +msgid "Enter a valid IPv4 or IPv6 address." +msgstr "" + +#: fields.py:816 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:817 fields.py:852 fields.py:885 +#, python-brace-format +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:818 fields.py:853 fields.py:886 +#, python-brace-format +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:819 fields.py:854 fields.py:890 +msgid "String value too large." +msgstr "" + +#: fields.py:851 fields.py:884 +msgid "A valid number is required." +msgstr "" + +#: fields.py:887 +#, python-brace-format +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:888 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:889 +#, python-brace-format +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:1004 +#, python-brace-format +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1005 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:1079 +#, python-brace-format +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1080 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:1148 +#, python-brace-format +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1207 +#, python-brace-format +msgid "Duration has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:1232 fields.py:1281 +#, python-brace-format +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1235 relations.py:62 relations.py:431 +#, python-brace-format +msgid "More than {count} items..." +msgstr "" + +#: fields.py:1282 fields.py:1429 relations.py:427 serializers.py:520 +#, python-brace-format +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1283 +msgid "This selection may not be empty." +msgstr "" + +#: fields.py:1320 +#, python-brace-format +msgid "\"{input}\" is not a valid path choice." +msgstr "" + +#: fields.py:1339 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1340 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1341 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1342 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1343 +#, python-brace-format +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1391 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1430 relations.py:428 serializers.py:521 +msgid "This list may not be empty." +msgstr "" + +#: fields.py:1483 +#, python-brace-format +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1530 +msgid "Value must be valid JSON." +msgstr "" + +#: filters.py:35 templates/rest_framework/filters/django_filter.html:5 +msgid "Submit" +msgstr "" + +#: pagination.py:189 +#, python-brace-format +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:407 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:196 +#, python-brace-format +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:197 +#, python-brace-format +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:229 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:230 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:231 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:232 +#, python-brace-format +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:391 +#, python-brace-format +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:392 +msgid "Invalid value." +msgstr "" + +#: serializers.py:326 +#, python-brace-format +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: templates/rest_framework/admin.html:118 +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "" + +#: templates/rest_framework/filters/django_filter.html:2 +#: templates/rest_framework/filters/django_filter_crispyforms.html:4 +msgid "Field filters" +msgstr "" + +#: templates/rest_framework/filters/ordering.html:3 +msgid "Ordering" +msgstr "" + +#: templates/rest_framework/filters/search.html:2 +msgid "Search" +msgstr "" + +#: templates/rest_framework/horizontal/radio.html:2 +#: templates/rest_framework/inline/radio.html:2 +#: templates/rest_framework/vertical/radio.html:2 +msgid "None" +msgstr "" + +#: templates/rest_framework/horizontal/select_multiple.html:2 +#: templates/rest_framework/inline/select_multiple.html:2 +#: templates/rest_framework/vertical/select_multiple.html:2 +msgid "No items to select." +msgstr "" + +#: validators.py:24 +msgid "This field must be unique." +msgstr "" + +#: validators.py:78 +#, python-brace-format +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:226 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:241 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:254 +#, python-brace-format +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:42 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:73 versioning.py:115 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:144 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:166 +msgid "Invalid version in query parameter." +msgstr "" + +#: views.py:88 +msgid "Permission denied." +msgstr "" diff --git a/rest_framework/metadata.py b/rest_framework/metadata.py index 45f5b766..6c4f1769 100644 --- a/rest_framework/metadata.py +++ b/rest_framework/metadata.py @@ -8,11 +8,13 @@ to return this information in a more standardized way. """ from __future__ import unicode_literals +from collections import OrderedDict + from django.core.exceptions import PermissionDenied from django.http import Http404 from django.utils.encoding import force_text + from rest_framework import exceptions, serializers -from rest_framework.compat import OrderedDict from rest_framework.request import clone_request from rest_framework.utils.field_mapping import ClassLookupDict @@ -52,6 +54,9 @@ class SimpleMetadata(BaseMetadata): serializers.MultipleChoiceField: 'multiple choice', serializers.FileField: 'file upload', serializers.ImageField: 'image upload', + serializers.ListField: 'list', + serializers.DictField: 'nested object', + serializers.Serializer: 'nested object', }) def determine_metadata(self, request, view): @@ -72,7 +77,7 @@ class SimpleMetadata(BaseMetadata): the fields that are accepted for 'PUT' and 'POST' methods. """ actions = {} - for method in set(['PUT', 'POST']) & set(view.allowed_methods): + for method in {'PUT', 'POST'} & set(view.allowed_methods): view.request = clone_request(request, method) try: # Test global permissions @@ -127,6 +132,11 @@ class SimpleMetadata(BaseMetadata): if value is not None and value != '': field_info[attr] = force_text(value, strings_only=True) + if getattr(field, 'child', None): + field_info['child'] = self.get_field_info(field.child) + elif getattr(field, 'fields', None): + field_info['children'] = self.get_serializer_info(field) + if not field_info.get('read_only') and hasattr(field, 'choices'): field_info['choices'] = [ { diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index c34cfcee..1104aa29 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -5,6 +5,7 @@ We don't bind behaviour to http method handlers yet, which allows mixin classes to be composed in interesting ways. """ from __future__ import unicode_literals + from rest_framework import status from rest_framework.response import Response from rest_framework.settings import api_settings diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index 663ec4c8..2a2b6f16 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -3,11 +3,14 @@ Content negotiation deals with selecting an appropriate renderer given the incoming request. Typically this will be based on the request's Accept header. """ from __future__ import unicode_literals + from django.http import Http404 + from rest_framework import HTTP_HEADER_ENCODING, exceptions from rest_framework.settings import api_settings -from rest_framework.utils.mediatypes import order_by_precedence, media_type_matches -from rest_framework.utils.mediatypes import _MediaType +from rest_framework.utils.mediatypes import ( + _MediaType, media_type_matches, order_by_precedence +) class BaseContentNegotiation(object): @@ -89,9 +92,6 @@ class DefaultContentNegotiation(BaseContentNegotiation): """ Given the incoming request, return a tokenised list of media type strings. - - Allows URL style accept override. eg. "?accept=application/json" """ header = request.META.get('HTTP_ACCEPT', '*/*') - header = request.query_params.get(self.settings.URL_ACCEPT_OVERRIDE, header) return [token.strip() for token in header.split(',')] diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index b6be6b7c..1051dc5b 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -4,21 +4,22 @@ Pagination serializers determine the structure of the output that should be used for paginated responses. """ from __future__ import unicode_literals -from base64 import b64encode, b64decode -from collections import namedtuple -from django.core.paginator import InvalidPage, Paginator as DjangoPaginator -from django.template import Context, loader + +from base64 import b64decode, b64encode +from collections import OrderedDict, namedtuple + +from django.core.paginator import Paginator as DjangoPaginator +from django.core.paginator import InvalidPage +from django.template import loader from django.utils import six from django.utils.six.moves.urllib import parse as urlparse from django.utils.translation import ugettext_lazy as _ -from rest_framework.compat import OrderedDict + +from rest_framework.compat import template_render from rest_framework.exceptions import NotFound from rest_framework.response import Response from rest_framework.settings import api_settings -from rest_framework.utils.urls import ( - replace_query_param, remove_query_param -) -import warnings +from rest_framework.utils.urls import remove_query_param, replace_query_param def _positive_int(integer_string, strict=False, cutoff=None): @@ -78,11 +79,7 @@ def _get_displayed_page_numbers(current, final): # We always include the first two pages, last two pages, and # two pages either side of the current page. - included = set(( - 1, - current - 1, current, current + 1, - final - )) + included = {1, current - 1, current, current + 1, final} # If the break would only exclude a single page number then we # may as well include the page number instead of the break. @@ -127,50 +124,6 @@ def _get_page_links(page_numbers, current, url_func): return page_links -def _decode_cursor(encoded): - """ - Given a string representing an encoded cursor, return a `Cursor` instance. - """ - - # The offset in the cursor is used in situations where we have a - # nearly-unique index. (Eg millisecond precision creation timestamps) - # We guard against malicious users attempting to cause expensive database - # queries, by having a hard cap on the maximum possible size of the offset. - OFFSET_CUTOFF = 1000 - - try: - querystring = b64decode(encoded.encode('ascii')).decode('ascii') - tokens = urlparse.parse_qs(querystring, keep_blank_values=True) - - offset = tokens.get('o', ['0'])[0] - offset = _positive_int(offset, cutoff=OFFSET_CUTOFF) - - reverse = tokens.get('r', ['0'])[0] - reverse = bool(int(reverse)) - - position = tokens.get('p', [None])[0] - except (TypeError, ValueError): - return None - - return Cursor(offset=offset, reverse=reverse, position=position) - - -def _encode_cursor(cursor): - """ - Given a Cursor instance, return an encoded string representation. - """ - tokens = {} - if cursor.offset != 0: - tokens['o'] = str(cursor.offset) - if cursor.reverse: - tokens['r'] = '1' - if cursor.position is not None: - tokens['p'] = cursor.position - - querystring = urlparse.urlencode(tokens, doseq=True) - return b64encode(querystring.encode('ascii')).decode('ascii') - - def _reverse_ordering(ordering_tuple): """ Given an order_by tuple such as `('-created', 'uuid')` reverse the @@ -200,6 +153,9 @@ class BasePagination(object): def to_html(self): # pragma: no cover raise NotImplementedError('to_html() must be implemented to display page controls.') + def get_results(self, data): + return data['results'] + class PageNumberPagination(BasePagination): """ @@ -213,6 +169,8 @@ class PageNumberPagination(BasePagination): # Defaults to `None`, meaning pagination is disabled. page_size = api_settings.PAGE_SIZE + django_paginator_class = DjangoPaginator + # Client can control the page using this query parameter. page_query_param = 'page' @@ -230,67 +188,16 @@ class PageNumberPagination(BasePagination): invalid_page_message = _('Invalid page "{page_number}": {message}.') - def _handle_backwards_compat(self, view): - """ - Prior to version 3.1, pagination was handled in the view, and the - attributes were set there. The attributes should now be set on - the pagination class, but the old style is still pending deprecation. - """ - assert not ( - getattr(view, 'pagination_serializer_class', None) or - getattr(api_settings, 'DEFAULT_PAGINATION_SERIALIZER_CLASS', None) - ), ( - "The pagination_serializer_class attribute and " - "DEFAULT_PAGINATION_SERIALIZER_CLASS setting have been removed as " - "part of the 3.1 pagination API improvement. See the pagination " - "documentation for details on the new API." - ) - - for (settings_key, attr_name) in ( - ('PAGINATE_BY', 'page_size'), - ('PAGINATE_BY_PARAM', 'page_size_query_param'), - ('MAX_PAGINATE_BY', 'max_page_size') - ): - value = getattr(api_settings, settings_key, None) - if value is not None: - setattr(self, attr_name, value) - warnings.warn( - "The `%s` settings key is pending deprecation. " - "Use the `%s` attribute on the pagination class instead." % ( - settings_key, attr_name - ), - PendingDeprecationWarning, - ) - - for (view_attr, attr_name) in ( - ('paginate_by', 'page_size'), - ('page_query_param', 'page_query_param'), - ('paginate_by_param', 'page_size_query_param'), - ('max_paginate_by', 'max_page_size') - ): - value = getattr(view, view_attr, None) - if value is not None: - setattr(self, attr_name, value) - warnings.warn( - "The `%s` view attribute is pending deprecation. " - "Use the `%s` attribute on the pagination class instead." % ( - view_attr, attr_name - ), - PendingDeprecationWarning, - ) - def paginate_queryset(self, queryset, request, view=None): """ Paginate a queryset if required, either returning a page object, or `None` if pagination is not configured for this view. """ - self._handle_backwards_compat(view) - page_size = self.get_page_size(request) if not page_size: return None - paginator = DjangoPaginator(queryset, page_size) + paginator = self.django_paginator_class(queryset, page_size) page_number = request.query_params.get(self.page_query_param, 1) if page_number in self.last_page_strings: page_number = paginator.num_pages @@ -303,7 +210,7 @@ class PageNumberPagination(BasePagination): ) raise NotFound(msg) - if paginator.count > 1 and self.template is not None: + if paginator.num_pages > 1 and self.template is not None: # The browsable API should display pagination controls. self.display_page_controls = True @@ -369,8 +276,8 @@ class PageNumberPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) class LimitOffsetPagination(BasePagination): @@ -431,6 +338,8 @@ class LimitOffsetPagination(BasePagination): return None url = self.request.build_absolute_uri() + url = replace_query_param(url, self.limit_query_param, self.limit) + offset = self.offset + self.limit return replace_query_param(url, self.offset_query_param, offset) @@ -439,6 +348,7 @@ class LimitOffsetPagination(BasePagination): return None url = self.request.build_absolute_uri() + url = replace_query_param(url, self.limit_query_param, self.limit) if self.offset - self.limit <= 0: return remove_query_param(url, self.offset_query_param) @@ -458,6 +368,11 @@ class LimitOffsetPagination(BasePagination): _divide_with_ceil(self.count - self.offset, self.limit) + _divide_with_ceil(self.offset, self.limit) ) + if final < 1: + final = 1 + + if current > final: + current = final def page_number_to_url(page_number): if page_number == 1: @@ -477,8 +392,8 @@ class LimitOffsetPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) class CursorPagination(BasePagination): @@ -494,21 +409,17 @@ class CursorPagination(BasePagination): template = 'rest_framework/pagination/previous_and_next.html' def paginate_queryset(self, queryset, request, view=None): - if self.page_size is None: + self.page_size = self.get_page_size(request) + if not self.page_size: return None self.base_url = request.build_absolute_uri() self.ordering = self.get_ordering(request, queryset, view) - # Determine if we have a cursor, and if so then decode it. - encoded = request.query_params.get(self.cursor_query_param) - if encoded is None: - self.cursor = None + self.cursor = self.decode_cursor(request) + if self.cursor is None: (offset, reverse, current_position) = (0, False, None) else: - self.cursor = _decode_cursor(encoded) - if self.cursor is None: - raise NotFound(self.invalid_cursor_message) (offset, reverse, current_position) = self.cursor # Cursor pagination always enforces an ordering. @@ -574,6 +485,9 @@ class CursorPagination(BasePagination): return self.page + def get_page_size(self, request): + return self.page_size + def get_next_link(self): if not self.has_next: return None @@ -620,8 +534,7 @@ class CursorPagination(BasePagination): position = self.previous_position cursor = Cursor(offset=offset, reverse=False, position=position) - encoded = _encode_cursor(cursor) - return replace_query_param(self.base_url, self.cursor_query_param, encoded) + return self.encode_cursor(cursor) def get_previous_link(self): if not self.has_previous: @@ -669,8 +582,7 @@ class CursorPagination(BasePagination): position = self.next_position cursor = Cursor(offset=offset, reverse=True, position=position) - encoded = _encode_cursor(cursor) - return replace_query_param(self.base_url, self.cursor_query_param, encoded) + return self.encode_cursor(cursor) def get_ordering(self, request, queryset, view): """ @@ -701,6 +613,11 @@ class CursorPagination(BasePagination): 'Using cursor pagination, but no ordering attribute was declared ' 'on the pagination class.' ) + assert '__' not in ordering, ( + 'Cursor pagination does not support double underscore lookups ' + 'for orderings. Orderings should be an unchanging, unique or ' + 'nearly-unique field on the model, such as "-created" or "pk".' + ) assert isinstance(ordering, (six.string_types, list, tuple)), ( 'Invalid ordering. Expected string or tuple, but got {type}'.format( @@ -712,6 +629,53 @@ class CursorPagination(BasePagination): return (ordering,) return tuple(ordering) + def decode_cursor(self, request): + """ + Given a request with a cursor, return a `Cursor` instance. + """ + # Determine if we have a cursor, and if so then decode it. + encoded = request.query_params.get(self.cursor_query_param) + if encoded is None: + return None + + # The offset in the cursor is used in situations where we have a + # nearly-unique index. (Eg millisecond precision creation timestamps) + # We guard against malicious users attempting to cause expensive database + # queries, by having a hard cap on the maximum possible size of the offset. + OFFSET_CUTOFF = 1000 + + try: + querystring = b64decode(encoded.encode('ascii')).decode('ascii') + tokens = urlparse.parse_qs(querystring, keep_blank_values=True) + + offset = tokens.get('o', ['0'])[0] + offset = _positive_int(offset, cutoff=OFFSET_CUTOFF) + + reverse = tokens.get('r', ['0'])[0] + reverse = bool(int(reverse)) + + position = tokens.get('p', [None])[0] + except (TypeError, ValueError): + raise NotFound(self.invalid_cursor_message) + + return Cursor(offset=offset, reverse=reverse, position=position) + + def encode_cursor(self, cursor): + """ + Given a Cursor instance, return an url with encoded cursor. + """ + tokens = {} + if cursor.offset != 0: + tokens['o'] = str(cursor.offset) + if cursor.reverse: + tokens['r'] = '1' + if cursor.position is not None: + tokens['p'] = cursor.position + + querystring = urlparse.urlencode(tokens, doseq=True) + encoded = b64encode(querystring.encode('ascii')).decode('ascii') + return replace_query_param(self.base_url, self.cursor_query_param, encoded) + def _get_position_from_instance(self, instance, ordering): attr = getattr(instance, ordering[0].lstrip('-')) return six.text_type(attr) @@ -731,5 +695,5 @@ class CursorPagination(BasePagination): def to_html(self): template = loader.get_template(self.template) - context = Context(self.get_html_context()) - return template.render(context) + context = self.get_html_context() + return template_render(template, context) diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index 437d1339..2dc808f1 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -6,17 +6,22 @@ on the request, such as form content or json encoded data. """ from __future__ import unicode_literals +import json + from django.conf import settings from django.core.files.uploadhandler import StopFutureHandlers from django.http import QueryDict -from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser -from django.http.multipartparser import MultiPartParserError, parse_header, ChunkIter +from django.http.multipartparser import \ + MultiPartParser as DjangoMultiPartParser +from django.http.multipartparser import ( + ChunkIter, MultiPartParserError, parse_header +) from django.utils import six -from django.utils.six.moves.urllib import parse as urlparse from django.utils.encoding import force_text -from rest_framework.exceptions import ParseError +from django.utils.six.moves.urllib import parse as urlparse + from rest_framework import renderers -import json +from rest_framework.exceptions import ParseError class DataAndFiles(object): diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 6ded6bbb..4d5832a7 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -2,8 +2,8 @@ Provides a set of pluggable permission policies. """ from __future__ import unicode_literals + from django.http import Http404 -from rest_framework.compat import get_model_name SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS') @@ -102,7 +102,7 @@ class DjangoModelPermissions(BasePermission): """ kwargs = { 'app_label': model_cls._meta.app_label, - 'model_name': get_model_name(model_cls) + 'model_name': model_cls._meta.model_name } return [perm % kwargs for perm in self.perms_map[method]] @@ -112,15 +112,15 @@ class DjangoModelPermissions(BasePermission): if getattr(view, '_ignore_model_permissions', False): return True - try: + if hasattr(view, 'get_queryset'): queryset = view.get_queryset() - except AttributeError: + else: queryset = getattr(view, 'queryset', None) assert queryset is not None, ( 'Cannot apply DjangoModelPermissions on a view that ' - 'does not have `.queryset` property or overrides the ' - '`.get_queryset()` method.') + 'does not set `.queryset` or have a `.get_queryset()` method.' + ) perms = self.get_required_permissions(request.method, queryset.model) @@ -164,20 +164,20 @@ class DjangoObjectPermissions(DjangoModelPermissions): def get_required_object_permissions(self, method, model_cls): kwargs = { 'app_label': model_cls._meta.app_label, - 'model_name': get_model_name(model_cls) + 'model_name': model_cls._meta.model_name } return [perm % kwargs for perm in self.perms_map[method]] def has_object_permission(self, request, view, obj): - try: + if hasattr(view, 'get_queryset'): queryset = view.get_queryset() - except AttributeError: + else: queryset = getattr(view, 'queryset', None) assert queryset is not None, ( 'Cannot apply DjangoObjectPermissions on a view that ' - 'does not have `.queryset` property or overrides the ' - '`.get_queryset()` method.') + 'does not set `.queryset` or have a `.get_queryset()` method.' + ) model_cls = queryset.model user = request.user diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 00a4a265..744823c4 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -1,18 +1,43 @@ # coding: utf-8 from __future__ import unicode_literals -from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured -from django.core.urlresolvers import get_script_prefix, resolve, NoReverseMatch, Resolver404 + +from collections import OrderedDict + +from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist +from django.core.urlresolvers import ( + NoReverseMatch, Resolver404, get_script_prefix, resolve +) +from django.db.models import Manager from django.db.models.query import QuerySet from django.utils import six from django.utils.encoding import smart_text from django.utils.six.moves.urllib import parse as urlparse from django.utils.translation import ugettext_lazy as _ -from rest_framework.compat import OrderedDict -from rest_framework.fields import get_attribute, empty, Field + +from rest_framework.fields import ( + Field, empty, get_attribute, is_simple_callable, iter_options +) from rest_framework.reverse import reverse from rest_framework.utils import html +class Hyperlink(six.text_type): + """ + A string like object that additionally has an associated name. + We use this for hyperlinked URLs that may render as a named link + in some contexts, or render as a plain URL in others. + """ + def __new__(self, url, name): + ret = six.text_type.__new__(self, url) + ret.name = name + return ret + + def __getnewargs__(self): + return(str(self), self.name,) + + is_hyperlink = True + + class PKOnlyObject(object): """ This is a mock object, used for when we only need the pk of the object @@ -27,13 +52,19 @@ class PKOnlyObject(object): # rather than the parent serializer. MANY_RELATION_KWARGS = ( 'read_only', 'write_only', 'required', 'default', 'initial', 'source', - 'label', 'help_text', 'style', 'error_messages' + 'label', 'help_text', 'style', 'error_messages', 'allow_empty' ) class RelatedField(Field): + queryset = None + html_cutoff = 1000 + html_cutoff_text = _('More than {count} items...') + def __init__(self, **kwargs): - self.queryset = kwargs.pop('queryset', None) + self.queryset = kwargs.pop('queryset', self.queryset) + self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff) + self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text) assert self.queryset is not None or kwargs.get('read_only', None), ( 'Relational field must provide a `queryset` argument, ' 'or set read_only=`True`.' @@ -42,6 +73,8 @@ class RelatedField(Field): 'Relational fields should not provide a `queryset` argument, ' 'when setting read_only=`True`.' ) + kwargs.pop('many', None) + kwargs.pop('allow_empty', None) super(RelatedField, self).__init__(**kwargs) def __new__(cls, *args, **kwargs): @@ -82,8 +115,13 @@ class RelatedField(Field): def get_queryset(self): queryset = self.queryset - if isinstance(queryset, QuerySet): + if isinstance(queryset, (QuerySet, Manager)): # Ensure queryset is re-evaluated whenever used. + # Note that actually a `Manager` class may also be used as the + # queryset argument. This occurs on ModelSerializer fields, + # as it allows us to generate a more expressive 'repr' output + # for the field. + # Eg: 'MyRelationship(queryset=ExampleModel.objects.all())' queryset = queryset.all() return queryset @@ -95,7 +133,12 @@ class RelatedField(Field): # Optimized case, return a mock object only containing the pk attribute. try: instance = get_attribute(instance, self.source_attrs[:-1]) - return PKOnlyObject(pk=instance.serializable_value(self.source_attrs[-1])) + value = instance.serializable_value(self.source_attrs[-1]) + if is_simple_callable(value): + # Handle edge case where the relationship `source` argument + # points to a `get_relationship()` method on the model + value = value().pk + return PKOnlyObject(pk=value) except AttributeError: pass @@ -104,14 +147,34 @@ class RelatedField(Field): @property def choices(self): + queryset = self.get_queryset() + if queryset is None: + # Ensure that field.choices returns something sensible + # even when accessed with a read-only field. + return {} + return OrderedDict([ ( six.text_type(self.to_representation(item)), - six.text_type(item) + self.display_value(item) ) - for item in self.queryset.all() + for item in queryset ]) + @property + def grouped_choices(self): + return self.choices + + def iter_options(self): + return iter_options( + self.grouped_choices, + cutoff=self.html_cutoff, + cutoff_text=self.html_cutoff_text + ) + + def display_value(self, instance): + return six.text_type(instance) + class StringRelatedField(RelatedField): """ @@ -134,10 +197,16 @@ class PrimaryKeyRelatedField(RelatedField): 'incorrect_type': _('Incorrect type. Expected pk value, received {data_type}.'), } + def __init__(self, **kwargs): + self.pk_field = kwargs.pop('pk_field', None) + super(PrimaryKeyRelatedField, self).__init__(**kwargs) + def use_pk_only_optimization(self): return True def to_internal_value(self, data): + if self.pk_field is not None: + data = self.pk_field.to_internal_value(data) try: return self.get_queryset().get(pk=data) except ObjectDoesNotExist: @@ -146,11 +215,14 @@ class PrimaryKeyRelatedField(RelatedField): self.fail('incorrect_type', data_type=type(data).__name__) def to_representation(self, value): + if self.pk_field is not None: + return self.pk_field.to_representation(value.pk) return value.pk class HyperlinkedRelatedField(RelatedField): lookup_field = 'pk' + view_name = None default_error_messages = { 'required': _('This field is required.'), @@ -161,8 +233,9 @@ class HyperlinkedRelatedField(RelatedField): } def __init__(self, view_name=None, **kwargs): - assert view_name is not None, 'The `view_name` argument is required.' - self.view_name = view_name + if view_name is not None: + self.view_name = view_name + assert self.view_name is not None, 'The `view_name` argument is required.' self.lookup_field = kwargs.pop('lookup_field', self.lookup_field) self.lookup_url_kwarg = kwargs.pop('lookup_url_kwarg', self.lookup_field) self.format = kwargs.pop('format', None) @@ -203,6 +276,9 @@ class HyperlinkedRelatedField(RelatedField): kwargs = {self.lookup_url_kwarg: lookup_value} return self.reverse(view_name, kwargs=kwargs, request=request, format=format) + def get_name(self, obj): + return six.text_type(obj) + def to_internal_value(self, data): request = self.context.get('request', None) try: @@ -261,7 +337,7 @@ class HyperlinkedRelatedField(RelatedField): # Return the hyperlink, or error if incorrectly configured. try: - return self.get_url(value, self.view_name, request, format) + url = self.get_url(value, self.view_name, request, format) except NoReverseMatch: msg = ( 'Could not resolve URL for hyperlinked relationship using ' @@ -269,8 +345,21 @@ class HyperlinkedRelatedField(RelatedField): 'model in your API, or incorrectly configured the ' '`lookup_field` attribute on this field.' ) + if value in ('', None): + value_string = {'': 'the empty string', None: 'None'}[value] + msg += ( + " WARNING: The value of the field on the model instance " + "was %s, which may be why it didn't match any " + "entries in your URL conf." % value_string + ) raise ImproperlyConfigured(msg % self.view_name) + if url is None: + return None + + name = self.get_name(value) + return Hyperlink(url, name) + class HyperlinkedIdentityField(HyperlinkedRelatedField): """ @@ -294,7 +383,7 @@ class HyperlinkedIdentityField(HyperlinkedRelatedField): class SlugRelatedField(RelatedField): """ - A read-write field the represents the target of the relationship + A read-write field that represents the target of the relationship by a unique 'slug' attribute. """ @@ -334,9 +423,19 @@ class ManyRelatedField(Field): """ initial = [] default_empty_html = [] + default_error_messages = { + 'not_a_list': _('Expected a list of items but got type "{input_type}".'), + 'empty': _('This list may not be empty.') + } + html_cutoff = 1000 + html_cutoff_text = _('More than {count} items...') def __init__(self, child_relation=None, *args, **kwargs): self.child_relation = child_relation + self.allow_empty = kwargs.pop('allow_empty', True) + self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff) + self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text) + assert child_relation is not None, '`child_relation` is a required argument.' super(ManyRelatedField, self).__init__(*args, **kwargs) self.child_relation.bind(field_name='', parent=self) @@ -354,6 +453,11 @@ class ManyRelatedField(Field): return dictionary.get(self.field_name, empty) def to_internal_value(self, data): + if isinstance(data, type('')) or not hasattr(data, '__iter__'): + self.fail('not_a_list', input_type=type(data).__name__) + if not self.allow_empty and len(data) == 0: + self.fail('empty') + return [ self.child_relation.to_internal_value(item) for item in data @@ -375,16 +479,15 @@ class ManyRelatedField(Field): @property def choices(self): - queryset = self.child_relation.queryset - iterable = queryset.all() if (hasattr(queryset, 'all')) else queryset - items_and_representations = [ - (item, self.child_relation.to_representation(item)) - for item in iterable - ] - return OrderedDict([ - ( - six.text_type(item_representation), - six.text_type(item) + ' - ' + six.text_type(item_representation) - ) - for item, item_representation in items_and_representations - ]) + return self.child_relation.choices + + @property + def grouped_choices(self): + return self.choices + + def iter_options(self): + return iter_options( + self.grouped_choices, + cutoff=self.html_cutoff, + cutoff_text=self.html_cutoff_text + ) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 6c7cdf53..fa64f88e 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -4,24 +4,29 @@ Renderers are used to serialize a response into specific media types. They give us a generic way of being able to handle various media types on the response, such as JSON encoded data or HTML output. -REST framework also provides an HTML renderer the renders the browsable API. +REST framework also provides an HTML renderer that renders the browsable API. """ from __future__ import unicode_literals import json +from collections import OrderedDict + import django from django import forms from django.core.exceptions import ImproperlyConfigured from django.core.paginator import Page from django.http.multipartparser import parse_header -from django.template import Context, RequestContext, loader, Template +from django.template import Template, loader from django.test.client import encode_multipart from django.utils import six -from rest_framework import exceptions, serializers, status, VERSION -from rest_framework.compat import SHORT_SEPARATORS, LONG_SEPARATORS, INDENT_SEPARATORS + +from rest_framework import VERSION, exceptions, serializers, status +from rest_framework.compat import ( + INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, template_render +) from rest_framework.exceptions import ParseError -from rest_framework.settings import api_settings from rest_framework.request import is_form_media_type, override_method +from rest_framework.settings import api_settings from rest_framework.utils import encoders from rest_framework.utils.breadcrumbs import get_breadcrumbs from rest_framework.utils.field_mapping import ClassLookupDict @@ -164,7 +169,7 @@ class TemplateHTMLRenderer(BaseRenderer): template = self.resolve_template(template_names) context = self.resolve_context(data, request, response) - return template.render(context) + return template_render(template, context, request=request) def resolve_template(self, template_names): return loader.select_template(template_names) @@ -172,7 +177,7 @@ class TemplateHTMLRenderer(BaseRenderer): def resolve_context(self, data, request, response): if response.exception: data['status_code'] = response.status_code - return RequestContext(request, data) + return data def get_template_names(self, response, view): if response.template_name: @@ -226,7 +231,7 @@ class StaticHTMLRenderer(TemplateHTMLRenderer): request = renderer_context['request'] template = self.get_exception_template(response) context = self.resolve_context(data, request, response) - return template.render(context) + return template_render(template, context, request=request) return data @@ -245,7 +250,7 @@ class HTMLFormRenderer(BaseRenderer): media_type = 'text/html' format = 'form' charset = 'utf-8' - template_pack = 'rest_framework/horizontal/' + template_pack = 'rest_framework/vertical/' base_template = 'form.html' default_style = ClassLookupDict({ @@ -301,7 +306,10 @@ class HTMLFormRenderer(BaseRenderer): }, serializers.ListSerializer: { 'base_template': 'list_fieldset.html' - } + }, + serializers.FilePathField: { + 'base_template': 'select.html', + }, }) def render_field(self, field, parent_style): @@ -314,6 +322,9 @@ class HTMLFormRenderer(BaseRenderer): style['template_pack'] = parent_style.get('template_pack', self.template_pack) style['renderer'] = self + # Get a clone of the field with text-only value representation. + field = field.as_form_field() + if style.get('input_type') == 'datetime-local' and isinstance(field.value, six.text_type): field.value = field.value.rstrip('Z') @@ -323,38 +334,28 @@ class HTMLFormRenderer(BaseRenderer): template_name = style['template_pack'].strip('/') + '/' + style['base_template'] template = loader.get_template(template_name) - context = Context({'field': field, 'style': style}) - return template.render(context) + context = {'field': field, 'style': style} + return template_render(template, context) def render(self, data, accepted_media_type=None, renderer_context=None): """ Render serializer data and return an HTML form, as a string. """ form = data.serializer - meta = getattr(form, 'Meta', None) - style = getattr(meta, 'style', {}) + + style = renderer_context.get('style', {}) if 'template_pack' not in style: style['template_pack'] = self.template_pack - if 'base_template' not in style: - style['base_template'] = self.base_template style['renderer'] = self - # This API needs to be finessed and finalized for 3.1 - if 'template' in renderer_context: - template_name = renderer_context['template'] - elif 'template' in style: - template_name = style['template'] - else: - template_name = style['template_pack'].strip('/') + '/' + style['base_template'] - - renderer_context = renderer_context or {} - request = renderer_context['request'] + template_pack = style['template_pack'].strip('/') + template_name = template_pack + '/' + self.base_template template = loader.get_template(template_name) - context = RequestContext(request, { + context = { 'form': form, 'style': style - }) - return template.render(context) + } + return template_render(template, context) class BrowsableAPIRenderer(BaseRenderer): @@ -364,6 +365,7 @@ class BrowsableAPIRenderer(BaseRenderer): media_type = 'text/html' format = 'api' template = 'rest_framework/api.html' + filter_template = 'rest_framework/filters/base.html' charset = 'utf-8' form_renderer_class = HTMLFormRenderer @@ -410,9 +412,6 @@ class BrowsableAPIRenderer(BaseRenderer): if method not in view.allowed_methods: return # Not a valid method - if not api_settings.FORM_METHOD_OVERRIDE: - return # Cannot use form overloading - try: view.check_permissions(request) if obj is not None: @@ -498,10 +497,7 @@ class BrowsableAPIRenderer(BaseRenderer): return form_renderer.render( serializer.data, self.accepted_media_type, - dict( - list(self.renderer_context.items()) + - [('template', 'rest_framework/api_form.html')] - ) + {'style': {'template_pack': 'rest_framework/horizontal'}} ) def get_raw_data_form(self, data, view, method, request): @@ -520,13 +516,6 @@ class BrowsableAPIRenderer(BaseRenderer): instance = None with override_method(view, request, method) as request: - # If we're not using content overloading there's no point in - # supplying a generic form, as the view won't treat the form's - # value as the content of the request. - if not (api_settings.FORM_CONTENT_OVERRIDE and - api_settings.FORM_CONTENTTYPE_OVERRIDE): - return None - # Check permissions if not self.show_form_for_method(view, method, request, instance): return @@ -554,39 +543,66 @@ class BrowsableAPIRenderer(BaseRenderer): # Generate a generic form that includes a content type field, # and a content field. - content_type_field = api_settings.FORM_CONTENTTYPE_OVERRIDE - content_field = api_settings.FORM_CONTENT_OVERRIDE - media_types = [parser.media_type for parser in view.parser_classes] choices = [(media_type, media_type) for media_type in media_types] initial = media_types[0] - # NB. http://jacobian.org/writing/dynamic-form-generation/ class GenericContentForm(forms.Form): - def __init__(self): - super(GenericContentForm, self).__init__() - - self.fields[content_type_field] = forms.ChoiceField( - label='Media type', - choices=choices, - initial=initial - ) - self.fields[content_field] = forms.CharField( - label='Content', - widget=forms.Textarea, - initial=content - ) + _content_type = forms.ChoiceField( + label='Media type', + choices=choices, + initial=initial, + widget=forms.Select(attrs={'data-override': 'content-type'}) + ) + _content = forms.CharField( + label='Content', + widget=forms.Textarea(attrs={'data-override': 'content'}), + initial=content + ) return GenericContentForm() def get_name(self, view): return view.get_view_name() - def get_description(self, view): + def get_description(self, view, status_code): + if status_code in (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN): + return '' return view.get_view_description(html=True) def get_breadcrumbs(self, request): - return get_breadcrumbs(request.path) + return get_breadcrumbs(request.path, request) + + def get_filter_form(self, data, view, request): + if not hasattr(view, 'get_queryset') or not hasattr(view, 'filter_backends'): + return + + # Infer if this is a list view or not. + paginator = getattr(view, 'paginator', None) + if isinstance(data, list): + pass + elif (paginator is not None and data is not None): + try: + paginator.get_results(data) + except (TypeError, KeyError): + return + elif not isinstance(data, list): + return + + queryset = view.get_queryset() + elements = [] + for backend in view.filter_backends: + if hasattr(backend, 'to_html'): + html = backend().to_html(request, queryset, view) + if html: + elements.append(html) + + if not elements: + return + + template = loader.get_template(self.filter_template) + context = {'elements': elements} + return template_render(template, context) def get_context(self, data, accepted_media_type, renderer_context): """ @@ -603,7 +619,7 @@ class BrowsableAPIRenderer(BaseRenderer): raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request) raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form - response_headers = dict(response.items()) + response_headers = OrderedDict(sorted(response.items())) renderer_content_type = '' if renderer: renderer_content_type = '%s' % renderer.media_type @@ -621,7 +637,7 @@ class BrowsableAPIRenderer(BaseRenderer): 'view': view, 'request': request, 'response': response, - 'description': self.get_description(view), + 'description': self.get_description(view, response.status_code), 'name': self.get_name(view), 'version': VERSION, 'paginator': paginator, @@ -635,6 +651,8 @@ class BrowsableAPIRenderer(BaseRenderer): 'delete_form': self.get_rendered_html_form(data, view, 'DELETE', request), 'options_form': self.get_rendered_html_form(data, view, 'OPTIONS', request), + 'filter_form': self.get_filter_form(data, view, request), + 'raw_data_put_form': raw_data_put_form, 'raw_data_post_form': raw_data_post_form, 'raw_data_patch_form': raw_data_patch_form, @@ -655,8 +673,7 @@ class BrowsableAPIRenderer(BaseRenderer): template = loader.get_template(self.template) context = self.get_context(data, accepted_media_type, renderer_context) - context = RequestContext(renderer_context['request'], context) - ret = template.render(context) + ret = template_render(template, context, request=renderer_context['request']) # Munge DELETE Response code to allow us to return content # (Do this *after* we've rendered the template so that we include @@ -668,6 +685,89 @@ class BrowsableAPIRenderer(BaseRenderer): return ret +class AdminRenderer(BrowsableAPIRenderer): + template = 'rest_framework/admin.html' + format = 'admin' + + def render(self, data, accepted_media_type=None, renderer_context=None): + self.accepted_media_type = accepted_media_type or '' + self.renderer_context = renderer_context or {} + + response = renderer_context['response'] + request = renderer_context['request'] + view = self.renderer_context['view'] + + if response.status_code == status.HTTP_400_BAD_REQUEST: + # Errors still need to display the list or detail information. + # The only way we can get at that is to simulate a GET request. + self.error_form = self.get_rendered_html_form(data, view, request.method, request) + self.error_title = {'POST': 'Create', 'PUT': 'Edit'}.get(request.method, 'Errors') + + with override_method(view, request, 'GET') as request: + response = view.get(request, *view.args, **view.kwargs) + data = response.data + + template = loader.get_template(self.template) + context = self.get_context(data, accepted_media_type, renderer_context) + ret = template_render(template, context, request=renderer_context['request']) + + # Creation and deletion should use redirects in the admin style. + if (response.status_code == status.HTTP_201_CREATED) and ('Location' in response): + response.status_code = status.HTTP_302_FOUND + response['Location'] = request.build_absolute_uri() + ret = '' + + if response.status_code == status.HTTP_204_NO_CONTENT: + response.status_code = status.HTTP_302_FOUND + try: + # Attempt to get the parent breadcrumb URL. + response['Location'] = self.get_breadcrumbs(request)[-2][1] + except KeyError: + # Otherwise reload current URL to get a 'Not Found' page. + response['Location'] = request.full_path + ret = '' + + return ret + + def get_context(self, data, accepted_media_type, renderer_context): + """ + Render the HTML for the browsable API representation. + """ + context = super(AdminRenderer, self).get_context( + data, accepted_media_type, renderer_context + ) + + paginator = getattr(context['view'], 'paginator', None) + if (paginator is not None and data is not None): + try: + results = paginator.get_results(data) + except (TypeError, KeyError): + results = data + else: + results = data + + if results is None: + header = {} + style = 'detail' + elif isinstance(results, list): + header = results[0] if results else {} + style = 'list' + else: + header = results + style = 'detail' + + columns = [key for key in header.keys() if key != 'url'] + details = [key for key in header.keys() if key != 'url'] + + context['style'] = style + context['columns'] = columns + context['details'] = details + context['results'] = results + context['error_form'] = getattr(self, 'error_form', None) + context['error_title'] = getattr(self, 'error_title', None) + return context + + class MultiPartRenderer(BaseRenderer): media_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg' format = 'multipart' @@ -675,4 +775,12 @@ class MultiPartRenderer(BaseRenderer): BOUNDARY = 'BoUnDaRyStRiNg' if django.VERSION >= (1, 5) else b'BoUnDaRyStRiNg' def render(self, data, accepted_media_type=None, renderer_context=None): + if hasattr(data, 'items'): + for key, value in data.items(): + assert not isinstance(value, dict), ( + "Test data contained a dictionary value for key '%s', " + "but multipart uploads do not support nested data. " + "You may want to consider using format='json' in this " + "test case." % key + ) return encode_multipart(self.BOUNDARY, data) diff --git a/rest_framework/request.py b/rest_framework/request.py index 174a9de5..846cadcd 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -9,16 +9,17 @@ The wrapped request then offers a richer API, in particular : - form overloading of HTTP method, content type and content """ from __future__ import unicode_literals + +import sys + from django.conf import settings from django.http import QueryDict from django.http.multipartparser import parse_header from django.utils import six from django.utils.datastructures import MultiValueDict -from rest_framework import HTTP_HEADER_ENCODING -from rest_framework import exceptions + +from rest_framework import HTTP_HEADER_ENCODING, exceptions from rest_framework.settings import api_settings -import sys -import warnings def is_form_media_type(media_type): @@ -85,7 +86,7 @@ def clone_request(request, method): ret._full_data = request._full_data ret._content_type = request._content_type ret._stream = request._stream - ret._method = method + ret.method = method if hasattr(request, '_user'): ret._user = request._user if hasattr(request, '_auth'): @@ -128,11 +129,6 @@ class Request(object): - authentication_classes(list/tuple). The authentications used to try authenticating the request's user. """ - - _METHOD_PARAM = api_settings.FORM_METHOD_OVERRIDE - _CONTENT_PARAM = api_settings.FORM_CONTENT_OVERRIDE - _CONTENTTYPE_PARAM = api_settings.FORM_CONTENTTYPE_OVERRIDE - def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None): self._request = request @@ -143,7 +139,6 @@ class Request(object): self._data = Empty self._files = Empty self._full_data = Empty - self._method = Empty self._content_type = Empty self._stream = Empty @@ -161,30 +156,10 @@ class Request(object): def _default_negotiator(self): return api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS() - @property - def method(self): - """ - Returns the HTTP method. - - This allows the `method` to be overridden by using a hidden `form` - field on a form POST request. - """ - if not _hasattr(self, '_method'): - self._load_method_and_content_type() - return self._method - @property def content_type(self): - """ - Returns the content type header. - - This should be used instead of `request.META.get('HTTP_CONTENT_TYPE')`, - as it allows the content type to be overridden by using a hidden form - field on a form POST request. - """ - if not _hasattr(self, '_content_type'): - self._load_method_and_content_type() - return self._content_type + meta = self._request.META + return meta.get('CONTENT_TYPE', meta.get('HTTP_CONTENT_TYPE', '')) @property def stream(self): @@ -202,58 +177,12 @@ class Request(object): """ return self._request.GET - @property - def QUERY_PARAMS(self): - """ - Synonym for `.query_params`, for backwards compatibility. - """ - warnings.warn( - "`request.QUERY_PARAMS` is deprecated. Use `request.query_params` instead.", - DeprecationWarning, - stacklevel=1 - ) - return self._request.GET - @property def data(self): if not _hasattr(self, '_full_data'): self._load_data_and_files() return self._full_data - @property - def DATA(self): - """ - Parses the request body and returns the data. - - Similar to usual behaviour of `request.POST`, except that it handles - arbitrary parsers, and also works on methods other than POST (eg PUT). - """ - warnings.warn( - "`request.DATA` is deprecated. Use `request.data` instead.", - DeprecationWarning, - stacklevel=1 - ) - if not _hasattr(self, '_data'): - self._load_data_and_files() - return self._data - - @property - def FILES(self): - """ - Parses the request body and returns any files uploaded in the request. - - Similar to usual behaviour of `request.FILES`, except that it handles - arbitrary parsers, and also works on methods other than POST (eg PUT). - """ - warnings.warn( - "`request.FILES` is deprecated. Use `request.data` instead.", - DeprecationWarning, - stacklevel=1 - ) - if not _hasattr(self, '_files'): - self._load_data_and_files() - return self._files - @property def user(self): """ @@ -310,9 +239,6 @@ class Request(object): """ Parses the request content into `self.data`. """ - if not _hasattr(self, '_content_type'): - self._load_method_and_content_type() - if not _hasattr(self, '_data'): self._data, self._files = self._parse() if self._files: @@ -321,32 +247,14 @@ class Request(object): else: self._full_data = self._data - def _load_method_and_content_type(self): - """ - Sets the method and content_type, and then check if they've - been overridden. - """ - self._content_type = self.META.get('HTTP_CONTENT_TYPE', - self.META.get('CONTENT_TYPE', '')) - - self._perform_form_overloading() - - if not _hasattr(self, '_method'): - self._method = self._request.method - - # Allow X-HTTP-METHOD-OVERRIDE header - if 'HTTP_X_HTTP_METHOD_OVERRIDE' in self.META: - self._method = self.META['HTTP_X_HTTP_METHOD_OVERRIDE'].upper() - def _load_stream(self): """ Return the content body of the request, as a stream. """ + meta = self._request.META try: content_length = int( - self.META.get( - 'CONTENT_LENGTH', self.META.get('HTTP_CONTENT_LENGTH') - ) + meta.get('CONTENT_LENGTH', meta.get('HTTP_CONTENT_LENGTH', 0)) ) except (ValueError, TypeError): content_length = 0 @@ -358,50 +266,6 @@ class Request(object): else: self._stream = six.BytesIO(self.raw_post_data) - def _perform_form_overloading(self): - """ - If this is a form POST request, then we need to check if the method and - content/content_type have been overridden by setting them in hidden - form fields or not. - """ - - USE_FORM_OVERLOADING = ( - self._METHOD_PARAM or - (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM) - ) - - # We only need to use form overloading on form POST requests. - if ( - self._request.method != 'POST' or - not USE_FORM_OVERLOADING or - not is_form_media_type(self._content_type) - ): - return - - # At this point we're committed to parsing the request as form data. - self._data = self._request.POST - self._files = self._request.FILES - self._full_data = self._data.copy() - self._full_data.update(self._files) - - # Method overloading - change the method and remove the param from the content. - if ( - self._METHOD_PARAM and - self._METHOD_PARAM in self._data - ): - self._method = self._data[self._METHOD_PARAM].upper() - - # Content overloading - modify the content type, and force re-parse. - if ( - self._CONTENT_PARAM and - self._CONTENTTYPE_PARAM and - self._CONTENT_PARAM in self._data and - self._CONTENTTYPE_PARAM in self._data - ): - self._content_type = self._data[self._CONTENTTYPE_PARAM] - self._stream = six.BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) - self._data, self._files, self._full_data = (Empty, Empty, Empty) - def _parse(self): """ Parse the request content, returning a two-tuple of (data, files) @@ -493,3 +357,35 @@ class Request(object): return getattr(self._request, attr) except AttributeError: six.reraise(info[0], info[1], info[2].tb_next) + + @property + def DATA(self): + raise NotImplementedError( + '`request.DATA` has been deprecated in favor of `request.data` ' + 'since version 3.0, and has been fully removed as of version 3.2.' + ) + + @property + def POST(self): + # Ensure that request.POST uses our request parsing. + if not _hasattr(self, '_data'): + self._load_data_and_files() + if is_form_media_type(self.content_type): + return self.data + return QueryDict('', encoding=self._request._encoding) + + @property + def FILES(self): + # Leave this one alone for backwards compat with Django's request.FILES + # Different from the other two cases, which are not valid property + # names on the WSGIRequest class. + if not _hasattr(self, '_files'): + self._load_data_and_files() + return self._files + + @property + def QUERY_PARAMS(self): + raise NotImplementedError( + '`request.QUERY_PARAMS` has been deprecated in favor of `request.query_params` ' + 'since version 3.0, and has been fully removed as of version 3.2.' + ) diff --git a/rest_framework/response.py b/rest_framework/response.py index 9319e708..0e97668e 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -5,9 +5,12 @@ it is initialized with unrendered data, instead of a pre-rendered string. The appropriate renderer is called during Django's template response rendering. """ from __future__ import unicode_literals -from django.utils.six.moves.http_client import responses + from django.template.response import SimpleTemplateResponse from django.utils import six +from django.utils.six.moves.http_client import responses + +from rest_framework.serializers import Serializer class Response(SimpleTemplateResponse): @@ -27,6 +30,15 @@ class Response(SimpleTemplateResponse): For example being set automatically by the `APIView`. """ super(Response, self).__init__(None, status=status) + + if isinstance(data, Serializer): + msg = ( + 'You passed a Serializer instance as data, but ' + 'probably meant to pass serialized `.data` or ' + '`.error`. representation.' + ) + raise AssertionError(msg) + self.data = data self.template_name = template_name self.exception = exception @@ -86,7 +98,7 @@ class Response(SimpleTemplateResponse): state = super(Response, self).__getstate__() for key in ( 'accepted_renderer', 'renderer_context', 'resolver_match', - 'client', 'request', 'wsgi_request' + 'client', 'request', 'json', 'wsgi_request' ): if key in state: del state[key] diff --git a/rest_framework/reverse.py b/rest_framework/reverse.py index e6d3f563..5a7ba09a 100644 --- a/rest_framework/reverse.py +++ b/rest_framework/reverse.py @@ -2,11 +2,35 @@ Provide urlresolver functions that return fully qualified URLs or view names """ from __future__ import unicode_literals + from django.core.urlresolvers import reverse as django_reverse from django.core.urlresolvers import NoReverseMatch from django.utils import six from django.utils.functional import lazy +from rest_framework.settings import api_settings +from rest_framework.utils.urls import replace_query_param + + +def preserve_builtin_query_params(url, request=None): + """ + Given an incoming request, and an outgoing URL representation, + append the value of any built-in query parameters. + """ + if request is None: + return url + + overrides = [ + api_settings.URL_FORMAT_OVERRIDE, + ] + + for param in overrides: + if param and (param in request.GET): + value = request.GET[param] + url = replace_query_param(url, param, value) + + return url + def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): """ @@ -17,13 +41,15 @@ def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra scheme = getattr(request, 'versioning_scheme', None) if scheme is not None: try: - return scheme.reverse(viewname, args, kwargs, request, format, **extra) + url = scheme.reverse(viewname, args, kwargs, request, format, **extra) except NoReverseMatch: # In case the versioning scheme reversal fails, fallback to the # default implementation - pass + url = _reverse(viewname, args, kwargs, request, format, **extra) + else: + url = _reverse(viewname, args, kwargs, request, format, **extra) - return _reverse(viewname, args, kwargs, request, format, **extra) + return preserve_builtin_query_params(url, request) def _reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 4df852bf..39605923 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -16,17 +16,17 @@ For example, you might have a `urls.py` that looks something like this: from __future__ import unicode_literals import itertools -from collections import namedtuple -from django.conf.urls import patterns, url +from collections import OrderedDict, namedtuple + +from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import NoReverseMatch + from rest_framework import views -from rest_framework.compat import get_resolver_match, OrderedDict from rest_framework.response import Response from rest_framework.reverse import reverse from rest_framework.urlpatterns import format_suffix_patterns - Route = namedtuple('Route', ['url', 'mapping', 'name', 'initkwargs']) DynamicDetailRoute = namedtuple('DynamicDetailRoute', ['url', 'name', 'initkwargs']) DynamicListRoute = namedtuple('DynamicListRoute', ['url', 'name', 'initkwargs']) @@ -76,7 +76,7 @@ class BaseRouter(object): @property def urls(self): if not hasattr(self, '_urls'): - self._urls = patterns('', *self.get_urls()) + self._urls = self.get_urls() return self._urls @@ -174,7 +174,7 @@ class SimpleRouter(BaseRouter): url_path = initkwargs.pop("url_path", None) or methodname ret.append(Route( url=replace_methodname(route.url, url_path), - mapping=dict((httpmethod, methodname) for httpmethod in httpmethods), + mapping={httpmethod: methodname for httpmethod in httpmethods}, name=replace_methodname(route.name, url_path), initkwargs=initkwargs, )) @@ -283,13 +283,15 @@ class DefaultRouter(SimpleRouter): def get(self, request, *args, **kwargs): ret = OrderedDict() - namespace = get_resolver_match(request).namespace + namespace = request.resolver_match.namespace for key, url_name in api_root_dict.items(): if namespace: url_name = namespace + ':' + url_name try: ret[key] = reverse( url_name, + args=args, + kwargs=kwargs, request=request, format=kwargs.get('format', None) ) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index cf491c72..99d36a8a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -11,30 +11,30 @@ python primitives. response content is handled by parsers and renderers. """ from __future__ import unicode_literals + +import warnings + from django.db import models -from django.db.models.fields import FieldDoesNotExist, Field as DjangoModelField -from django.db.models import query +from django.db.models.fields import Field as DjangoModelField +from django.db.models.fields import FieldDoesNotExist +from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ -from rest_framework.compat import ( - postgres_fields, - unicode_to_repr, - DurationField as ModelDurationField, -) + +from rest_framework.compat import DurationField as ModelDurationField +from rest_framework.compat import JSONField as ModelJSONField +from rest_framework.compat import postgres_fields, unicode_to_repr from rest_framework.utils import model_meta from rest_framework.utils.field_mapping import ( - get_url_kwargs, get_field_kwargs, - get_relation_kwargs, get_nested_relation_kwargs, - ClassLookupDict + ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs, + get_relation_kwargs, get_url_kwargs ) from rest_framework.utils.serializer_helpers import ( - ReturnDict, ReturnList, BoundField, NestedBoundField, BindingDict + BindingDict, BoundField, NestedBoundField, ReturnDict, ReturnList ) from rest_framework.validators import ( UniqueForDateValidator, UniqueForMonthValidator, UniqueForYearValidator, UniqueTogetherValidator ) -import warnings - # Note: We do the following so that users of the framework can use this style: # @@ -43,18 +43,19 @@ import warnings # This helps keep the separation between model fields, form fields, and # serializer fields more explicit. -from rest_framework.relations import * # NOQA -from rest_framework.fields import * # NOQA - +from rest_framework.fields import * # NOQA # isort:skip +from rest_framework.relations import * # NOQA # isort:skip # We assume that 'validators' are intended for the child serializer, # rather than the parent serializer. LIST_SERIALIZER_KWARGS = ( 'read_only', 'write_only', 'required', 'default', 'initial', 'source', - 'label', 'help_text', 'style', 'error_messages', - 'instance', 'data', 'partial', 'context' + 'label', 'help_text', 'style', 'error_messages', 'allow_empty', + 'instance', 'data', 'partial', 'context', 'allow_null' ) +ALL_FIELDS = '__all__' + # BaseSerializer # -------------- @@ -117,12 +118,17 @@ class BaseSerializer(Field): kwargs['child'] = cls() return CustomListSerializer(*args, **kwargs) """ + allow_empty = kwargs.pop('allow_empty', None) child_serializer = cls(*args, **kwargs) - list_kwargs = {'child': child_serializer} - list_kwargs.update(dict([ - (key, value) for key, value in kwargs.items() + list_kwargs = { + 'child': child_serializer, + } + if allow_empty is not None: + list_kwargs['allow_empty'] = allow_empty + list_kwargs.update({ + key: value for key, value in kwargs.items() if key in LIST_SERIALIZER_KWARGS - ])) + }) meta = getattr(cls, 'Meta', None) list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer) return list_serializer_class(*args, **list_kwargs) @@ -155,6 +161,22 @@ class BaseSerializer(Field): 'You cannot call `.save()` on a serializer with invalid data.' ) + # Guard against incorrect use of `serializer.save(commit=False)` + assert 'commit' not in kwargs, ( + "'commit' is not a valid keyword argument to the 'save()' method. " + "If you need to access data before committing to the database then " + "inspect 'serializer.validated_data' instead. " + "You can also pass additional keyword arguments to 'save()' if you " + "need to set extra attributes on the saved model instance. " + "For example: 'serializer.save(owner=request.user)'.'" + ) + + assert not hasattr(self, '_data'), ( + "You cannot call `.save()` after accessing `serializer.data`." + "If you need to access data before committing to the database then " + "inspect 'serializer.validated_data' instead. " + ) + validated_data = dict( list(self.validated_data.items()) + list(kwargs.items()) @@ -196,7 +218,7 @@ class BaseSerializer(Field): self._errors = {} if self._errors and raise_exception: - raise ValidationError(self._errors) + raise ValidationError(self.errors) return not bool(self._errors) @@ -283,10 +305,10 @@ def get_validation_error_detail(exc): elif isinstance(exc.detail, dict): # If errors may be a dict we use the standard {key: list of values}. # Here we ensure that all the values are *lists* of errors. - return dict([ - (key, value if isinstance(value, list) else [value]) + return { + key: value if isinstance(value, list) else [value] for key, value in exc.detail.items() - ]) + } elif isinstance(exc.detail, list): # Errors raised as a list are non-field errors. return { @@ -318,6 +340,20 @@ class Serializer(BaseSerializer): self._fields[key] = value return self._fields + @cached_property + def _writable_fields(self): + return [ + field for field in self.fields.values() + if (not field.read_only) or (field.default is not empty) + ] + + @cached_property + def _readable_fields(self): + return [ + field for field in self.fields.values() + if not field.write_only + ] + def get_fields(self): """ Returns a dictionary of {field_name: field_instance}. @@ -355,7 +391,7 @@ class Serializer(BaseSerializer): # We override the default field access in order to support # nested HTML forms. if html.is_html_input(dictionary): - return html.parse_html_dict(dictionary, prefix=self.field_name) + return html.parse_html_dict(dictionary, prefix=self.field_name) or empty return dictionary.get(self.field_name, empty) def run_validation(self, data=empty): @@ -392,10 +428,7 @@ class Serializer(BaseSerializer): ret = OrderedDict() errors = OrderedDict() - fields = [ - field for field in self.fields.values() - if (not field.read_only) or (field.default is not empty) - ] + fields = self._writable_fields for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) @@ -423,7 +456,7 @@ class Serializer(BaseSerializer): Object instance -> Dict of primitive datatypes. """ ret = OrderedDict() - fields = [field for field in self.fields.values() if not field.write_only] + fields = self._readable_fields for field in fields: try: @@ -484,11 +517,13 @@ class ListSerializer(BaseSerializer): many = True default_error_messages = { - 'not_a_list': _('Expected a list of items but got type "{input_type}".') + 'not_a_list': _('Expected a list of items but got type "{input_type}".'), + 'empty': _('This list may not be empty.') } def __init__(self, *args, **kwargs): self.child = kwargs.pop('child', copy.deepcopy(self.child)) + self.allow_empty = kwargs.pop('allow_empty', True) assert self.child is not None, '`child` is a required argument.' assert not inspect.isclass(self.child), '`child` has not been instantiated.' super(ListSerializer, self).__init__(*args, **kwargs) @@ -544,6 +579,12 @@ class ListSerializer(BaseSerializer): api_settings.NON_FIELD_ERRORS_KEY: [message] }) + if not self.allow_empty and len(data) == 0: + message = self.error_messages['empty'] + raise ValidationError({ + api_settings.NON_FIELD_ERRORS_KEY: [message] + }) + ret = [] errors = [] @@ -567,7 +608,8 @@ class ListSerializer(BaseSerializer): """ # Dealing with nested relationships, data can be a Manager, # so, first get a queryset from the Manager if needed - iterable = data.all() if isinstance(data, (models.Manager, query.QuerySet)) else data + iterable = data.all() if isinstance(data, models.Manager) else data + return [ self.child.to_representation(item) for item in iterable ] @@ -593,6 +635,16 @@ class ListSerializer(BaseSerializer): """ Save and return a list of object instances. """ + # Guard against incorrect use of `serializer.save(commit=False)` + assert 'commit' not in kwargs, ( + "'commit' is not a valid keyword argument to the 'save()' method. " + "If you need to access data before committing to the database then " + "inspect 'serializer.validated_data' instead. " + "You can also pass additional keyword arguments to 'save()' if you " + "need to set extra attributes on the saved model instance. " + "For example: 'serializer.save(owner=request.user)'.'" + ) + validated_data = [ dict(list(attrs.items()) + list(kwargs.items())) for attrs in self.validated_data @@ -735,15 +787,27 @@ class ModelSerializer(Serializer): models.TimeField: TimeField, models.URLField: URLField, models.GenericIPAddressField: IPAddressField, + models.FilePathField: FilePathField, } if ModelDurationField is not None: serializer_field_mapping[ModelDurationField] = DurationField + if ModelJSONField is not None: + serializer_field_mapping[ModelJSONField] = JSONField serializer_related_field = PrimaryKeyRelatedField + serializer_related_to_field = SlugRelatedField serializer_url_field = HyperlinkedIdentityField serializer_choice_field = ChoiceField - # Default `create` and `update` behavior... + # The field name for hyperlinked identity fields. Defaults to 'url'. + # You can modify this using the API setting. + # + # Note that if you instead need modify this on a per-serializer basis, + # you'll also need to ensure you update the `create` method on any generic + # views, to correctly handle the 'Location' response header for + # "HTTP 201 Created" responses. + url_field_name = None + # Default `create` and `update` behavior... def create(self, validated_data): """ We have a bit of extra checking around this in order to provide @@ -807,6 +871,10 @@ class ModelSerializer(Serializer): def update(self, instance, validated_data): raise_errors_on_nested_writes('update', self, validated_data) + # Simply set each attribute on the instance, and then save it. + # Note that unlike `.create()` we don't need to treat many-to-many + # relationships as being a special case. During updates we already + # have an instance pk for the relationships to be associated with. for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() @@ -820,6 +888,9 @@ class ModelSerializer(Serializer): Return the dict of field names -> field instances that should be used for `self.fields` when instantiating the serializer. """ + if self.url_field_name is None: + self.url_field_name = api_settings.URL_FIELD_NAME + assert hasattr(self, 'Meta'), ( 'Class {serializer_class} missing "Meta" attribute'.format( serializer_class=self.__class__.__name__ @@ -894,10 +965,10 @@ class ModelSerializer(Serializer): fields = getattr(self.Meta, 'fields', None) exclude = getattr(self.Meta, 'exclude', None) - if fields and not isinstance(fields, (list, tuple)): + if fields and fields != ALL_FIELDS and not isinstance(fields, (list, tuple)): raise TypeError( - 'The `fields` option must be a list or tuple. Got %s.' % - type(fields).__name__ + 'The `fields` option must be a list or tuple or "__all__". ' + 'Got %s.' % type(fields).__name__ ) if exclude and not isinstance(exclude, (list, tuple)): @@ -913,6 +984,20 @@ class ModelSerializer(Serializer): ) ) + if fields is None and exclude is None: + warnings.warn( + "Creating a ModelSerializer without either the 'fields' " + "attribute or the 'exclude' attribute is pending deprecation " + "since 3.3.0. Add an explicit fields = '__all__' to the " + "{serializer_class} serializer.".format( + serializer_class=self.__class__.__name__ + ), + PendingDeprecationWarning + ) + + if fields == ALL_FIELDS: + fields = None + if fields is not None: # Ensure that all declared fields have also been included in the # `Meta.fields` option. @@ -985,7 +1070,7 @@ class ModelSerializer(Serializer): elif hasattr(model_class, field_name): return self.build_property_field(field_name, model_class) - elif field_name == api_settings.URL_FIELD_NAME: + elif field_name == self.url_field_name: return self.build_url_field(field_name, model_class) return self.build_unknown_field(field_name, model_class) @@ -1003,6 +1088,19 @@ class ModelSerializer(Serializer): # Fields with choices get coerced into `ChoiceField` # instead of using their regular typed field. field_class = self.serializer_choice_field + # Some model fields may introduce kwargs that would not be valid + # for the choice field. We need to strip these out. + # Eg. models.DecimalField(max_digits=3, decimal_places=1, choices=DECIMAL_CHOICES) + valid_kwargs = set(( + 'read_only', 'write_only', + 'required', 'default', 'initial', 'source', + 'label', 'help_text', 'style', + 'error_messages', 'validators', 'allow_null', 'allow_blank', + 'choices' + )) + for key in list(field_kwargs.keys()): + if key not in valid_kwargs: + field_kwargs.pop(key) if not issubclass(field_class, ModelField): # `model_field` is only valid for the fallback case of @@ -1032,6 +1130,11 @@ class ModelSerializer(Serializer): field_class = self.serializer_related_field field_kwargs = get_relation_kwargs(field_name, relation_info) + to_field = field_kwargs.pop('to_field', None) + if to_field and not relation_info.related_model._meta.get_field(to_field).primary_key: + field_kwargs['slug_field'] = to_field + field_class = self.serializer_related_to_field + # `view_name` is only valid for hyperlinked relationships. if not issubclass(field_class, HyperlinkedRelatedField): field_kwargs.pop('view_name', None) @@ -1095,8 +1198,8 @@ class ModelSerializer(Serializer): if extra_kwargs.get('default') and kwargs.get('required') is False: kwargs.pop('required') - if kwargs.get('read_only', False): - extra_kwargs.pop('required', None) + if extra_kwargs.get('read_only', kwargs.get('read_only', False)): + extra_kwargs.pop('required', None) # Read only fields should always omit the 'required' argument. kwargs.update(extra_kwargs) @@ -1118,44 +1221,6 @@ class ModelSerializer(Serializer): kwargs['read_only'] = True extra_kwargs[field_name] = kwargs - # These are all pending deprecation. - write_only_fields = getattr(self.Meta, 'write_only_fields', None) - if write_only_fields is not None: - warnings.warn( - "The `Meta.write_only_fields` option is deprecated. " - "Use `Meta.extra_kwargs={: {'write_only': True}}` instead.", - DeprecationWarning, - stacklevel=3 - ) - for field_name in write_only_fields: - kwargs = extra_kwargs.get(field_name, {}) - kwargs['write_only'] = True - extra_kwargs[field_name] = kwargs - - view_name = getattr(self.Meta, 'view_name', None) - if view_name is not None: - warnings.warn( - "The `Meta.view_name` option is deprecated. " - "Use `Meta.extra_kwargs={'url': {'view_name': ...}}` instead.", - DeprecationWarning, - stacklevel=3 - ) - kwargs = extra_kwargs.get(api_settings.URL_FIELD_NAME, {}) - kwargs['view_name'] = view_name - extra_kwargs[api_settings.URL_FIELD_NAME] = kwargs - - lookup_field = getattr(self.Meta, 'lookup_field', None) - if lookup_field is not None: - warnings.warn( - "The `Meta.lookup_field` option is deprecated. " - "Use `Meta.extra_kwargs={'url': {'lookup_field': ...}}` instead.", - DeprecationWarning, - stacklevel=3 - ) - kwargs = extra_kwargs.get(api_settings.URL_FIELD_NAME, {}) - kwargs['lookup_field'] = lookup_field - extra_kwargs[api_settings.URL_FIELD_NAME] = kwargs - return extra_kwargs def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs): @@ -1178,13 +1243,10 @@ class ModelSerializer(Serializer): for model_field in model_fields.values(): # Include each of the `unique_for_*` field names. - unique_constraint_names |= set([ - model_field.unique_for_date, - model_field.unique_for_month, - model_field.unique_for_year - ]) + unique_constraint_names |= {model_field.unique_for_date, model_field.unique_for_month, + model_field.unique_for_year} - unique_constraint_names -= set([None]) + unique_constraint_names -= {None} # Include each of the `unique_together` field names, # so long as all the field names are included on the serializer. @@ -1298,10 +1360,10 @@ class ModelSerializer(Serializer): # which may map onto a model field. Any dotted field name lookups # cannot map to a field, and must be a traversal, so we're not # including those. - field_names = set([ + field_names = { field.source for field in self.fields.values() if (field.source != '*') and ('.' not in field.source) - ]) + } # Note that we make sure to check `unique_together` both on the # base model class, but also on any parent classes. @@ -1367,7 +1429,7 @@ if hasattr(models, 'IPAddressField'): if postgres_fields: class CharMappingField(DictField): - child = CharField() + child = CharField(allow_blank=True) ModelSerializer.serializer_field_mapping[postgres_fields.HStoreField] = CharMappingField ModelSerializer.serializer_field_mapping[postgres_fields.ArrayField] = ListField @@ -1389,7 +1451,7 @@ class HyperlinkedModelSerializer(ModelSerializer): `Meta.fields` option is not specified. """ return ( - [api_settings.URL_FIELD_NAME] + + [self.url_field_name] + list(declared_fields.keys()) + list(model_info.fields.keys()) + list(model_info.forward_relations.keys()) diff --git a/rest_framework/settings.py b/rest_framework/settings.py index a3e9f590..adf73712 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -18,14 +18,14 @@ REST framework settings, checking for user settings first, then falling back to the defaults. """ from __future__ import unicode_literals -from django.test.signals import setting_changed + from django.conf import settings +from django.test.signals import setting_changed from django.utils import six + from rest_framework import ISO_8601 from rest_framework.compat import importlib -USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None) - DEFAULTS = { # Base API policies 'DEFAULT_RENDERER_CLASSES': ( @@ -91,13 +91,8 @@ DEFAULTS = { ), 'TEST_REQUEST_DEFAULT_FORMAT': 'multipart', - # Browser enhancements - 'FORM_METHOD_OVERRIDE': '_method', - 'FORM_CONTENT_OVERRIDE': '_content', - 'FORM_CONTENTTYPE_OVERRIDE': '_content_type', - 'URL_ACCEPT_OVERRIDE': 'accept', + # Hyperlink settings 'URL_FORMAT_OVERRIDE': 'format', - 'FORMAT_SUFFIX_KWARG': 'format', 'URL_FIELD_NAME': 'url', @@ -116,11 +111,6 @@ DEFAULTS = { 'COMPACT_JSON': True, 'COERCE_DECIMAL_TO_STRING': True, 'UPLOADED_FILES_USE_URL': True, - - # Pending deprecation: - 'PAGINATE_BY': None, - 'PAGINATE_BY_PARAM': None, - 'MAX_PAGINATE_BY': None } @@ -169,7 +159,7 @@ def import_from_string(val, setting_name): module_path, class_name = '.'.join(parts[:-1]), parts[-1] module = importlib.import_module(module_path) return getattr(module, class_name) - except ImportError as e: + except (ImportError, AttributeError) as e: msg = "Could not import '%s' for API setting '%s'. %s: %s." % (val, setting_name, e.__class__.__name__, e) raise ImportError(msg) @@ -186,10 +176,17 @@ class APISettings(object): and return the class, rather than the string literal. """ def __init__(self, user_settings=None, defaults=None, import_strings=None): - self.user_settings = user_settings or {} + if user_settings: + self._user_settings = user_settings self.defaults = defaults or DEFAULTS self.import_strings = import_strings or IMPORT_STRINGS + @property + def user_settings(self): + if not hasattr(self, '_user_settings'): + self._user_settings = getattr(settings, 'REST_FRAMEWORK', {}) + return self._user_settings + def __getattr__(self, attr): if attr not in self.defaults.keys(): raise AttributeError("Invalid API setting: '%s'" % attr) @@ -202,7 +199,7 @@ class APISettings(object): val = self.defaults[attr] # Coerce import strings into classes - if val and attr in self.import_strings: + if attr in self.import_strings: val = perform_import(val, attr) # Cache the result @@ -210,7 +207,7 @@ class APISettings(object): return val -api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) +api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS) def reload_api_settings(*args, **kwargs): diff --git a/rest_framework/static/rest_framework/css/bootstrap-tweaks.css b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css index f455c904..17085b49 100644 --- a/rest_framework/static/rest_framework/css/bootstrap-tweaks.css +++ b/rest_framework/static/rest_framework/css/bootstrap-tweaks.css @@ -1,6 +1,6 @@ /* -This CSS file contains some tweaks specific to the included Bootstrap theme. +This CSS file contains some tweaks specific to the included Bootstrap theme. It's separate from `style.css` so that it can be easily overridden by replacing a single block in the template. @@ -213,3 +213,22 @@ body a:hover { .request-info { clear:both; } + +.horizontal-checkbox label { + padding-top: 0; +} + +.horizontal-checkbox label { + padding-top: 0 !important; +} + +.horizontal-checkbox input { + float: left; + width: 20px; + margin-top: 3px; +} + +.modal-footer form { + margin-left: 5px; + margin-right: 5px; +} diff --git a/rest_framework/static/rest_framework/css/bootstrap.min.css b/rest_framework/static/rest_framework/css/bootstrap.min.css index a9f35cee..d65c66b1 100644 --- a/rest_framework/static/rest_framework/css/bootstrap.min.css +++ b/rest_framework/static/rest_framework/css/bootstrap.min.css @@ -1,5 +1,5 @@ /*! - * Bootstrap v3.2.0 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;width:100% \9;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;width:100% \9;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-horizontal .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg,.form-horizontal .form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{position:absolute;z-index:-1;filter:alpha(opacity=0);opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow="1"],.progress-bar[aria-valuenow="2"]{min-width:30px}.progress-bar[aria-valuenow="0"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/rest_framework/static/rest_framework/css/default.css b/rest_framework/static/rest_framework/css/default.css index ede54bd1..f4e645ca 100644 --- a/rest_framework/static/rest_framework/css/default.css +++ b/rest_framework/static/rest_framework/css/default.css @@ -3,7 +3,7 @@ content running up underneath it. */ h1 { - font-weight: 500; + font-weight: 300; } h2, h3 { @@ -33,6 +33,14 @@ h2, h3 { margin-right: 1em; } +td.nested { + padding: 0 !important; +} + +td.nested > table { + margin: 0; +} + form select, form input, form textarea { width: 90%; } @@ -65,3 +73,11 @@ pre { border-bottom: none; padding-bottom: 0px; } + +#filtersModal form input[type=submit] { + width: auto; +} + +#filtersModal .modal-body h2 { + margin-top: 0 +} diff --git a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot index 4a4ca865..b93a4953 100644 Binary files a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot and b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot differ diff --git a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.svg b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.svg index 25691af8..94fb5490 100644 --- a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.svg +++ b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.svg @@ -6,224 +6,283 @@ - - - + + - - + + - - - - - - - - - + + + + + + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf index 67fa00bf..1413fc60 100644 Binary files a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf and b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf differ diff --git a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff index 8c54182a..9e612858 100644 Binary files a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff and b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff differ diff --git a/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2 b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/rest_framework/static/rest_framework/js/ajax-form.js b/rest_framework/static/rest_framework/js/ajax-form.js new file mode 100644 index 00000000..db07fd8f --- /dev/null +++ b/rest_framework/static/rest_framework/js/ajax-form.js @@ -0,0 +1,97 @@ +function replaceDocument(docString) { + var doc = document.open("text/html"); + doc.write(docString); + doc.close(); +} + + +function doAjaxSubmit(e) { + var form = $(this); + var btn = $(this.clk); + var method = btn.data('method') || form.data('method') || form.attr('method') || 'GET'; + method = method.toUpperCase() + if (method === 'GET') { + // GET requests can always use standard form submits. + return; + } + + var contentType = + form.find('input[data-override="content-type"]').val() || + form.find('select[data-override="content-type"] option:selected').text(); + if (method === 'POST' && !contentType) { + // POST requests can use standard form submits, unless we have + // overridden the content type. + return; + } + + // At this point we need to make an AJAX form submission. + e.preventDefault(); + + var url = form.attr('action'); + var data; + if (contentType) { + data = form.find('[data-override="content"]').val() || '' + } else { + contentType = form.attr('enctype') || form.attr('encoding') + if (contentType === 'multipart/form-data') { + if (!window.FormData) { + alert('Your browser does not support AJAX multipart form submissions'); + return; + } + // Use the FormData API and allow the content type to be set automatically, + // so it includes the boundary string. + // See https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects + contentType = false; + data = new FormData(form[0]); + } else { + contentType = 'application/x-www-form-urlencoded; charset=UTF-8' + data = form.serialize(); + } + } + + var ret = $.ajax({ + url: url, + method: method, + data: data, + contentType: contentType, + processData: false, + headers: {'Accept': 'text/html; q=1.0, */*'}, + }); + ret.always(function(data, textStatus, jqXHR) { + if (textStatus != 'success') { + jqXHR = data; + } + var responseContentType = jqXHR.getResponseHeader("content-type") || ""; + if (responseContentType.toLowerCase().indexOf('text/html') === 0) { + replaceDocument(jqXHR.responseText); + try { + // Modify the location and scroll to top, as if after page load. + history.replaceState({}, '', url); + scroll(0,0); + } catch(err) { + // History API not supported, so redirect. + window.location = url; + } + } else { + // Not HTML content. We can't open this directly, so redirect. + window.location = url; + } + }); + return ret; +} + + +function captureSubmittingElement(e) { + var target = e.target; + var form = this; + form.clk = target; +} + + +$.fn.ajaxForm = function() { + var options = {} + return this + .unbind('submit.form-plugin click.form-plugin') + .bind('submit.form-plugin', options, doAjaxSubmit) + .bind('click.form-plugin', options, captureSubmittingElement); +}; diff --git a/rest_framework/static/rest_framework/js/bootstrap.min.js b/rest_framework/static/rest_framework/js/bootstrap.min.js index 7c1561a8..133aeecb 100644 --- a/rest_framework/static/rest_framework/js/bootstrap.min.js +++ b/rest_framework/static/rest_framework/js/bootstrap.min.js @@ -1,6 +1,7 @@ /*! - * Bootstrap v3.2.0 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.2.0",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.2.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b).on("keydown.bs.carousel",a.proxy(this.keydown,this)),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.2.0",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.to=function(b){var c=this,d=this.getItemIndex(this.$active=this.$element.find(".item.active"));return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,f&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(e)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one("bsTransitionEnd",function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(m)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.2.0",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(){this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.one("bsTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.2.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/rest_framework/static/rest_framework/js/csrf.js b/rest_framework/static/rest_framework/js/csrf.js new file mode 100644 index 00000000..4e8da0de --- /dev/null +++ b/rest_framework/static/rest_framework/js/csrf.js @@ -0,0 +1,47 @@ +function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} + +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} + +function sameOrigin(url) { + // test that a given url is a same-origin URL + // url could be relative or scheme relative or absolute + var host = document.location.host; // host + port + var protocol = document.location.protocol; + var sr_origin = '//' + host; + var origin = protocol + sr_origin; + // Allow absolute or scheme relative URLs to same origin + return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || + (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || + // or any other URL that isn't scheme relative or absolute i.e relative. + !(/^(\/\/|http:|https:).*/.test(url)); +} + +var csrftoken = getCookie('csrftoken'); + +$.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { + // Send the token to same-origin, relative URLs only. + // Send the token only if the method warrants CSRF protection + // Using the CSRFToken value acquired earlier + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } +}); diff --git a/rest_framework/static/rest_framework/js/default.js b/rest_framework/static/rest_framework/js/default.js index 22e5efde..dc6fd642 100644 --- a/rest_framework/static/rest_framework/js/default.js +++ b/rest_framework/static/rest_framework/js/default.js @@ -59,3 +59,7 @@ if (selectedTab && selectedTab.length > 0) { // If no tab selected, display rightmost tab. $('.form-switcher a:first').tab('show'); } + +$(window).load(function(){ + $('#errorModal').modal('show'); +}); diff --git a/rest_framework/static/rest_framework/js/jquery-1.11.3.min.js b/rest_framework/static/rest_framework/js/jquery-1.11.3.min.js new file mode 100644 index 00000000..0f60b7bd --- /dev/null +++ b/rest_framework/static/rest_framework/js/jquery-1.11.3.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("