diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
index 90595a6d3..740c20086 100644
--- a/.github/workflows/preview.yml
+++ b/.github/workflows/preview.yml
@@ -32,10 +32,10 @@ jobs: # A workflow run is made up of one or more jobs that can run sequentially
run: bundle exec rake build:preview
- name: Test html
run: bundle exec rake test:html
- - name: Test internal links
- run: bundle exec rake test:links:internal
- - name: Test *iiif.io* links
- run: bundle exec rake test:links:iiif
+# - name: Test internal links
+# run: bundle exec rake test:links:internal
+# - name: Test *iiif.io* links
+# run: bundle exec rake test:links:iiif
- name: Spec tests
run: bundle exec rake api:spec
- name: Create GitHub deployment # Deploy to Preview site
diff --git a/.gitignore b/.gitignore
index 2a8d1df61..ff449984d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,6 @@ tmp/
iiifc-theme
Gemfile.lock
vendor
+
+.vscode
+.idea
diff --git a/image_sources/presentation_diagrams.graffle b/image_sources/presentation_diagrams.graffle
index 250215097..147641fd2 100644
Binary files a/image_sources/presentation_diagrams.graffle and b/image_sources/presentation_diagrams.graffle differ
diff --git a/source/_includes/links.md b/source/_includes/links.md
index 4e9560006..6c0e773e8 100644
--- a/source/_includes/links.md
+++ b/source/_includes/links.md
@@ -189,7 +189,7 @@
[org-open-annotation-multi]: http://www.openannotation.org/spec/core/multiplicity.html#Choice "Open Annotation: Multiplicity"
[org-open-annotation-types]: http://www.openannotation.org/spec/core/core.html#BodyTargetType "Open Annotation: Body Target"
[org-open-annotation]: http://www.openannotation.org/spec/core/ "Open Annotation"
-[org-openarchives-rsync]: http://openarchives.org/rs/toc
+[org-openarchives-rsync]: https://openarchives.org/rs/toc
[org-rfc-2119]: https://tools.ietf.org/html/rfc2119 "RFC Keywords"
[org-rfc-2617]: https://tools.ietf.org/html/rfc2617 "HTTP Authentication: Basic and Digest Access Authentication"
[org-rfc-2818]: https://tools.ietf.org/html/rfc2818 "HTTP Over TLS"
diff --git a/source/assets/images/p4/use-case-5a.png b/source/assets/images/p4/use-case-5a.png
new file mode 100644
index 000000000..e00fd7e91
Binary files /dev/null and b/source/assets/images/p4/use-case-5a.png differ
diff --git a/source/assets/images/p4/whale-anno-camera.png b/source/assets/images/p4/whale-anno-camera.png
new file mode 100644
index 000000000..7c3d24793
Binary files /dev/null and b/source/assets/images/p4/whale-anno-camera.png differ
diff --git a/source/assets/images/p4/whale-default-camera.png b/source/assets/images/p4/whale-default-camera.png
new file mode 100644
index 000000000..1e31ba235
Binary files /dev/null and b/source/assets/images/p4/whale-default-camera.png differ
diff --git a/source/content-state/2.0/index.md b/source/content-state/2.0/index.md
new file mode 100644
index 000000000..9afb4e15f
--- /dev/null
+++ b/source/content-state/2.0/index.md
@@ -0,0 +1,844 @@
+---
+title: "IIIF Content State Protocols API 2.0"
+title_override: "IIIF Content State Protocols API 2.0"
+id: discovery-api-content-state
+layout: spec
+cssversion: 3
+tags: [specifications, presentation-api]
+major: 2
+minor: 0
+patch: 0
+pre: draft
+redirect_from:
+ - /content-state/index.html
+ - /content-state/2/index.html
+pre: draft
+editors:
+ - name: Michael Appleby
+ ORCID: https://orcid.org/0000-0002-1266-298X
+ institution: Yale University
+ - name: Dawn Childress
+ orcid: https://orcid.org/0000-0003-2602-2788
+ institution: UCLA
+ - name: Tom Crane
+ ORCID: https://orcid.org/0000-0003-1881-243X
+ institution: Digirati
+ - name: Jeff Mixter
+ orcid: https://orcid.org/0000-0002-8411-2952
+ institution: OCLC
+ - name: Robert Sanderson
+ ORCID: https://orcid.org/0000-0003-4441-6852
+ institution: Yale University
+ - name: Julie Winchester
+ ORCID:
+ institution: Duke University
+hero:
+ image: ''
+
+---
+
+
+## Status of this Document
+{:.no_toc}
+__This Version:__ {{ page.major }}.{{ page.minor }}.{{ page.patch }}{% if page.pre != 'final' %}-{{ page.pre }}{% endif %}
+
+__Latest Stable Version:__ [{{ site.data.apis.content-state.stable.major }}.{{ site.data.apis.content-state.stable.minor }}.{{ site.data.apis.content-state.stable.patch }}][contenstate-stable-version]
+
+__Previous Version:__ [1.0][contentstate09]
+
+**Editors**
+
+{% include api/editors.md editors=page.editors %}
+
+{% include copyright.md %}
+
+
+----
+
+## 1. Introduction
+{: #introduction}
+
+The [IIIF Presentation API][prezi-api] defines a Content State as any IIIF Presentation API resource, or a part of a IIIF Presentation API resource, or group of resources. The Content State is a compact format that can be used to initialize a view of another (typically larger) IIIF Presentation resource in a client It might be generated by a client to transfer a particular view of a resource into another client. The [IIIF Presentation API][prezi-api] provides the format of the _content state_, and this specification T provides mechanisms for passing it between applications regardless of their different user interfaces and capabilities.
+
+
+### 1.1. Objectives and Scope
+{: #objectives-and-scope}
+
+The objective of the IIIF Content State API is to provide a standardized format for sharing of a particular view of one or more [IIIF Presentation API][prezi-api] resources, such as a Collection, a Manifest, or a particular part of a Manifest.
+
+Example use cases for sharing a resource, or a particular view of a resource, include:
+
+* A user follows a link from a search result, which opens a IIIF viewer. The viewer focuses on the relevant part of the object, such as a particular line of text that contains the searched-for term.
+* A user opens several IIIF Manifests to compare paintings, then wishes to share this set of views with a colleague.
+
+Other examples include bookmarks, citations, playlists and deep linking into digital objects.
+
+This specification also describes how a content state is passed from one application to another, such as from a discovery platform to a viewer, so that the viewer can show the intended part of the resource (or resources) to the user. A simple example would be passing a content state description embedded within a query parameter of a URI that tells the viewer to load a IIIF Manifest.
+
+A viewer can also _export_ a content state, for example to enable a user to share a particular view with another user, or publish it as a reference or citation. Different IIIF clients will have different user interfaces and audiences, and may choose which of these mechanisms to support. Further detailed examples may be found in the [IIIF Cookbook][annex-cookbook].
+
+The _content state_ is distinct from the state of any particular viewer's user interface. A viewer state is likely to be client-specific and would concern which panels are open, which options are selected and similar user interface details. Viewers with very different user interfaces can all implement support for the Content State API.
+
+This specification provides mechanisms that IIIF compatible software can use to expose, share and transfer content state descriptions, but does not specify what form IIIF compatible software itself should take. A web page, a JavaScript web application, a native mobile application, a desktop application, or display kiosk hardware are all capable of sending and receiving content states.
+
+The intended audience of this document is developers of applications that implement the Presentation API, although other communities may benefit as well.
+
+
+### 1.2. Terminology
+{: #terminology}
+
+The specification uses the following terms:
+
+* __HTTP(S)__: The HTTP or HTTPS URI scheme and internet protocol.
+
+* __array__, __JSON object__, __number__, and __string__ in this document are to be interpreted as defined by the [JavaScript Object Notation (JSON)][org-rfc-8259] specification.
+
+* __Annotation__ is to be interpreted as defined in the [W3C Web Annotation Data Model][org-w3c-webanno] specification.
+
+The key words _MUST_, _MUST NOT_, _REQUIRED_, _SHALL_, _SHALL NOT_, _SHOULD_, _SHOULD NOT_, _RECOMMENDED_, _MAY_, and _OPTIONAL_ in this document are to be interpreted as described in [RFC 2119][org-rfc-2119].
+
+## 2. Content State
+{: #content-state}
+
+A content state is a JSON-LD data structure that uses the models described by the [IIIF Presentation API][prezi-api] and [W3C Web Annotation Data Model][org-w3c-webanno] specifications. The data structure is a description of a resource, or part of a resource. This data structure can be used by clients to load the resource required, and present a particular part of the resource to the user. The state might be very simple: for example, a link to a Manifest. A more complex content state would provide more detail about the intended target. The following are all behaviors a passed-in content state might produce in a compatible client:
+
+* _load Manifest M_
+* _load Manifest M, navigate to Canvas C, and zoom in to the region defined by xywh=X,Y,W,H_
+* _load Manifest M, navigate such that Range R is selected, and start playing the time-based canvas C within Range R at time t=T_
+
+These intentions can be expressed formally as an Annotation that targets the intended resource, or part of the resource. This content state Annotation can be easily passed into web applications, for example, as a query string parameter, or an HTML `data-` attribute, as defined in the following section on protocol and initialization mechanisms.
+
+### 2.1. Annotation Model for Content State
+
+The target of the Annotation is the described IIIF resource, using exactly the same patterns as any other IIIF-targeting Annotation that a IIIF viewer might encounter.
+
+The target could be any resource described by the Presentation API, for example, a:
+
+* Manifest
+* Range
+* Canvas
+* spatial or temporal fragment of a Canvas
+* spatial or temporal point on a Canvas
+
+The Annotation _MUST_ contain enough information about de-referenceable resources to show the content in context. For example, a Canvas is often not enough information for a viewer to show the intended view; the Manifest that the Canvas is part of needs to be declared so that the client can load that Manifest first, and then find the Canvas within it.
+
+### 2.2. Form of Annotation
+
+Annotations _MAY_ have one or more [motivations][org-w3c-webanno-motivation], that provide the reason(s) why it was created. For example, the `bookmarking` motivation is for annotations intended to convey a bookmark to a resource.
+
+A content state Annotation _MUST_ have the motivation `contentState`. This motivation is not defined by either the [W3C Web Annotation Data Model][org-w3c-webanno] or the IIIF Presentation API, and is chosen to avoid potential ambiguity when the target of the content state Annotation is itself an Annotation. The content state annotation _MAY_ also have additional motivations such as `bookmarking`, `identifying` and so on, but it is its particular `contentState` motivation that would trigger the required behavior in compatible software.
+
+A content state annotation can be provided in several forms, described in the following sections.
+
+Publishers _SHOULD_ provide the content state Annotation in one of the following forms.
+A client _SHOULD_ be able to accept and process the content state in all of these forms.
+
+#### 2.2.1. Full Annotation
+
+The content state _MAY_ be supplied in JSON-LD as a fully formed Annotation compliant with the [W3C Web Annotation Data Model][org-w3c-webanno] with the motivation `contentState`, as in this example:
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/Annotation-server/bookmarks/b1",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": {
+ "id": "https://example.org/iiif/item1/manifest",
+ "type": "Manifest"
+ }
+}
+```
+
+The target of the annotation is, in this case, a complete IIIF resource (here, a Manifest) but in more complex cases, the target could be a part of a IIIF resource.
+
+#### 2.2.2. Annotation URI
+
+The content state _MAY_ be supplied as a string whose value is the URI of an Annotation with the motivation `contentState`, that the client must dereference and process. For the example in 2.2.1 above, this would be the URI `https://example.org/Annotation-server/bookmarks/b1`. The response from that URI would be the JSON above.
+
+#### 2.2.3. Target Body // see #2294
+
+The content state _MAY_ be supplied as JSON-LD, as the value of the `target` property of an implied Annotation with the motivation `contentState`. For the example in 2.2.1, this would be:
+
+```json
+{
+ "id": "https://example.org/iiif/item1/manifest",
+ "type": "Manifest"
+}
+```
+
+This form is better suited to scenarios where compactness is important.
+
+#### 2.2.4. Target URI
+
+The content state _MAY_ be supplied as a string whose value is the `id` (the dereferenceable URI) of the `target` property only. This is the simplest form and is just the URI of a resource. For the example in 2.2.1, this would be the URI `https://example.org/iiif/item1/manifest`. The client would simply load this Manifest and display it.
+
+Examples 2.2.2 and 2.2.4 are both URIs. It is up to the client to recognise that 2.2.4 is a Manifest, whereas 2.2.2 is a content state Annotation that points to a Manifest. The client _MUST_ inspect the `type` property to determine what the dereferenced resource is. If the `type` is Annotation, the client _MUST_ also look at the `motivation` property to determine if the Annotation is a content state. If the `motivation` is not `contentState`, but the Annotation has been encountered where a content state is expected, the client _MUST_ assume that the Annotation itself is the intended IIIF content.
+
+If the `type` property of the target resource, once dereferenced, is `Canvas` or `Range`, then the resource _MUST_ include the Manifest URI that the Canvas or Range is to be found in, using the `partOf` property, as in example 2.2.5 below.
+
+#### 2.2.5. Limitations of Simple URIs
+
+While supporting many requirements for sharing resources and initializing a client application, the 2.2.4 form is not capable of expressing content states that are part of a IIIF resource, such as a region of a Canvas, or a Canvas URI that is not itself de-referenceable. One of the other forms must be used for these purposes.
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/import/1",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": {
+ "id": "https://example.org/object1/canvas7#xywh=1000,2000,1000,2000",
+ "type": "Canvas",
+ "partOf": [{
+ "id": "https://example.org/object1/manifest",
+ "type": "Manifest"
+ }]
+ }
+}
+```
+
+This description cannot be conveyed by just a Canvas URI or a Manifest URI; it needs the structure provided by a content state Annotation. It can be reduced to the target body form, but no further:
+
+```json
+{
+ "id": "https://example.org/object1/canvas7#xywh=1000,2000,1000,2000",
+ "type": "Canvas",
+ "partOf": [{
+ "id": "https://example.org/object1/manifest",
+ "type": "Manifest"
+ }]
+}
+```
+
+The requirement to dereference the URI before being able to process the content state might also have usability or performance implications around network latency. For example, if a client is processing a lot of content state Annotations, or the environment is untrusted and dereferencing unrecognized URIs to determine what they are might introduce the possibility of malicious URIs being constructed to adversely affect either the client or the publisher of the URI, then the other forms are likely to be preferred.
+
+
+## 3. Protocols
+{: #initialization}
+
+This section defines _Protocols_ for the transfer of this data, so that implementing software can send or receive a content state without specific knowledge of other participating software. These protocols make use of widely supported features of modern web browsers:
+
+* Passing a content state as a query string parameter in an HTTP GET request (3.1)
+* Passing a content state as a parameter in an HTTP POST request (3.2)
+* Reacting to the [Paste][org-mozilla-paste] event, where the pasted data is the URI of a content state or the full content state Annotation (3.3)
+* Using the [Drag and Drop API][org-mozilla-drag-drop] to expose and accept content states (3.4)
+* Uploading content state from the client machine via the [FileReader][org-mozilla-filereader] interface (3.5)
+* Initialising a client via an HTML5 `data-*` attribute (3.6)
+
+The data structure _MAY_ be made available to the client using these protocols. Other mechanisms are possible, but outside the scope of the specification.
+
+
+### 3.1. Linking: HTTP GET (Query String) Parameter
+{: #initialization-mechanisms-link}
+
+If a client is capable of reading the content state from the value of an HTTP GET request parameter, it _MUST_ look for the content state in a request parameter called `iiif-content`.
+
+If the intention is that the linked-to client loads an entire IIIF resource without focusing on any particular part, the simplest form of the content state _SHOULD_ be used:
+
+// Talk about URI encoding here, as per #2292
+
+```html
+{% raw %}
+Link to Viewer
+{% endraw %}
+```
+
+In this case the client at `https://example.org/viewer` would load the resource at `https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json`, determine that it is a Manifest (rather than, say, a Collection), and process accordingly.
+
+When the intention is to initialize the viewer at a particular part of the resource, the client provides more than just a URI; it must provide either the full annotation as in 2.2.1., or, preferably (for brevity) the body of the annotation, as in 2.2.3.
+
+In both of these scenarios, the GET request parameter _MUST_ be content-state-encoded as described in [Section 6][contentstate-encoding] below. This is required to avoid potential corruption of the content state, as explained in [Section 6][contentstate-encoding].
+
+In the following examples, the same Annotation is used each time. As the full JSON-LD annotation, this is:
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/content-states/1",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": {
+ "id": "https://damsssl.llgc.org.uk/iiif/2.0/4389767/canvas/4389772.json",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json",
+ "type": "Manifest"
+ }
+ ]
+ }
+}
+```
+
+An example of this usage would be a link from search results to a particular page of a digitized book, or a stored bookmark of a particular page (i.e., Canvas).
+
+Without the required content-state-encoding, the (invalid) link to the viewer would look like this:
+
+```html
+{% raw %}
+
+INVALID, unencoded link to Viewer
+{% endraw %}
+```
+
+However, this JSON-LD content MUST be content-state-encoded as in [Section 6][contentstate-encoding] below:
+
+```html
+{% raw %}
+Link to Viewer
+{% endraw %}
+```
+
+To reduce the size of the encoded content state, it _SHOULD_ be passed as just the `target` property of an implied Annotation with motivation `contentState`, that is, the fragment:
+
+```json
+{
+ "id": "https://damsssl.llgc.org.uk/iiif/2.0/4389767/canvas/4389772.json",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json",
+ "type": "Manifest"
+ }
+ ]
+}
+```
+
+This results in a more compact form, unencoded (and invalid), this would be:
+
+```html
+{% raw %}
+
+Link to Viewer
+{% endraw %}
+```
+
+However, this fragment MUST be content-state-encoded as in [Section 6][contentstate-encoding] below:
+
+```html
+{% raw %}
+Link to Viewer
+{% endraw %}
+```
+
+#### 3.1.1. Load by Reference
+
+This is a variant of the above, with the parameter value being a URI rather than the content itself.
+
+```html
+Link to Viewer
+```
+
+If the Content State is a URI, it _MUST NOT_ be content-state-encoded.
+
+### 3.2. HTTP POST (Form) Parameter
+{: #initialization-mechanisms-post}
+
+
+The same data structure, in the same formats, may instead be passed to a server in an HTTP POST, for example by a JavaScript client. This is also suited to server-side web applications, such as a web page rendering citations or a view initialized on the server. It is not suitable for initialising a standalone JavaScript application, as the POST data is typically unavailable.
+
+The data _SHOULD_ be sent with the `Content-Type` header value `application/json`, and the body _MUST NOT_ be content-state-encoded.
+
+```javascript
+
+async function postContentState(url, contentState) {
+ // Default options are marked with *
+ const response = await fetch(url, {
+ method: 'POST',
+ mode: 'cors',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(contentState) // body data type must match "Content-Type" header
+ });
+ return response.json(); // parses JSON response into native JavaScript objects
+}
+
+let target = 'https://example.com/bookmarking-service';
+let myBookmark = captureContentState(); // implementation not specified!
+
+postContentState(target, myBookmark)
+ .then(reply => {
+ console.log(reply);
+ });
+```
+In this example, the server at `https://example.com/bookmarking-service` should expect to process the _unencoded_ content state in the same forms and variants as above.
+
+
+### 3.3. Accepting the Content State as a Paste Operation
+{: #initialization-mechanisms-paste}
+
+The client allows the content state URI or data to be pasted into part of its UI (e.g., from a "Load..." option exposing a `textarea` element for the user to manually paste into). A client can also accept a paste operation transparently, by reading from the clipboard:
+
+```html
+
+```
+
+The first parameter to `getData` is the content type, and for maximum interoperability within the scope of this specification this _MUST_ be `"text/plain"`.
+
+In that scenario the user can paste the content state directly into the application. If this scenario is supported, the client _SHOULD_ accept resource URIs directly, such as the URI of a Manifest. The content state _MUST NOT_ be content-state-encoded.
+
+Refer to [Section 3.7][contentstate-export] below for methods of exporting data, including the _Copy to Clipboard_ pattern, a natural pairing with a paste operation, from one viewer to another.
+
+
+### 3.4. Drag and Drop
+{: #initialization-mechanisms-dragdrop}
+
+In this scenario, one system provides a _draggable_ element:
+
+```html
+
+
+
+```
+
+And another system provides an element capable of receiving a `drop` event:
+
+```html
+
+
+
+
+
+```
+
+This technique can also be used within the same client, to drag a content state from one part to another.
+
+The first parameter to `setData` and `getData` is the content type, and for maximum interoperability within the scope of this specification this _MUST_ be `"text/plain"`. Applications can assert multiple additional content types for their own custom behavior, such as dragging from the application to the desktop and saving as a file, but this is outside the scope of the specification. In the above example, the content of the drag and drop operation could be a plain URI, or unencoded JSON-LD. It _MUST NOT_ be content-state-encoded.
+
+
+### 3.5. Upload File
+
+A JavaScript client can accept content state from the local machine via the `FileReader` interface:
+
+```html
+
+
+
+```
+
+The same rules apply; the viewer _MUST_ dereference and process the Annotation at that URI. The uploaded content _MUST NOT_ be content-state-encoded.
+
+### 3.6. Common Initialization Parameter
+
+If a IIIF client can accept a content state via a custom HTML attribute, then it _SHOULD_ use the attribute `data-iiif-content` for this purpose, to assist page developers using that client in understanding what the attribute is for. A viewer that accepts a content state _SHOULD_ process an Annotation in any of the forms described in the GET parameter section, but _MUST NOT_ be content-state-encoded.
+
+```html
+
+Loading a whole manifest
+
+
+
+Loading a manifest to show a particular Canvas
+
+
+```
+
+### 3.7. Exporting Current Content State from Viewer
+{: #export}
+
+There are further ways in which a client can _export_ its current content state, beyond populating a drag and drop operation as in example 3.4. While interoperability concerns require this specification to describe the ways in which a client can _accept_ state, the ways in which a content state might have arrived on a user's clipboard are out of scope here, and are covered in the [IIIF Cookbook][annex-cookbook]. These include:
+
+* Copy to Clipboard
+* Download File
+* Display for Copying
+* Send to External Service
+
+
+## 4. Processing Received Content States
+
+Once the content state has been created (following the patterns in section 2) and transferred to the receiving client (using a protocol described in section 3), the client must then process the received content state.
+
+If the content state is a simple URI, the client _MUST_ load the resource at that URI and process it. The resource at that URI _MUST_ be the full content state Annotation as in 2.2.2 or a IIIF Resource as in 2.2.4. That is, the dereferenced response _MUST_ be JSON-LD, and _SHOULD_ have a value of `type` taken from `Annotation`, `Collection`, `Manifest`, `Canvas` and `Range`. The response _MUST_ use UTF-8 encoding.
+
+If the content state is JSON-LD the client _MUST_ inspect the `type` property to decide whether the value is the full content state Annotation (indicated by the additional presence of the `contentState` motivation, as in example 2.2.1), or the value of the `target` property of an implied content state Annotation (as in example 2.2.3).
+
+
+## 5. Examples of Content States
+
+The following examples demonstrate the use of the existing IIIF Presentation API and W3C Web Annotation Data Model to describe parts of resources. Any IIIF resource that can be expressed in the Presentation model can be used in a content state. The full form of the Annotation (as if it were available at the URI given in the `id` property) has been used in each case. Further examples can be found in the [IIIF Cookbook][annex-cookbook].
+
+Publishers _SHOULD_ provide the simplest JSON-LD representation, and not assume that any client can handle arbitrarily complex content states.
+
+### 5.1. A Region of a Canvas in a Manifest
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/import/1",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": {
+ "id": "https://example.org/object1/canvas7#xywh=1000,2000,1000,2000",
+ "type": "Canvas",
+ "partOf": [{
+ "id": "https://example.org/object1/manifest",
+ "type": "Manifest"
+ }]
+ }
+}
+```
+
+When processed by a viewer, the user should see the rectangle `1000,2000,1000,2000` highlighted on the Canvas given in the `id` parameter; the viewer loads the manifest linked to in the `partOf` property and navigates to that canvas, and then fills the viewport with that rectangle or otherwise draws attention to it.
+
+
+### 5.2. Start Playing at a Point in a Recording
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/import/2",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/id1/canvas1",
+ "type": "Canvas",
+ "partOf": [{
+ "id": "https://example.org/iiif/id1/manifest",
+ "type": "Manifest"
+ }]
+ },
+ "selector": {
+ "type": "PointSelector",
+ "t": 14.5
+ }
+ }
+}
+```
+
+This example should cause a viewer to open Manifest `https://example.org/iiif/id1/manifest`, navigate to Canvas `https://example.org/iiif/id1/canvas1`, and start playing at 14.5 seconds into that canvas.
+
+
+### 5.3. Multiple Targets for a Comparison View
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/import/3",
+ "type": "Annotation",
+ "motivation": ["contentState"],
+ "target": [
+ {
+ "id": "https://example.org/iiif/item1/canvas37",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://example.org/iiif/item1/manifest",
+ "type": "Manifest"
+ }
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/item2/canvas99",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://example.org/iiif/item2/manifest",
+ "type": "Manifest"
+ }
+ ]
+ }
+ ]
+}
+```
+
+Here the viewer should open two manifests at once (if it is capable of such a view).
+
+
+### 5.4. Search Results
+
+The following example uses the compact, query string form of the content state to demonstrate what HTML search results linking to a particular viewer might look like.
+
+Firstly, in non-valid, unencoded form to show the annotation:
+
+```html
+Results for "cats"
+
+ -
+
+
+
...she has often seen a cat without a grin but never a grin without a cat
+
+
+
+```
+
+...and then in valid, content-state-encoded form:
+
+```html
+Results for "cats"
+
+ -
+
+
...she has often seen a cat without a grin but never a grin without a cat
+
+
+
+```
+
+## 6. Content State Encoding
+
+When a Content State is sent in an HTTP GET operation such as a query string parameter on a link in a search result or even an email, it is vulnerable to corruption - it might get encoded and re-encoded before it arrives at a viewer or other IIIF-compatible software. This section defines the requirements for safely encoding content states, to provide the string representation seen in the above examples.
+
+### 6.1. Choice of encoding mechanism
+
+A content state will contain characters from JSON syntax, and may contain strings from any language. The identifiers of annotations and other resources within the content state _MAY_ be Internationalized Resource Identifiers (IRIs), as defined in [RFC 3987][org-rfc-3987]. For these reasons the content state _MUST_ be _encoded_ using an encoding that:
+
+* Is simple to implement, for both decoding and encoding, in a web browser and on the server
+* Will safely encode any UTF-16 string from JavaScript, avoiding known browser issues such as the ["Unicode Problem"][btoa-unicode-problem]
+* Is impervious to _double encoding_ - that is, once encoded, any further likely encodings of any request or response parts will not change the already-encoded content state.
+
+This specification defines a two-step encoding that uses both the [encodeURIComponent][org-ecma-encodeuricomponent] function available in web browsers, followed by [Base 64 Encoding with URL and Filename Safe Alphabet][org-rfc-4648-5] ("base64url") encoding, with padding characters removed. The initial encodeURIComponent step allows any UTF-16 string in JavaScript to then be safely encoded to base64url in a web browser. The final step of removing padding removes the "=" character which might be subject to further percent-encoding as part of a URL.
+
+This process is described by the term _content-state-encoding_ throughout this specification.
+
+**Note that "base64url" is not the same encoding as "base64".**
+
+The process to encode a content state is:
+
+* encode to a UTF-8 string described by [encodeURIComponent][org-ecma-encodeuricomponent]
+* encode the resulting UTF-8 string as [base64url][org-rfc-4648-5]
+* remove any "=" padding characters from the end
+
+Conversely to decode a content state:
+
+* restore any removed "=" padding characters to the end of the string to make it a multiple of 4 characters long.
+* decode the resulting string from base64url to a UTF-8 string
+* decode the resulting UTF-8 string as described by [decodeURIComponent][org-ecma-decodeuricomponent]
+
+Code samples for these operations are given in the next section.
+
+### 6.2. Content State encoding and URI requirements
+
+* Any content state that is in JSON-LD form, rather than a simple URI string, _MUST_ be _content-state-encoded_ when passed as a GET parameter on a query string, and a client _MUST_ accept it in this form.
+
+* Content state resource identifiers must be URIs, for consistency with the IIIF Presentation API. They _MUST NOT_ contain characters that would make them [IRIs][org-rfc-3987] but not URIs, even though the [W3C Web Annotation Data Model][org-w3c-webanno] permits IRIs.
+
+* When the content state is a plain URI, rather than a JSON object, it _MUST NOT_ be content-state-encoded.
+
+* Any content state passed by mechanisms other than a HTTP GET request parameter _MUST NOT_ be content-state-encoded.
+
+* When published as inline, encoded JSON-LD in the full form given in section 2.2. above, the content state Annotation _MAY_ omit the `id` and `@context` properties.
+
+* When published on a server for clients to fetch over HTTP, in the same way a client would fetch a Manifest or Collection, content states _MUST_ be valid JSON-LD documents conforming to the [IIIF Presentation API][prezi-api] and served as described in [Section 7][contentstate-http] below. They _MUST NOT_ be content-state-encoded, but _MAY_ have other encodings appropriate for JSON content, such as `Content-Encoding: gzip` to reduce the response size.
+
+
+### 6.3. Examples of Content State Encoding
+
+JavaScript and Python examples are given below. Examples for other languages and frameworks can be found in the [IIIF Cookbook][annex-cookbook].
+
+#### 6.3.1. JavaScript
+
+```javascript
+function encodeContentState(plainContentState) {
+ let uriEncoded = encodeURIComponent(plainContentState); // using built in function
+ let base64 = btoa(uriEncoded); // using built in function
+ let base64url = base64.replace(/\+/g, "-").replace(/\//g, "_");
+ let base64urlNoPadding = base64url.replace(/=/g, "");
+ return base64urlNoPadding;
+}
+
+
+function decodeContentState(encodedContentState) {
+ let base64url = restorePadding(encodedContentState);
+ let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
+ let base64Decoded = atob(base64); // using built in function
+ let uriDecoded = decodeURIComponent(base64Decoded); // using built in function
+ return uriDecoded;
+}
+
+
+function restorePadding(s) {
+ // The length of the restored string must be a multiple of 4
+ let pad = s.length % 4;
+ let padding = "";
+ if (pad) {
+ if (pad === 1) {
+ throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding');
+ }
+ s += '===='.slice(0, 4 - pad);
+ }
+ return s + padding;
+}
+```
+
+#### 6.3.2. Python
+
+// Add in one for query string as #2292
+
+```python
+import base64
+import urllib
+
+def encode_content_state(plain_content_state):
+ # The safe='' is required below, as the default is '/'
+ # We want to match the behavour of encodeURIComponent and encode '/' as '%2F'
+ uri_encoded = urllib.parse.quote(plain_content_state, safe='') # equivalent of encodeURIComponent
+ utf8_encoded = uri_encoded.encode("UTF-8")
+ base64url = base64.urlsafe_b64encode(utf8_encoded)
+ utf8_decoded = base64url.decode("UTF-8")
+ base64url_no_padding = utf8_decoded.replace("=", "")
+ return base64url_no_padding
+
+
+def decode_content_state(encoded_content_state):
+ padded_content_state = restore_padding(encoded_content_state)
+ base64url_decoded = base64.urlsafe_b64decode(padded_content_state)
+ utf8_decoded = base64url_decoded.decode("UTF-8")
+ uri_decoded = urllib.parse.unquote(utf8_decoded)
+ return uri_decoded
+
+
+def restore_padding(s):
+ # string length must be a multiple of 4
+ pad = len(s) % 4
+ padding = ""
+ if pad:
+ if pad == 1:
+ raise Exception("InvalidLengthError: Input base64url string is the wrong length to determine padding")
+ padding = "=" * (4 - pad)
+ return s + padding
+
+```
+
+Given the following content state annotation:
+
+```json
+{
+ "id": "https://example.org/object1/canvas7#xywh=1000,2000,1000,2000",
+ "type": "Canvas",
+ "partOf": [{
+ "id": "https://example.org/object1/manifest",
+ "type": "Manifest"
+ }]
+}
+```
+
+The JSON can be optionally condensed to remove unnecessary whitespace:
+
+```
+{"id":"https://example.org/object1/canvas7#xywh=1000,2000,1000,2000","type":"Canvas","partOf":[{"id":"https://example.org/object1/manifest","type":"Manifest"}]}
+```
+
+The condensed form is then encoded (this example in Python):
+
+```python
+>>> encode_content_state(condensed)
+
+'JTdCJTIyaWQlMjIlM0ElMjJodHRwcyUzQSUyRiUyRmV4YW1wbGUub3JnJTJGb2JqZWN0MSUyRmNhbnZhczclMjN4eXdoJTNEMTAwMCUyQzIwMDAlMkMxMDAwJTJDMjAwMCUyMiUyQyUyMnR5cGUlMjIlM0ElMjJDYW52YXMlMjIlMkMlMjJwYXJ0T2YlMjIlM0ElNUIlN0IlMjJpZCUyMiUzQSUyMmh0dHBzJTNBJTJGJTJGZXhhbXBsZS5vcmclMkZvYmplY3QxJTJGbWFuaWZlc3QlMjIlMkMlMjJ0eXBlJTIyJTNBJTIyTWFuaWZlc3QlMjIlN0QlNUQlN0Q'
+```
+
+The string "JTdC..." is the now URI-safe, encoded form of the content state, suitable for passing to and from web applications.
+
+
+
+## 7. HTTP Requests and Responses
+
+This section describes the _RECOMMENDED_ request and response interactions for the API, when served as JSON-LD bodies of HTTP responses. It does not apply to _inline_ content states, which are encoded as described in section 2.3, and transfered by the other mechanisms described above. This section follows the specification given in [Section 6][prezi30-http] of the Presentation API.
+
+### 7.1. Requests
+
+An HTTP request for a content state is the same as an HTTP request for a Presentation API resource. Unlike [IIIF Image API][image-api] requests, or other parameterized services, the URIs for Presentation API resources cannot be assumed to follow any particular pattern. A client that fetches URIs for content states and URIs for Presentation API resources (such as Manifests and Collections) by the same mechanism _MUST_ inspect the response to determine whether it is a Presentation API resource, or a content state that references part of a Presentation API resource.
+
+### 7.2. Responses
+
+The format for content states as HTTP responses is JSON, as described above. It is good practice for all resources with an HTTP(S) URI to provide their description when the URI is dereferenced. If a resource is [referenced][prezi30-terminology] within a response, rather than being [embedded][prezi30-terminology], then it _MUST_ be able to be dereferenced.
+
+If the server receives a request with an `Accept` header, it _SHOULD_ respond following the rules of [content negotiation][org-rfc-7231-conneg]. Note that content types provided in the `Accept` header of the request _MAY_ include parameters, for example `profile` or `charset`.
+
+If the request does not include an `Accept` header, the HTTP `Content-Type` header of the response _SHOULD_ have the value `application/ld+json` (JSON-LD) with the `profile` parameter given as the context document: `http://iiif.io/api/presentation/3/context.json`.
+
+``` none
+Content-Type: application/ld+json;profile="http://iiif.io/api/presentation/3/context.json"
+```
+{: .urltemplate}
+
+If the `Content-Type` header `application/ld+json` cannot be generated due to server configuration details, then the `Content-Type` header _SHOULD_ instead be `application/json` (regular JSON), without a `profile` parameter.
+
+``` none
+Content-Type: application/json
+```
+{: .urltemplate}
+
+The HTTP server _MUST_ follow the [CORS requirements][org-w3c-cors] to enable browser-based clients to retrieve the descriptions. Recipes for enabling CORS and conditional Content-Type headers are provided in the [Apache HTTP Server Implementation Notes][notes-apache].
+
+
+## Appendices
+
+### A. Acknowledgements
+{: #acknowledgements}
+
+Many thanks to the members of the [IIIF community][iiif-community] for their continuous engagement, innovative ideas, and feedback.
+
+This version is due to the work of the [IIIF Discovery Technical Specification Group][groups-discovery], chaired by Antoine Isaac (Europeana), Matthew McGrattan (Digirati) and Rob Sanderson (Yale University). The IIIF Community thanks them for their leadership, and the members of the group for their tireless work.
+
+### B. Change Log
+{: #change-log}
+
+| Date | Description |
+| ---------- | ----------------------- |
+| 2022-02-09 | Version 1.0 (Drop Dragon) |
+| 2022-01-31 | Version 0.9.1 (unnamed) |
+| 2021-06-21 | Version 0.9 (unnamed) |
+| 2020-11-22 | Version 0.3 (unnamed) |
+| 2019-02-04 | Version 0.2 (unnamed) |
+| 2018-10-31 | Version 0.1 (unnamed) |
+
+{% include links.md %}
diff --git a/source/image/1.1/index.html b/source/image/1.1/index.html
index 95de05280..72398da23 100644
--- a/source/image/1.1/index.html
+++ b/source/image/1.1/index.html
@@ -944,7 +944,7 @@
This API does not specify whether the image server will support authentication or what mechanism it might use. In the
case of "401 Unauthorized" HTTP error response, the content of the WWW-Authenticate header will depend on the
authentication mechanism supported by the server. If the server supports HTTP Basic or Digest authentication then the
- header should follow RFC2617, for example:
+ header should follow RFC2617, for example:
WWW-Authenticate: Basic realm="Images"
@@ -1002,7 +1002,7 @@
The URL syntax of this API relies upon slash (/) separators which MUST NOT be encoded. Clients MUST percent-encode
special characters (the to-encode set below: percent and gen-delims of
- RFC3986 except the colon) within the components
+ RFC3986 except the colon) within the components
of requests. For example, any slashes within the identifier part of the URL MUST be percent-encoded. Encoding is
necessary only for the identifier because other components will not include special characters.
diff --git a/source/model/shared-canvas/1.0/index.html b/source/model/shared-canvas/1.0/index.html
index 5d4f0233a..2a07e7c8d 100644
--- a/source/model/shared-canvas/1.0/index.html
+++ b/source/model/shared-canvas/1.0/index.html
@@ -58,7 +58,7 @@ Abstract
parts thereof,
via Open
Annotations and the Annotations are grouped and ordered
-in OAI-ORE
+in OAI-ORE
Aggregations.
diff --git a/source/presentation/4.0/index.md b/source/presentation/4.0/index.md
new file mode 100644
index 000000000..e9e67f486
--- /dev/null
+++ b/source/presentation/4.0/index.md
@@ -0,0 +1,2831 @@
+---
+title: "Presentation API 4.0"
+title_override: "IIIF Presentation API 4.0"
+id: presentation-api
+layout: spec
+cssversion: 3
+tags: [specifications, presentation-api]
+major: 4
+minor: 0
+patch: 0
+pre:
+redirect_from:
+ - /presentation/index.html
+ - /presentation/4/index.html
+editors:
+ - name: Michael Appleby
+ ORCID: https://orcid.org/0000-0002-1266-298X
+ institution: Yale University
+ - name: Tom Crane
+ ORCID: https://orcid.org/0000-0003-1881-243X
+ institution: Digirati
+ - name: Robert Sanderson
+ ORCID: https://orcid.org/0000-0003-4441-6852
+ institution: J. Paul Getty Trust
+ - name: Dawn Childress
+ ORCID: https://orcid.org/0000-0003-2602-2788
+ institution: UCLA
+ - name: Julie Winchester
+ ORCID: https://orcid.org/0000-0001-6578-764X
+ institution: Duke University
+ - name: Jeff Mixter
+ ORCID: https://orcid.org/0000-0002-8411-2952
+ institution: OCLC
+hero:
+ image: ''
+---
+
+
+
+# Status of this Document
+{:.no_toc}
+__This Version:__ {{ page.major }}.{{ page.minor }}.{{ page.patch }}{% if page.pre != 'final' %}-{{ page.pre }}{% endif %}
+
+__Latest Stable Version:__ [{{ site.data.apis.presentation.latest.major }}.{{ site.data.apis.presentation.latest.minor }}.{{ site.data.apis.presentation.latest.patch }}][prezi-stable-version]
+
+__Previous Version:__ [3.0][prezi30]
+
+**Editors:**
+
+{% include api/editors.md editors=page.editors %}
+
+{% include copyright.md %}
+
+----
+
+# Introduction
+
+The purpose of the IIIF Presentation API specification is to provide a [model](model) and JSON serialization format of that model.
+
+It provides a document format---the IIIF Manifest---for cultural heritage organizations (and anyone else) to present objects in a standardized, interoperable way. This allows compatible software such as viewers and annotation tools to load and present complex digital objects on the web from thousands of different providers.
+
+**If you have existing images, audio, video and models on the web, you can easily provide IIIF Manifests for them by publishing the appropriate JSON documents.**
+
+The IIIF Presentation API is concerned with enabling user experiences---providing enough information to present objects in compatible software, and leaving the meaning of the objects to external descriptive metadata standards.
+
+This document acts as an introduction to the specification through a set of typical (but non-exhaustive) use cases. The [Presentation API 4.0 Properties](model) document provides the formal specification of the model and terms used in this introduction.
+
+## IIIF Use cases
+
+1. **Artwork** - a Manifest that represents a painting, comprising a single image and accompanying display information.
+2. **Book** - a Manifest that represents a digitized bound volume made up many separate images in order. The IIIF model provides structural elements to indicate the chapters. The text of the book is made available in machine-readable form as Web Annotations.
+3. **Periodical** - a IIIF Collection that provides multiple child Collections and Manifests, representing the publication run of a newspaper over many years. The IIIF model provides structural elements to indicate individual articles and other elements.
+4. **45 Single** - a Manifest that represents the digitized audio from the two sides of a vinyl 7 inch record.
+5. **Movie** - a Manifest that represents the digitized video of a film. A transcript of the audio is provided as Web Annotations, and additional machine-readable files provide subtitles and captions.
+6. **Simple 3D Model** - a Manifest that publishes a single 3D model.
+7. **Complex Scene** - a Manifest that publishes a complex 3D scene comprising multiple models, lights and cameras.
+8. **Storytelling in 3D** - a Manifest that defines a sequence of states in a complex scene for the purposes of guiding a user through a particular experience.
+
+These use case were chosen as a broad sample to introduce IIIF concepts. Many more use cases are provided as recipes in the [IIIF Cookbook](link).
+
+
+> TODO Consider diagrams
+
+
+# Foundations
+
+This section is what you need to know to make sense of the examples that follow it.
+
+
+ 
+
+
+
+## Manifests
+
+A Manifest is the primary unit of distribution of IIIF. Each Manifest usually describes how to present an object, such as a book, statue, music album or 3 dimensional scene. It is a JSON document that carries information needed for the client to present content to the user, such as a title and other descriptive information. The scope of what constitutes an object, and thus its Manifest, is up to the publisher of that Manifest. The Manifest contains sufficient information for the client to initialize itself and begin to display something quickly to the user.
+
+The Manifest's `items` property is an ordered list of _Containers_ of _Content Resources_ (images, 3D models, audio, etc). Client software loads the Manifest and presents each Container's Content Resources. The client software also presents user interface controls to navigate the list of Content Containers.
+
+Manifests have descriptive, technical and linking properties. The required properties of Manifests are `id`, `type`, `items` and `label`. Other commonly used properties include `summary`, `metadata`, `rights`, `thumbnail`, `homepage` and `provider`.
+
+(👀) [Model Documentation](model/#manifest)
+
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json",
+ "type": "Manifest",
+ "label": {
+ "en": [ "Single Image Example" ]
+ },
+ "items": [
+ // A list of Containers
+ ]
+}
+```
+
+
+
+## Containers
+
+A Container is a frame of reference that allows the relative positioning of Content Resources, a concept borrowed from standards like PDF and HTML, or applications like Photoshop and PowerPoint, where an initially blank display surface has images, video, text and other content "painted" on to it. The frame is defined by a set of dimensions, with different types of Container having different dimensions. This specification defines three sub-classes of Container: Timeline (which only has a duration), Canvas (which has bounded height and width, and may have a duration), and Scene (which has infinite height, width and depth, and may have a duration).
+
+The required properties of all Containers are `id`, and `type`. Most Containers also have the `items` and `label` properties. Further properties are required for the different types of Container.
+
+The defined Container types are:
+
+### Timeline
+
+A Container that represents a bounded temporal range, without any spatial coordinates. It is typically used for audio-only content.
+
+Timelines have an additional required property of `duration`, which gives the extent of the Timeline as a floating point number of seconds.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/timeline",
+ "type": "Timeline",
+ "duration": 32.76,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/page/p1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/annotation/t1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/audio/clip.mp3",
+ "type": "Audio",
+ "format": "audio/mp3",
+ "duration": 32.76
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/timeline"
+ }
+ ]
+ }
+ ]
+}
+```
+
+### Canvas
+
+A Container that represents a bounded, two-dimensional space, optionally with a bounded temporal range. Canvases are typically used for Image and Video content.
+
+Canvases have two additional required properties: `height` and `width`, which give the spatial extent as integers. Canvases may also have the `duration` property in the same manner as Timelines.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas",
+ "type": "Canvas",
+ "width": 12000,
+ "height": 9000,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/page/p2",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/annotation/c1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/image/painting.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "width": 4000,
+ "height": 3000
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas"
+ }
+ ]
+ }
+ ]
+}
+```
+
+### Scene
+
+A Container that represents a boundless three-dimensional space, optionally with a bounded temporal range. Scenes are typically used for rendering 3D models, and can additionally have Cameras and Lights.
+
+Scenes may also have the `duration` property in the same manner as Timelines.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/scene",
+ "type": "Scene",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/page/p3",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/annotation/s1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/models/astronaut.glb",
+ "type": "Model",
+ "format": "model/gltf-binary"
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/scene"
+ }
+ ]
+ }
+ ]
+}
+```
+
+Scenes can have time-based and image content in them as well as 3D content. See model for how to do this.
+
+[👀 Model Documentation](model/#containers)
+
+
+## Annotations
+
+
+IIIF uses the concept of _Annotation_ to link resources together from around the web. This specification uses a World Wide Web Consortium (W3C) standard for this called the [Web Annotation Data Model][org-web-anno]. This is a structured linking mechanism useful for making comments about Content Resources, but IIIF's primary use of it is to associate the images, audio and other Content Resources with their Containers for presentation.
+
+In each of the three Containers above, an **Annotation** links the Container to a Content Resource. The Content Resource in the `body` property is _painted_ into the Container by an Annotation whose `target` property is the `id` of the Container. In all three simple cases here the `target` property is the `id` of the Container with no further qualification.
+
+Different uses of Annotation are distinguished through their `motivation` property. This specification defines a value for `motivation` called `painting` for associating Content Resources with Containers, which this specification calls a Painting Annotation. The verb "paint" is also used to refer to the associating of a Content Resource with a Container by a Painting Annotation. This is from the notion of painting onto a canvas, a metaphor borrowed from art and used for image-based digital applications, and expanded by IIIF into "painting" any Content Resource into a Container of any number of dimensions.
+
+The same linking mechanism is also used in IIIF with other motivations for transcriptions, commentary, tags and other content. This provides a single, unified method for aligning content, and provides a standards-based framework for referencing parts of resources. As Annotations can be added later, it promotes a distributed system in which further content such as commentary can be aligned with the objects published on the web.
+
+Annotations are grouped within the `items` property of an Annotation Page, and the `items` property of the Container is a list of Annotation Pages. This allows consistent grouping of Annotations when required.
+
+(👀) [Model Documentation](model/#Annotations)
+
+
+## Content Resources
+
+Content Resources are external web resources, including images, video, audio, 3D models, data, web pages or any other format. Typically these are the resources that will be painted into a Container using a Painting Annotation.
+
+In addition to the required properties `id` and `type`, other commonly used properties include `format`, and `width`, `height` and `duration` as appropriate to the Content Resource format. The values of these properties are often the source of the equivalent Container properties.
+
+(👀) [Model Documentation](model/#ContentResources)
+
+### Containers as Content Resources
+
+Containers may also be treated as Content Resources and painted into other Containers. This allows composition of content, such as painting a Canvas bearing a Video into a Scene, or painting a 3D model along with its associated Lights into an encompassing Scene. This capability is described further in [nesting](#nesting).
+
+### Referencing Parts of Resources
+
+A common scenario is to refer to only part of a resource, either a Container or a Content Resource. There are two primary methods for achieving this: adding a fragment to the end of the URI for the resource, or creating a Specific Resource that describes the method for selecting the desired part.
+
+Parts of resources on the Web can be identified using URIs with a fragment component that both describes how to select the part from the resource, and, as a URI, also identifies it. In HTML this is frequently used to refer to part of the web page, called an anchor. The URI with the fragment can be used in place of the URI without the fragment in order to refer to this part.
+
+There are different types of fragment based on the format of the resource. The most commonly used type in IIIF is the W3C's Media Fragments specification, as it can define a temporal and 2D spatial region.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/comments/c1",
+ "type": "Annotation",
+ "motivation": [ "commenting" ],
+ "body": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/bodies/koto-body",
+ "type": "TextualBody",
+ "value": "Koto with a cover being carried",
+ "language": "en",
+ "format": "text/plain"
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas#xywh=6050,3220,925,1250"
+}
+```
+
+Here the Canvas `id` from the earlier example is still the `target` of an Annotation, but it has been qualified to a specific region of that Canvas by a URI fragment `#xywh=6050,3220,925,1250`. Note that the x, y, w, and h are in the Canvas coordinate space, not the image pixel dimensions space. This annotation has no knowledge of or dependency on the particular image we painted onto the Canvas; we could replace that image with one of a different, higher resolution without affecting this annotation or the region of the Canvas it targets.
+
+
+### Specific Resource
+
+URIs with fragments are insufficient for complex referencing, like circular regions or arbitrary text spans, and do not support other useful features such as describing styling or transformation. The Web Annotation Data Model introduces a class called `SpecificResource` that represents the resource in a specific context or role, which IIIF uses to describe these more complex requirements.
+
+Several different classes of Selector are used in IIIF, including an alternative implementation of the fragment pattern called `FragmentSelector`. The fragment is given in the `value` property of the `FragmentSelector`, and the resource it should be applied to is given in `source`.
+
+The required properties of Specific Resources are `id`, `type`, and `source`. Other commonly used properties include `selector`, `transform`, and `scope`.
+
+The fragment example above can be expressed using a Specific Resource:
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/comments/c1",
+ "type": "Annotation",
+ "motivation": [ "commenting" ],
+ "body": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/bodies/koto-body",
+ "type": "TextualBody",
+ "value": "Koto with a cover being carried",
+ "language": "en",
+ "format": "text/plain"
+ },
+ "target": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/resources/koto-sr",
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas",
+ "type": "Canvas"
+ },
+ "selector": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/selectors/koto-selector",
+ "type": "FragmentSelector",
+ "value": "xywh=6050,3220,925,1250"
+ }
+ }
+}
+```
+
+## Navigational Resources
+
+Navigational resources provide structure for IIIF resources that allow viewing clients to guide users through IIIF content and collections. They define how resources are organized for discovery and interaction across multiple resources, like Collections, or within a resource, like Ranges, that help clients construct meaningful navigational interfaces, such as hierarchies, groupings, lists, or tables of contents.
+
+### Collection
+
+IIIF Collections are ordered lists of Manifests and Collections. Collections allow these resources to be grouped in a hierarchical structure for navigation and other purposes.
+
+Collections may include both other Collections and Manifests, forming a tree-structured hierarchy that expresses relationships among IIIF resources. This organization can represent archival or curatorial structures, logical groupings such as volumes or series, or dynamically generated sets of related items. As such, they enable clients to load predefined sets of resources at initialization, render dynamically generated sets such as search results, visualize lists or hierarchies of related content, and facilitate navigation through structured aggregations of Manifests and Collections.
+
+```json
+{
+ "id": "https://iiif.example.org/collection/top",
+ "type": "Collection",
+ "label": { "en": ["Top-level Collection"] },
+ "items": [
+ {
+ "id": "https://iiif.example.org/collection/sub1",
+ "type": "Collection",
+ "label": { "en": ["Sub-Collection 1"] }
+ },
+ {
+ "id": "https://iiif.example.org/manifest/1",
+ "type": "Manifest",
+ "label": { "en": ["Manifest 1"] }
+ },
+ {
+ "id": "https://iiif.example.org/manifest/2",
+ "type": "Manifest",
+ "label": { "en": ["Manifest 2"] }
+ }
+ ]
+}
+```
+
+:eyes:
+
+### Range
+
+IIIF Ranges are used to represent structure _WITHIN_ a Manifest beyond the default order of the Containers in the `items` property. Ranges define meaningful divisions or sequences---such as chapters in a book, sections of a newspaper, or movements of a musical work---that allow clients to present hierarchical or linear navigation interfaces that enable the user to quickly move through the object's content..
+
+Ranges may include Containers, parts of Containers via Specific Resources or fragment URIs, or other Ranges, creating tree-like structures that reflect the logical or intellectual organization of the resource, such as a table of contents or an alternative ordering of items.
+
+```json
+{
+ "id": "https://iiif.example.org/manifest/1/range/toc",
+ "type": "Range",
+ "label": { "en": ["Table of Contents"] },
+ "items": [
+ {
+ "id": "https://iiif.example.org/manifest/1/canvas/1",
+ "type": "Canvas",
+ "label": { "en": ["Page 1"] }
+ },
+ {
+ "id": "https://iiif.example.org/manifest/1/canvas/2",
+ "type": "Canvas",
+ "label": { "en": ["Page 2"] }
+ },
+ {
+ "id": "https://iiif.example.org/manifest/1/range/chapter2",
+ "type": "Range",
+ "label": { "en": ["Chapter 2"] },
+ "items": [
+ {
+ "id": "https://iiif.example.org/manifest/1/canvas/3",
+ "type": "Canvas",
+ "label": { "en": ["Page 3"] }
+ }
+ ]
+ }
+ ]
+}
+```
+
+:eyes:
+
+
+
+# Image Content
+
+## Use Case 1: Artwork with deep zoom
+
+This example is a Manifest with one Canvas, representing an artwork. The content resource, a JPEG image of the artwork, is associated with the Canvas via a Painting Annotation.
+
+The unit integer coordinates of the Canvas (12000 x 9000) are not the same as the pixel dimensions of the JPEG image (4000 x 3000), but they are proportional---the Canvas has a 4:3 landscape aspect ratio, and so does the JPEG image.The `target` property of the Annotation is the Canvas `id`, unqualified by any particular region; this is taken to mean the content (the image) should fill the Canvas completely. As the Canvas and the image are the same aspect ratio, no distortion will occur. This approach allows the current image to be replaced by a higher resolution image in future, on the same Canvas. The Canvas dimensions establish a coordinate system for _painting annotations_ and other kinds of annotation that link content with the Canvas; they are not pixels of images.
+
+The example demonstrates the use of the common descriptive properties `label` for the title of the artwork, `metadata` for additional information to display to the user, `summary` for a brief description of the artwork, `rights` to assert a rights statement or license from a controlled vocabulary, `homepage` to link to the artwork's specific web page, `thumbnail` to provide a small image to stand for the Manifest, `provider` to give information about the publisher of the Manifest, and finally, `service` to specify a IIIF Image API service that provides features such as deep zooming, derivative generation, image fragment referencing, rotation, and more.
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json",
+ "type": "Manifest",
+ "label": {
+ "en": [ "Use case 1: Artwork" ]
+ },
+ "metadata": [
+ {
+ "label": { "en": [ "Artist" ] },
+ "value": { "en": [ "Anne Artist" ] }
+ },
+ {
+ "label": { "en": [ "Date" ] },
+ "value": { "en": [ "c. 1800" ] }
+ }
+ ],
+ "summary": { "en": [ "A longer piece of text to be shown when the metadata is not." ] },
+ "rights": "http://rightsstatements.org/vocab/NoC-NC/1.0/",
+ "homepage": [
+ {
+ "id": "https://example.org/works/artwork37",
+ "type": "Text",
+ "format": "text/html",
+ "label": { "en": [ "Homepage for artwork37" ] }
+ }
+ ],
+ "thumbnail": [
+ {
+ "id": "https://example.org/works/artwork37/thumbnail.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "width": 100,
+ "height": 150
+ }
+ ],
+ "provider":
+ [
+ {
+ "id": "https://example.org/about",
+ "type": "Agent",
+ "label": { "en": [ "Example Organization" ] },
+ "homepage": [
+ {
+ "id": "https://example.org/",
+ "type": "Text",
+ "label": { "en": [ "Example Organization Homepage" ] },
+ "format": "text/html"
+ }
+ ],
+ "logo": [
+ {
+ "id": "https://example.org/images/logo.png",
+ "type": "Image",
+ "format": "image/png",
+ "height": 100,
+ "width": 120
+ }
+ ]
+ }
+ ],
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas",
+ "type": "Canvas",
+ "width": 12000,
+ "height": 9000,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/page/p2",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/annotation/c1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example/image/painting/full/max/0/default.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "width": 4000,
+ "height": 3000,
+ "service": [
+ {
+ "id": "https://iiif.io/api/presentation/example/image/painting",
+ "profile": "level1",
+ "type": "ImageService3",
+ // etc
+ }
+ ]
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/canvas"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+
+>
+**Key Points**
+* All IIIF documents begin with the `@context` key, which maps the JSON structure into a linked data representation. The value identifies the version of the specification in use. [👀 Model Documentation](model/#json-ld-contexts-and-extensions)
+* Every JSON object that has a `type` property also has an `id` property and vice versa.
+* Text elements intended for display to the user are conveyed by _Language Maps_, JSON objects in which the keys are language codes and the values are lists of one or more strings in that language. [👀 Model Documentation](model/#language-of-property-values)
+* The Painting Annotation is a member of the `items` property of an Annotation Page. While in this case there is only one Annotation Page and one Annotation, the mechanism is needed for consistency when there are multiple Annotation Pages, and it allows for Annotation Pages in general to be separate resources on the web.
+* The `metadata` label and value pairs are for display to the user rather than for machines to interpret.
+* The `rights` property is always a single string value which is a URI.
+* Any resource can have a `provider` property which a client can display to the user. This typically tells the user who the publisher is and how they might be contacted. The value of this property is an [Agent](model/#agent).
+* The `service` property specifies a software application that a client might interact with to gain additional information or functionality, in this case, the IIIF Image API. Images in IIIF do not require an Image Service---we have included one here as an example, but do not include a service in the following image examples for brevity.
+{: .note}
+
+!!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas), [AnnotationPage](#model/AnnotationPage), [Annotation](#model/Annotation), [Agent](#model/Agent)
+Properties: [id](#model/id), [type](#model/type), [label](#model/label), [metadata](#modle/metadata), [summary](#modle/summary), [rights](#model/rights), [homepage](#model/homepage), [thumbnail](#model/thumbnail), [provider](#model/provider), and [service](#model/Service)
+{: .note}
+
+
+## Use Case 2: Book
+
+This example is a Manifest with multiple Canvases, each of which represents a page of a book. It demonstrates the use of the `behavior` property to indicate to a client that the object is _paged_---this helps a client generate the correct user experience. The `viewingDirection` property indicates that the book is read left-to-right. In this case, the property is redundant as `left-to-right` is the default value. The Manifest has a `rendering` property linking to a PDF representation; typically a client would offer this as a download or "view as" option. The `start` property is used to tell a client to initialize the view on a particular Canvas, useful if the digitized work contains a large amount of irrelevant front matter or blank pages. The `requiredStatement` is a message that a client MUST show to the user when presenting the Manifest.
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book.json",
+ "type": "Manifest",
+ "label": { "en": [ "Use case 2: Book" ] },
+ "behavior": [ "paged" ],
+ "viewingDirection": "left-to-right",
+ "rendering": [
+ {
+ "id": "https://example.org/pdfs/book.pdf",
+ "type": "Text",
+ "label": { "en": [ "PDF version" ] },
+ "format": "application/pdf"
+ }
+ ],
+ "start": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c2",
+ "type": "Canvas"
+ },
+ "requiredStatement": {
+ "label": { "en": [ "Attribution" ] },
+ "value": { "en": [ "Provided courtesy of Example Institution" ] }
+ },
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c1",
+ "type": "Canvas",
+ "label": { "en": [ "Blank page" ] },
+ "height": 4613,
+ "width": 3204,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/page/p1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/annotation/a1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/image/page1.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 4613,
+ "width": 3204,
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c1"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c2",
+ "type": "Canvas",
+ "label": { "en": [ "Frontispiece" ] },
+ "height": 4613,
+ "width": 3204,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/page/p2",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/annotation/a2",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/image/page2.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 4613,
+ "width": 3204,
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c2"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c3",
+ "type": "Canvas",
+ "label": { "en": [ "Title Page" ] },
+ "height": 4613,
+ "width": 3204,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/page/p3",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-book/annotation/a3",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://iiif.io/api/presentation/example-content-resources/image/page3.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 4613,
+ "width": 3204,
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-book/canvas/c3"
+ }
+ ]
+ }
+ ]
+ },
+ // Additional Canvases
+ ]
+}
+```
+
+>
+**Key Points**
+* Canvas labels are not required, but are recommended when a Manifest has more than one Canvas in order to provide visual labels for each Canvas for navigation within the IIIF client UI.
+{: .note}
+
+!!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas)
+Properties: [behavior](#model/behavior), [viewingDirection](#model/viewingDirection), [start](#model/start), [rendering](#model/rendering), [requiredStatement](#model/requiredStatement)
+{: .note}
+
+
+
+## Use Case 3: Periodical
+
+This example demonstrates the use of IIIF Collections to group Manifests into a hierarchy. In this case, there is a Collection for a run of the _The Tombstone Epitaph_, published from 1880 to 1920. This contains 41 child Collections each representing a year's worth of issues. The parent Collection and each of its child Collections use the `behavior` "multi-part" to signal that the Collections and their Manifests are part of a logical set. Each of the year Collections has one Manifest for each issue of the newspaper.
+
+The top-level Collection has a `navPlace` property that could be used on a "Newspapers of America" map to allow users to view newspapers by location. Each Manifest has a `navDate` property that could be used to plot the issues on a timeline or calendar-style user interface. Within each Manifest, the `structures` property provides Ranges which are used to identify individual sections of the Newspaper, and individual stories within those sections, which may be spread across multiple columns and pages. Each story's Range includes the `supplementary` property to link to an Annotation Collection that provides the text of the story.
+
+IIIF Collection with `behavior` "multi-part" that contains the individual "multi-part" Collections for each year/volume:
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/periodical/collection.json",
+ "type": "Collection",
+ "label": { "en": [ "The Tombstone Epitaph (1880-1920)" ] },
+ "behavior": [ "multi-part" ],
+ "navPlace": {
+ "id": "https://example.org/iiif/periodical/collection/place/1",
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "id": "https://example.org/iiif/periodical/collection/feature/1",
+ "type": "Feature",
+ "properties": {
+ "label": { "en": ["Tombstone, Cochise County, Arizona"] }
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [31.715940, −110.064827]
+ }
+ }
+ ]
+ },
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/v1.json",
+ "type": "Collection",
+ "label": { "en": [ "The Tombstone Epitaph, 1880" ] }
+ },
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/v2.json",
+ "type": "Collection",
+ "label": { "en": [ "The Tombstone Epitaph, 1881" ] }
+ },
+ // Additional multi-part collections for each year/volume
+ ]
+}
+```
+IIIF Collection with `behavior` "multi-part" for the second volume (1881), with individual Manifests for each issue:
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/periodical/multi-part-collection/v1.json",
+ "type": "Collection",
+ "label": { "en": [ "The Tombstone Epitaph, 1881" ] },
+ "behavior": [ "multi-part" ],
+ "items": [
+ // Previous issues
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/issue1.json",
+ "type": "Manifest",
+ "label": { "en": [ "October 27, 1881" ] }
+ },
+ // Subsequent issues
+ ]
+}
+```
+
+Manifest for the October 27, 1881 issue, with Ranges for table of contents:
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/periodical/multi-part-collection/issue1.json",
+ "type": "Manifest",
+ "label": { "en": [ "The Tombstone Epitaph, October 27, 1881" ] },
+ "behavior": [ "paged" ],
+ "navDate": "1881-10-27T00:00:00+00:00",
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/canvas/c1",
+ "type": "Canvas",
+ "label": { "en": [ "Page 1" ] },
+ "height": 4613,
+ "width": 3204,
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/page/p1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/annotation/a1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://example.org/image/page1.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 4613,
+ "width": 3204,
+ },
+ "target": "https://example.org/iiif/periodical/multi-part-collection/canvas/c1"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/canvas/c2",
+ "type": "Canvas",
+ "label": { "en": [ "Page 2" ] },
+ "height": 4613,
+ "width": 3204,
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/page/p2",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/annotation/a2",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://example.org/image/page2.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 4613,
+ "width": 3204,
+ },
+ "target": "https://example.org/iiif/periodical/multi-part-collection/canvas/c2"
+ }
+ ]
+ }
+ ]
+ },
+ // Additional Canvases
+ ],
+ "structures": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/range/r0",
+ "type": "Range",
+ "label": { "en": [ "October 27, 1881" ] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/range/r1",
+ "type": "Range",
+ "label": { "en": [ "Yesterday's Tragedy: Three Men Hurled Into Eternity In the Duration of a Moment" ] },
+ "supplementary": { "id": "https://example.org/iiif/full-text-anno-collection", "type": "AnnotationCollection" },
+ "items": [
+ {
+ "id": "https://example.org/iiif/periodical/multi-part-collection/canvas/c1",
+ "type": "Canvas"
+ },
+ // Additional contents
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+*
+{: .note}
+
+__Definitions__
+Classes: [Collection](#model/Collection), [Range](#model/Range), [AnnotationCollection](#model/AnnotationCollection)
+Properties: [behavior](#model/behavior), [navPlace](#model/navPlace), [navDate](#model/navDate), [structure](#model/structures), [supplementary](#model/supplementary)
+{: .note}
+
+thumbnail-nav
+sequence
+
+
+
+# Audio and Video
+
+## Use Case 4: A 45 single with 2 tracks
+
+This example is a Manifest with two Timelines, each of which represent a temporal extent during which a song is played. As in most cases, the Timeline `duration` is the same length as that of Content Resource painted into it. This example is a recording digitized from a 45 RPM 7 inch single. It demonstrates the use of `format` for the audio files' content type, `language` (One song is in English and one is in German), `behavior` with value "auto-advance" that tells a client to automatically advance to the second Timeline after playing the first, `annotations` that link to Annotation Pages of annotations with the motivation `supplementing` that provide the lyrics (one example is given afterwards) - and an `accompanyingContainer` that carries a picture of the single's cover that is shown while the songs are playing.
+
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio.json",
+ "type": "Manifest",
+ "label": { "en": [ "Use case 3: 45 single with 2 tracks" ] },
+ "behavior": [ "auto-advance" ],
+ "accompanyingContainer": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/accompany/c1",
+ "type": "Canvas",
+ "label": { "en": [ "Photo of cover sleeve" ] },
+ "height": 900,
+ "width": 900,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/accompany/c1/page",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/accompany/c1/image",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://example.org/presentation/example-content-resources/image/cover.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 900,
+ "width": 900
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-audio/accompany/ac1"
+ }
+ ]
+ }
+ ]
+ },
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/timeline/t1",
+ "type": "Timeline",
+ "label": { "en": [ "Side A: 99 Luftballons" ] },
+ "duration": 231,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/track/tr1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/annotation/a1",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://example.org/presentation/example-content-resources/audio/track1.mp4",
+ "type": "Sound",
+ "format": "audio/mp4",
+ "duration": 231,
+ "language": [ "de" ],
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-audio/timeline/t1"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/timeline/t2",
+ "type": "Timeline",
+ "label": { "en": [ "Side B: 99 Red Balloons" ] },
+ "duration": 230.5,
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/track/tr2",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-audio/annotation/a2",
+ "type": "Annotation",
+ "motivation": [ "painting" ],
+ "body": {
+ "id": "https://example.org/presentation/example-content-resources/audio/track2.mp4",
+ "type": "Sound",
+ "format": "audio/mp4",
+ "duration": 230.5,
+ "language": [ "en" ],
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-audio/timeline/t2"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/external-anno.json",
+ "type": "AnnotationPage",
+ }
+ ]
+}
+```
+
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/3/context.json",
+ "id": "https://example.org/iiif/presentation/examples/external-anno.json",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/external-anno/a1",
+ "type": "Annotation",
+ "motivation": [ "supplementing" ],
+ "body": {
+ "id": "https://example.org/presentation/example-content-resources/lyrics1.txt",
+ "type": "TextualBody",
+ "language": "de",
+ "format": "text/plain",
+ "value": "Hast du etwas Zeit für mich?"
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-audio/timeline/t1#t=3.5,6.8"
+ }
+ ],
+ // (annotations for the rest of the song lines)
+}
+```
+
+>
+**Key Points**
+* t vs. instant / verbose vs. append to URI???
+{: .note}
+
+!!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Timeline](#model/Timeline),[TextualBody](#model/TextualBody)
+Properties: [duration](#model/duration), [format](#model/format), [language](#model/language), [behavior](#model/behavior), [annotations](#model/annotations), [accompanyingContainer](#model/accompanyingContainer)
+{: .note}
+
+
+## Use Case 5: Movie with subtitles
+
+This example is a Manifest with one Canvas that represents the temporal extent of the movie (the Canvas `duration`) and its aspect ratio (given by the `width` and `height` of the Canvas). The example demonstrates the use of a `Choice` annotation body to give two alternative versions of the movie, indicated by their `label` and `fileSize` properties as well as `height` and `width`. Subtitles are provided by an annotation that links to a VTT file. The motivation of this annotation is `supplementing` and the `provides` property of this annotation indicates what accessibility feature it provides, in this case the term `subtitles`. The `timeMode` property in this case is redundant as `trim` is the default value. The Canvas has a `placeholderContainer` that provides a poster image to show in place of the video file before the user initiates playback.
+
+```json
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie.json",
+ "type": "Manifest",
+ "label": { "en": [ "Use Case 4: Movie with Subtitles" ] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/canvas",
+ "type": "Canvas",
+ "height": 1080,
+ "width": 1440,
+ "duration": 3600,
+ "timeMode": "trim",
+ "placeholderContainer": {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/placeholder",
+ "type": "Canvas",
+ "height": 320,
+ "width": 400,
+ "items": [
+ {
+ "id": "https://example.org/image/placeholder/annopage",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/placeholder/image",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "id": "https://example.org/image/placeholder.png",
+ "type": "Image",
+ "format": "image/png",
+ "height": 320,
+ "width": 400,
+ },
+ "target": "https://iiif.io/api/cookbook/recipe/0013-placeholderCanvas/canvas/donizetti/placeholder"
+ }
+ ]
+ }
+ ]
+ },
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/annopage1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/anno1",
+ "type": "Annotation",
+ "motivation": "painting",
+ "body": {
+ "type": "Choice",
+ "items": [
+ {
+ "id": "https://example.org/video/movie-low.mp4",
+ "type": "Video",
+ "label": { "en": ["Low resolution (360 MB)" ]},
+ "height": 360,
+ "width": 480,
+ "duration": 3600,
+ "format": "video/mp4",
+ "fileSize": 360553219
+ },
+ {
+ "id": "https://example.org/video/movie-hi.mp4",
+ "type": "Video",
+ "label": { "en": ["High resolution (1.3 GB)" ]},
+ "height": 1080,
+ "width": 1440,
+ "duration": 3600,
+ "format": "video/mp4",
+ "fileSize": 1345876231
+ }
+ ]
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-movie/canvas"
+ }
+ ]
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/subtitles",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/manifest-with-movie/subtitles/anno",
+ "type": "Annotation",
+ "motivation": "supplementing",
+ "body": {
+ "id": "https://example.org/text/subtitles.vtt",
+ "type": "Text",
+ "format": "text/vtt",
+ "provides": [ "subtitles" ],
+ "label": {
+ "en": [
+ "Subtitles in WebVTT format"
+ ]
+ },
+ "language": "en"
+ },
+ "target": "https://example.org/iiif/presentation/examples/manifest-with-movie/canvas"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+* The decision about which item in the `Choice` to play by default is client dependent. In the absence of any other decision process the client should play the first item. In this specific example, the user might make the decision after reading the `label`, or the client might make the decision based on the `fileSize` property and an assessment of the user's available bandwidth. However, the client may have no way of determining why the publisher has offered the choices, and should not prevent the user from making the choice. The cookbook demonstrates several uses of `Choice` for common image and AV use cases.
+* Slop - impl note - don't interpret **very** minor discrepancies between `duration` on the different Choices and the Container `duration` as an instruction to stretch or compress the audio/video stream to match the Container duration. No real way to quantify this, just _be sensible_.
+{: .note}
+
+
+!!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas), [Choice](#model/Choice)
+Properties: [fileSize](#model/fileSize), [format](#model/format), [provides](#model/provides), [timeMode](#model/timeMode), [behavior](#model/behavior), [placeholderContainer](#model/placeholderContainer)
+{: .note}
+
+# 3D
+
+3D Content Resources are painted into Scenes.
+
+Scenes have infinite height (y axis), width (x axis) and depth (z axis), where 0 on each axis (the origin of the coordinate system) is treated as the center of the scene's space.
+
+The positive y axis points upwards, the positive x axis points to the right, and the positive z axis points forwards (a [right-handed cartesian coordinate system](https://en.wikipedia.org/wiki/Right-hand_rule)).
+
+
+
+(Image: Wikipedia)
+
+
+## 3D Supporting Resources
+
+
+Constructs from the domain of 3D graphics are expressed in IIIF as Resources. They are associated with Scenes via Painting Annotations in the same manner as Content Resources. They aid in or enhance the rendering of Content Resources, especially in Scenes.
+
+### Cameras
+
+A Camera provides a view of a region of the Scene's space from a particular position within the Scene; the client constructs a viewport into the Scene and uses the view of one or more Cameras to render that region. The size and aspect ratio of the viewport is client and device dependent.
+
+There are two types of Camera, `PerspectiveCamera` and `OrthographicCamera`. The first Camera defined and not [hidden](model#hidden-value) in a Scene is the default Camera used to display Scene contents. If the Scene does not have any Cameras defined within it, then the client provides a default Camera. The type, properties and position of this default camera are client-dependent.
+
+
+### Lights
+
+There are four types of Light: AmbientLight, DirectionalLight, PointLight and SpotLight. They have a `color` and an `intensity`. SpotLight has an additional property of `angle` that determines the spread of its light cone.
+
+If the Scene has no Lights, then the client provides its own lighting as it sees fit.
+
+
+### Audio Emitters
+
+There are three types of Audio emitter: AmbientAudio, PointAudio and SpotAudio. They have a `source` (an audio Content Resource) and a `volume`.
+
+### Transforms
+
+When painting resources into Scenes, it is often necessary to resize, rotate or move them relative to the coordinate space of the Scene. These operations are specified using three Transforms: ScaleTransform, RotateTransform and TranslateTransform. Each Transform has three properties, `x`, `y` and `z` which determine how the Transform affects that axis in the local coordinate space.
+
+Transforms are added to a SpecificResource using the `transform` property, and there may be more than one applied when adding a model to a Scene. Different orders of the same set of transforms can have different results, so attention must be paid when creating the array and when processing it.
+
+
+## Use Case 5: Simple 3D Model
+
+This example is a Manifest with a single Scene, with a single model of a space suit painted at the Scene's origin.
+
+> PNG of Scene
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/3d/model_origin.json",
+ "type": "Manifest",
+ "label": { "en": ["Single Model"] },
+ "summary": { "en": ["Viewer should render the model at the scene origin, and then viewer should add default lighting and camera"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "label": { "en": ["A Scene"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/astronaut/astronaut.glb",
+ "type": "Model",
+ "format": "model/gltf-binary"
+ },
+ "target": "https://example.org/iiif/scene1/page/p1/1"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+* As this Scene only has one resource in it (the model), the client must provide lighting and a default camera.
+* In this simplest use case, the Painting Annotation targets the whole Scene rather than a specific point. The client places the model's origin at the Scene's origin. This is in contrast to the _bounded_ Containers `Canvas` and `Timeline`, where the painted resource fills the Container completely.
+{: .note}
+
+
+## Use Case 5a: Simple 3D Model in Configured Scene
+
+This example adds a Light and a Camera to the previous example, and places the model at a specific point rather than at the default origin position.
+
+Annotations may use a type of Selector called a `PointSelector` to align the Annotation to a point within the Scene that is not the Scene's origin. PointSelectors have three spatial properties, `x`, `y` and `z` which give the value on that axis. They also have a temporal property `instant` which can be used if the Scene has a duration, which gives the temporal point in seconds from the start of the duration, the use of which is defined in the [section on Scenes with Durations]().
+
+The Light is green and has a position, but has its default orientation of looking along the negative-y axis as no rotation has been specified. The Camera has a position and is pointing at the model's origin via the `lookAt` property. The Camera has a `fieldOfView` of 50. The `near` and `far` properties are included to ensure the model falls within the camera's range (although unnecessary in a simple Scene like this). The Scene has a background color.
+
+
+
+
+```jsonc
+ {
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/3d/model_origin.json",
+ "type": "Manifest",
+ "label": { "en": ["Single Model with light and Camera"] },
+ "summary": { "en": ["Viewer should render the model at (-1,0,1), add the light, and base the viewport on the provided camera"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "label": { "en": ["A Scene"] },
+ "backgroundColor": "#FF00FE",
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/astronaut/astronaut.glb",
+ "type": "Model",
+ "format": "model/gltf-binary"
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": -1.0,
+ "y": 1.0,
+ "z": 1.0
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno2",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://example.org/iiif/3d/cameras/1",
+ "type": "PerspectiveCamera",
+ "label": {"en": ["Perspective Camera 1"]},
+ "lookAt": {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation"
+ },
+ "near": 1,
+ "far": 100,
+ "fieldOfView": 50
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 0.0,
+ "y": 6.0,
+ "z": 10.0
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno2",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://example.org/iiif/3d/lights/1",
+ "type": "SpotLight",
+ "label": {"en": ["Spot Light 1"]},
+ "angle": 90.0,
+ "color": "#A0FFA0"
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ },
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 0.0,
+ "y": 3.0,
+ "z": 1.0
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+* This example uses some of the Scene-Specific resources introduced in the next section.
+* A Point Selector explicitly places the model in the Scene via the Painting Annotation's `target` property. In the previous example, there was an implicit Point Selector placing the model at (0,0,0) because no explicit Point Selector was provided.
+* The provided Light should replace any default lighting the client might have.
+{: .note}
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [Model](#model/Model), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [PerspectiveCamera](#model/PerspectiveCamera), [SpotLight](#model/SpotLight)
+Properties: [backgroundColor](#model/backgroundColor), [lookAt](#model/lookAt), [near](#model/near), [far](#model/far), [feildOfView](#model/fieldOfView), [angle](#model/angle), [color](#model/color)
+{: .note}
+
+## Use Case 6: Complex Scene
+
+This example is a Manifest with a single Scene with multiple models painted into the Scene at specific positions with transforms applied. It represents a collection of chess game pieces with multiple pawns and a single queen. The example demonstrates painting multiple models into a Scene, including one Content Resource being painted into a Scene multiple times. Transforms and Point Selectors are used to establish position and scale for Annotations. Some external web resources referenced as Content Resources may include elements such as lights or audio that are undesirable within a Manifest, and the `exclude` property is used to prevent these from being rendered. The property `interactionMode` is used to guide clients in how to best guide or limit user interaction with rendered content.
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/3d/model_origin.json",
+ "type": "Manifest",
+ "label": { "en": ["Use Case 6: Complex Scene"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "label": { "en": ["Chess Game Pieces"] },
+ "interactionMode": ["hemisphere-orbit"],
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/chess/pawn.glb",
+ "label": {"en": ["Pawn 1"]},
+ "type": "Model",
+ "format": "model/gltf-binary"
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ },
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 1.0,
+ "y": 0.0,
+ "z": 0.0
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/chess/pawn.glb",
+ "label": {"en": ["Pawn 2 tipped over"]},
+ "type": "Model",
+ "format": "model/gltf-binary"
+ }
+ ],
+ "transform": [
+ {
+ "type": "RotateTransform",
+ "x": 0.0,
+ "y": 0.0,
+ "z": -90.0
+ },
+ {
+ "type": "Translate Transform",
+ "x": 0.0,
+ "y": 1.0,
+ "z": 0.0
+ }
+ ]
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ },
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 2.0,
+ "y": 0.0,
+ "z": 3.0
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "exclude": ["Audio", "Lights"],
+ "body": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/chess/queen.glb",
+ "label": {"en": ["Queen"]},
+ "type": "Model",
+ "format": "model/gltf-binary"
+ }
+ ],
+ "transform": [
+ {
+ "type": "ScaleTransform",
+ "x": 1.5,
+ "y": 1.5,
+ "z": 1.5
+ },
+ ]
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene"
+ },
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 1.0,
+ "y": 0.0,
+ "z": 2.0
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+* Each Annotation is painted into the Scene at a different point via Point Selectors.
+* The second Annotation represents a pawn game piece that is tipped over, and Transforms are used to achieve this. RotateTransform is used to tip the pawn over and TranslateTransform is used to align the bottom of the pawn with the coordinate origin's XY plane.
+* The third Annotation represents a queen game piece that is scaled to be larger than the pawns using ScaleTransform.
+* The `exclude` property instructs clients not to import or render any external audio or light content present in the Content Resource for the queen game piece.
+* The `interactionMode` property instructs clients that, if possible, user interactions relating to orbiting the scene should be restricted to a hemisphere.
+{: .note}
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [Model](#model/Model), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [RotateTransform](#model/RotateTransform), [TranslateTransform](#model/TranslateTransform), [ScaleTransform](#model/ScaleTransform)
+Properties: [exclude](#model/exclude), [interactionMode](#model/interactionMode)
+{: .note}
+
+
+
+## Use Case 7: Scene with Audio
+
+This example is a Manifest with a single Scene with a duration. Multiple Audio Emitter Annotations are painted into the Scene, with positional emitters used to create a 3D audio experience. Some of the Audio Emitter Annotations are only painted into the Scene for a limited period of time, producing dynamic change in the sounds heard within the Scene. A commenting Annotation is also provided to highlight the instant in time when a change in sound occurs.
+
+A content resource may be annotated into a Scene for a period of time by use of a PointSelector that is temporally scoped by a [FragmentSelector](https://www.w3.org/TR/annotation-model/#fragment-selector). The FragmentSelector has a `value` property, the value of which follows the [media fragment syntax](https://www.w3.org/TR/media-frags/#naming-time) of `t=`. This annotation pattern uses the `refinedBy` property [defined by the W3C Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#refinement-of-selection). When using a URL fragment in place of a SpecificResource, the parameter `t` can be used to select the temporal region. Both patterns are used in this example.
+
+An Annotation may target a specific point in time using a PointSelector's `instant` property. The property's value must be a positive floating point number indicating a value in seconds that falls within the Scene's duration. In this example this is used for a comment Annotation.
+
+In this example, the audio content resources have durations that do not match the Scene's duration. The Annotation property [`timeMode` property](https://iiif.io/api/presentation/3.0/#timemode) is used to indicate the desired behavior when the duration of the content resource that is not equal to the temporal region targeted by the annotation.
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/3d/model_origin.json",
+ "type": "Manifest",
+ "label": { "en": ["Use Case 7: Scene with Audio"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "label": { "en": ["Positional Audio Symphony Hall Experience"] },
+ "duration": 60,
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://example.org/iiif/audio/1",
+ "type": "AmbientAudio",
+ "source": {
+ "id": "https://example.org/iiif/assets/symphony_hall_ambience.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ },
+ "volume": {
+ "id": "https://example.org/iiif/quantity/1",
+ "type": "Quantity",
+ "unit": "relative",
+ "quantityValue": 0.1
+ }
+ },
+ "target": "https://example.org/iiif/scene1"
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno2",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "timeMode": "trim",
+ "body": {
+ "id": "https://example.org/iiif/audio/2",
+ "type": "PointAudio",
+ "source": {
+ "id": "https://example.org/iiif/assets/orchestra_percussion_120s.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ },
+ "volume": {
+ "id": "https://example.org/iiif/quantity/2",
+ "type": "Quantity",
+ "unit": "relative",
+ "quantityValue": 0.2
+ }
+ },
+ "target": {
+ "id": "https://example.org/iiif/selectors/anno2",
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "id": "https://example.org/uuid/9fbd580b-895b-41b9-974a-1553329037f2",
+ "type": "PointSelector",
+ "x": -3.0,
+ "y": 0.0,
+ "z": -2.0,
+ "refinedBy": {
+ "id": "https://example.org/uuid/3d0d097b-2b37-4a15-b6a5-506e417d5115",
+ "type": "FragmentSelector",
+ "value": "t=0,30"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno3",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "timeMode": "loop",
+ "body": {
+ "id": "https://example.org/iiif/audio/3",
+ "type": "SpotAudio",
+ "source": {
+ "id": "https://example.org/iiif/assets/orchestra_tuba_10s.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ },
+ "angle": 45.0,
+ "volume": {
+ "id": "https://example.org/iiif/quantity/3",
+ "type": "Quantity",
+ "unit": "relative",
+ "quantityValue": 0.3
+ },
+ "lookAt": "https://example.org/iiif/scene1"
+ },
+ "target": "https://example.org/iiif/scene1#xyz=3,0,-2&t=30,60"
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/3d/commenting",
+ "type": "Annotation",
+ "motivation": ["commenting"],
+ "bodyValue": "This is the point when the percussion stops playing and the tuba begins playing.",
+ "target": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "instant": 30.0
+ }
+ ]
+ }
+ },
+ ],
+ }
+ ]
+}
+```
+
+>
+**Key Points**
+* The Scene has a duration of 60 seconds.
+* The Scene has three different Audio Emitter Annotations painted into the Scene---AmbientAudio, PointAudio, and SpotAudio. Each Audio Emitter uses the `volume` property to specify audio volume.
+* AmbientAudio targets the Scene via a reference to the Scene URI, which implicitly targets the Scene's entire duration.
+* PointAudio targets the Scene with a PointSelector to paint the Audio Emitter at a specific point in 3D space, and that PointSelector is temporally scoped by a FragmentSelector to target the first 30 seconds of the Scene duration.
+* SpotAudio targets the Scene via a URL fragment to demonstrate an alternate approach to target a point and range of time in the Scene. It uses the `lookAt` property to point the Audio Emitter cone toward the Scene origin.
+* The content resources for PointAudio and SpotAudio use the property `timeMode` to specify different ways of handling mismatches between content resource audio length and Scene duration.
+* A commenting Annotation targets the Scene at the instant corresponding to 30 seconds of the Scene duration to highlight the point at which PointAudio stops playing and SpotAudio begins playing.
+* It is an error to select a temporal region of a Scene that does not have a `duration`, or to select a temporal region that is not within the Scene's temporal extent. A Canvas or Scene with a `duration` may not be annotated as a content resource into a Scene that does not itself have a `duration`.
+{: .note}
+
+__Definitions__
+Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [FragmentSelector](#model/FragmentSelector), [AmbientAudio](#model/AmbientAudio), [PointAudio](#model/PointAudio), [SpotAudio](#model/SpotAudio)
+Properties: [duration](#model/duration), [volume](#model/volume), [angle](#model/angle), [lookAt](#model/lookAt), [timeMode](#model/timeMode)
+{: .note}
+
+
+# Nesting (more about Containers as Content Resources)
+
+> How does this relate to model doc? What's normative and needs to be in model.md because it defines a Scene?
+
+A Canvas can be painted into a Scene as an Annotation, but the 2D nature of Canvases requires special consideration due to important differences between Canvases and Scenes. A Canvas describes a bounded 2D space with finite `height` and `width` measured in pixels with a pixel origin at the top-left corner of the Canvas, while Scenes describe a boundless 3D space with x, y, and z axes of arbitrary coordinate units and a coordinate origin at the center of the space. It is important to note that in many cases the pixel scale used by a Canvas or a 2D image content resource will not be in proportion to the desired 3D coordinate unit scale in a Scene.
+
+When a Canvas is painted as an Annotation targeting a Scene, the top-left corner of the Canvas (the pixel origin) is aligned with the 3D coordinate origin of the Scene. The top edge of the Canvas is aligned with (e.g., is colinear to) the positive x axis extending from the coordinate origin. The left edge of the Canvas is aligned with (e.g., is colinear to) the negative y axis extending from the coordinate origin. The Canvas is scaled to the Scene such that the pixel dimensions correspond to 3D coordinate units - a Canvas 200 pixels wide and 400 pixels high will extend 200 coordinate units across the x axis and 400 coordinate units across the y axis. Please note: direction terms "top", "bottom", "right", and "left" used in this section refer to the frame of reference of the Canvas itself, not the Scene into which the Canvas is painted.
+
+A Canvas in a Scene has a specific forward face and a backward face. By default, the forward face of a Canvas should point in the direction of the positive z axis. If the property `backgroundColor` is used, this color should be used for the backward face of the Canvas. Otherwise, a reverse view of the forward face of the Canvas should be visible on the backward face.
+
+
+ To Do: Add an image demonstrating default Canvas placement in Scene
+
+
+A `PointSelector` can be used to modify the point at which the Canvas will be painted, by establishing a new point to align with the top-left corner of the Canvas instead of the Scene coordinate origin. Transforms can also be used to modify Canvas rotation, scale, or translation.
+
+
+
+## Scene in Scene
+
+Scenes and other IIIF containers, such as Canvases, may also be embedded within Scenes, as described below in the nesting section [fwd-ref-to-nesting].
+
+```json
+{
+ "id": "https://example.org/iiif/scenes/1",
+ "type": "Scene",
+ "label": {"en": ["Chessboard"]},
+ "backgroundColor": "#000000",
+ "items": [
+ "Note: Annotations Live Here"
+ ]
+}
+```
+As with other resources, it may be appropriate to modify the initial scale, rotation, or translation of a content resource Scene prior to painting it within another Scene. Scenes associated with SpecificResources may be manipulated through the transforms described in Transforms(transforms_section).
+
+A simple example painting one Scene into another:
+
+```json
+{
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ },
+ "target": "https://example.org/iiif/scene2"
+}
+```
+
+When a Scene is nested into another Scene, the `backgroundColor` of the Scene to be nested should be ignored as it is non-sensible to import. All Annotations painted into the Scene to be nested will be painted into the Scene into which content is being nested, including Light or Camera resources. If the Scene to be nested has one or more Camera Annotations while the Scene into which content is being nested does not, the first Camera Annotation from the nested Scene will become the default Camera for the overall Scene.
+
+
+
+
+# Annotations
+
+In the examples so far, Annotations have been used to associate the images, audio and other Content Resources with their Containers for presentation. IIIF uses the same W3C standard for the perhaps more familiar _annotation_ concepts of commenting, tagging, describing and so on. Annotations can carry textual transcriptions or translations of the content, discussion about the content and any other linking between resources.
+
+Whereas annotations that associate content resources with Containers are included in the `items` property of the Container, all other types of Annotation are referenced from the `annotations` property. Containers, Manifests, Collections and Ranges can all have this property, linking to relevant annotations. As with the `items` property, annotations are grouped into one or more AnnotationPage resources. These are usually external references.
+
+```
+Manifest
+ items
+ Canvas
+ annotations
+ AnnotationPage
+ items
+ Annotation
+```
+
+## Annotation Page
+
+Annotation Pages are used to group Annotations. In cases where many annotations are present, such as when transcription, translation, and commentary are associated with a manuscript, it can be useful to separate these annotations into groups that can facilitate improved user interactions in a client.
+
+Each Annotation Page can be embedded or externally referenced. Clients should process the Annotation Pages and their items in the order given in the Container. Publishers may choose to expedite the processing of embedded Annotation Pages by ordering them before external pages, which will need to be dereferenced by the client. Order can be significant, however. Annotations are assigned an ascending [z-index](https://developer.mozilla.org/en-US/docs/Web/CSS/z-index) from the first annotation encountered. Annotations with a higher z-index will render in front of those with a lower z-index when displayed on a Canvas.
+
+## Annotation Collection
+
+Annotation Collections represent groupings of Annotation Pages that should be managed as a single whole, regardless of which Container or resource they target. This allows, for example, all of the Annotations that make up a particular translation of the text of a book to be collected together. A client might then present a user interface that allows all of the Annotations in an Annotation Collection to be displayed or hidden according to the user’s preference.
+
+For Annotation Collections with many Annotations, there will be many pages. The Annotation Collection refers to the first and last page, and then the pages refer to the previous and next pages in the ordered list. Each page is part of the Annotation Collection.
+
+```json
+{
+ "id": "https://example.org/iiif/book1/annocoll/transcription",
+ "type": "AnnotationCollection",
+ "label": {"en": ["Diplomatic Transcription"]},
+ "total": 112,
+ "first": { "id": "https://example.org/iiif/book1/annopage/l1", "type": "AnnotationPage" },
+ "last": { "id": "https://example.org/iiif/book1/annopage/l112", "type": "AnnotationPage" }
+}
+```
+
+```jsonc
+{
+ "id": "https://example.org/iiif/book1/annopage/l2",
+ "type": "AnnotationPage",
+ "prev": "https://example.org/iiif/book1/annopage/l1",
+ "next": "https://example.org/iiif/book1/annopage/l3",
+ "items": [
+ {
+ "id": "https://example.org/iiif/book1/annopage/l2/a1",
+ "type": "Annotation"
+ // ...
+ },
+ {
+ "id": "https://example.org/iiif/book1/annopage/l2/a2",
+ "type": "Annotation"
+ // ...
+ }
+ ],
+ "partOf": [
+ {
+ "id": "https://example.org/iiif/book1/annocoll/transcription",
+ "type": "AnnotationCollection",
+ }
+ ]
+}
+```
+
+
+
+## Comment Annotations
+
+Commentary can be associated with a Timeline, Canvas, or Scene via Annotations with a `commenting` motivation.
+
+### A comment about a segment of music
+
+
+
+This is an example of a commenting annotation that targets two-minute segment of a muscial performance.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/1",
+ "type": "Annotation",
+ "motivation": [ "commenting" ],
+ "body": {
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/1/theme2",
+ "type": "TextualBody",
+ "language": "en",
+ "format": "text/plain",
+ "value": "The second theme of the concerto is introduced."
+ },
+ "target": "https://example.org/iiif/presentation/examples/commenting/timeline/t1#t=38.0,158.0"
+ }
+```
+
+### A comment about a face in a painting
+
+A comment on a Canvas can target a non-rectangular area. This example uses a `SvgSelector` to comment on a painting.
+
+```json
+{
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/2",
+ "type": "Annotation",
+ "motivation": [ "commenting" ],
+ "body": {
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/2/person2",
+ "type": "TextualBody",
+ "language": "en",
+ "format": "text/plain",
+ "value": "Note the expressive eyes of the subject of this painting."
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/presentation/examples/commenting/canvas/2",
+ "type": "Canvas"
+ },
+ "selector": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno2/selector2",
+ "type": "SvgSelector",
+ "value": " ... "
+ }
+ ]
+ }
+}
+```
+
+Annotations may alternately use a different type of Selector, called a `WktSelector`, to align the Annotation to a target region within a Canvas or Scene.
+
+### A comment about 3D sculpture
+
+A commenting annotation can also reference a Content Resource, such as a Model, within a Scene. This is accomplished by targeting the annotation that paints the resource into the Scene. In this example, the commenting annotation targets an annotation that paints a model of a portrait bust into a scene.
+
+In some cases it is desirable to influence the client's positioning of the commenting annotation when rendered. This may be done to ensure that the annotation does not hide key visual elements or to ensure that the annotation itself is not obscured by resources painted in the Container, such as 3D models. In these cases, the `position` property may be used to define the position where a TextualBody should be rendered. The example shows a `position` that places the annotation at a specific coordinate within the Scene. The position is a `SpecificResource` that requires a `source` and `selector`.
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/manifest/commenting/manifest/3",
+ "type": "Manifest",
+ "label": { "en": [ "1st Centry Roman portrait bust with comment" ] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/commenting/scene3",
+ "type": "Scene",
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/commenting/scene3/painting-annotation-pages/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/commenting/scene3/sculpture",
+ "type": "Annotation",
+ "motivation": [ "painting"] ,
+ "label": {
+ "en": [ "A 1st century Roman portait bust." ]
+ },
+ "body": {
+ "id": "https://example.org/iiif/scene/commenting/models/portait.gltf",
+ "type": "Model"
+ },
+ "target": "https://example.org/iiif/scene/commenting/scene3"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/scene/commenting/scene3/commenting-annotation-pages/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/3",
+ "type": "Annotation",
+ "motivation": [ "commenting" ],
+ "body": {
+ "id": "https://example.org/iiif/presentation/examples/commenting/anno/3/comment1",
+ "type": "TextualBody",
+ "language": "en",
+ "format": "text/plain",
+ "value": "This marble portrait exemplifies the veristic tradition that dominated Roman Republican portraiture and persisted into the early Imperial period.",
+ "position": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene/commenting/scene3",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 0.75,
+ "y": 1.5,
+ "z": 0.1
+ }
+ ]
+ }
+ },
+ "target": "https://example.org/iiif/scene/commenting/scene3/sculpture"
+ }
+ ]
+ }
+ ]
+}
+```
+
+
+
+
+## Linking Annotations
+
+An Annotation with the motivation `linking` is used to create links between resources, both within the Manifest or to external content on the web, including other IIIF resources. Examples include linking to the continuation of an article in a digitized newspaper in a different Canvas, or to an external web page that describes the diagram in the Canvas. A client typically renders the links as clickable "Hotspots" - but can offer whatever accessible affordance as appropriate. The user experience of whether the linked resource is opened in a new tab, new window or by replacing the current view is up to the implementation.
+
+The resource the user should be taken to is the `body` of the annotation, and the region of the Container that the user clicks or otherwise activates to follow the link is the `target`:
+
+```jsonc
+{
+ "id": "https://example.com/annotation/p0002-link",
+ "type": "Annotation",
+ "motivation": "linking",
+ "body": [
+ {
+ "id": "https://example.com/website1",
+ "type": "Text"
+ }
+ ],
+ "target": "https://example.com/canvas/p1#xywh=265,661,1260,1239"
+}
+```
+
+
+## Activating Annotations
+
+Sometimes it is necessary to modify the contents of a Container in the contexts of different annotations on that Container. This technique allows IIIF to be used for exhibitions, storytelling (fwd ref) and other interactive applications beyond simply conveying a set of static resources in a Container.
+
+Annotations with the motivation `activating` are referred to as _activating_ annotations, and are used to link a resource that triggers an action with the resource(s) to change, enable or disable. The `target` of the activating annotation could be a commenting annotation, for which a user might click a corresponding UI element. In other scenarios the `target` could be the painting annotation of a 3D model, or an annotation that targets part of a model, or a region of a Canvas, or a point or segment of a Timeline, or any other annotation that a user could interact with (in whatever manner) to trigger an event. Even a volume of space in a Scene or an extent of time in a Container with `duration` could be the `target`, so that when the user "enters" that region or extent, something happens.
+
+The `body` of the annotation is then activated. This has different processing requirements depending on what the body is:
+
+* If the body is a reference to a Painting Annotation:
+ * if the annotation has the `behavior` "hidden", then remove "hidden" from the `behavior`.
+ * if the annotation paints a Camera, make that Camera the active Camera (i.e., make this the viewport) (see [ref]).
+* If the body is a SpecificResource with a `selector` property with the type "AnimationSelector", play the animation named by the `value` property of the Selector. (see [ref]).
+* If the body has the `type` "JSONPatch", apply the patch operations listed in `operations` to the resource identified by `patchTarget`. (see [ref]).
+* Processing for other body types can be found in the [IIIF Cookbook][ref]
+
+Activating annotations are provided in a Container's `annotations` property. They can be mixed in with the commenting (or other interactive annotations) they target, or they can be in a separate AnnotationPage. The client should evaluate all the activating annotations it can find.
+
+```jsonc
+{
+ "id": "https://example.org/iiif/3d/anno9",
+ "type": "Annotation",
+ "motivation": ["activating"],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/commenting-anno-for-mandibular-tooth",
+ "type": "Annotation"
+ }
+ ],
+ "body": [
+ {
+ "id": "https://example.org/iiif/3d/anno-that-paints-desired-camera-to-view-tooth",
+ "type": "Annotation"
+ }
+ ]
+}
+```
+
+
+### Showing and hiding resources
+
+An activating annotation has two additional optional properties:
+
+* `enables`: For each Annotation or AnnotationPage in the value, remove the 'hidden' behavior if it has it.
+* `disables`: For each Annotation or AnnotationPage in the value, add the 'hidden' behavior if it does not have it.
+
+If the values are the `id` properties of painting annotations that paint models, `enables` makes them visible and `disables` hides them. If they paint Lights, `enables` turns them on and `disables` turns them off.
+
+Referencing a Painting Annotation as the `body` of an activating annotation implicitly enables it, as if it had been listed in `enables`. The inverse is not always true - for example, referencing a Camera in `enables` removes the "hidden" `behavior` and therefore allows it to be included in the client's evaluation of what the default camera is, but does not perform the additional action of changing the viewport to that Camera. For Lights and Models in a Scene, the two are equivalent because no _additional_ processing behavior is provided by this specification.
+
+For many use cases, the activating annotations don't need bodies. The following example demonstrates a light switch that can be toggled on and off:
+
+```jsonc
+{
+ "@context": "http://iiif.io/api/presentation/4/context.json",
+ "id": "https://example.org/iiif/manifest/switch",
+ "type": "Manifest",
+ "label": { "en": [ "Light switch" ] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1",
+ "type": "Scene",
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/painting-annotation-pages/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/painting-annotation/lightswitch-1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "label": {
+ "en": ["A light switch"]
+ },
+ "body": {
+ "id": "https://example.org/iiif/model/models/lightswitch.gltf",
+ "type": "Model"
+ },
+ "target": "https://example.org/iiif/scene/switch/scene-1"
+ },
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/lights/point-light-4",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://example.org/iiif/scene/switch/scene-1/lights/4/body",
+ "type": "PointLight"
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": "https://example.org/iiif/scene/switch/scene-1",
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 5, "y": 5, "z": 5
+ }
+ ]
+ },
+ "behavior": ["hidden"]
+ }
+ ]
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/annos/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/annos/1/switch-comment-0",
+ "type": "Annotation",
+ "motivation": [
+ "commenting"
+ ],
+ "body": {
+ "type": "TextualBody",
+ "value": "Click the switch to turn the light on or off"
+ },
+ "target": "https://example.org/iiif/painting-annotation/lightswitch-1"
+ },
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-on-2",
+ "type": "Annotation",
+ "motivation": [
+ "activating"
+ ],
+ "target": "https://example.org/iiif/painting-annotation/lightswitch-1",
+ "disables": [
+ "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-on-2"
+ ],
+ "enables": [
+ "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-off-3",
+ "https://example.org/iiif/scene/switch/scene-1/lights/point-light-4"
+ ]
+ },
+ {
+ "id": "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-off-3",
+ "type": "Annotation",
+ "motivation": [
+ "activating"
+ ],
+ "target": "https://example.org/iiif/painting-annotation/lightswitch-1",
+ "disables": [
+ "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-off-3",
+ "https://example.org/iiif/scene/switch/scene-1/lights/point-light-4"
+ ],
+ "enables": [
+ "https://example.org/iiif/scene/switch/scene-1/annos/1/activating-on-2"
+ ],
+ "behavior": ["hidden"]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+* Initially, a model of a light switch is painted into the Scene. A PointLight is also painted, but with the `behavior` "hidden", which means it is inactive (i.e., off). A commenting annotation with the text "Click the switch to turn the light on or off" targets the light switch. An activating annotation targets the commenting annotation, so that user interaction with the commenting annotation will trigger the activating annotation. This activating annotation has no `body`, but it does have `enables` with values that are the `id` properties of the painting annotation for the light switch model, and the activating annotation that turns the light off. It also has a `disables` with the value of its own `id` - i.e., it disables _itself_. A further activating annotation has the opposite effect. Initially this has the `behavior` "hidden" - which means it is inactive. It also targets the commenting annotation, but has no effect while hidden.
+* When the user interacts with the light switch model, the client processes any activating annotations that target it and are not hidden. In this case, the first activating annotation is triggered because while both target the switch, only the first is not hidden. This activation `enables` the light (i.e., removing its "hidden" `behavior` and therefore turning it on) and the other activating annotation, and `disables` itself.
+* If the user clicks the light again, the client again processes any activating annotations that target it and are not hidden. This time the second annotation is the active one - and it `disables` the light (turning it off) and itself, and enables the first activating annotation again.
+* Subsequent clicks simply alternate between these two states, indefinitely.
+
+
+### Triggering a named animation in a model
+
+Sometimes a model file has inbuilt animations. While a description of these is outside the scope of IIIF, because it is 3D-implementation-specific, as long as there is a way to refer to a model's animation(s) by name, we can connect the animation to IIIF resources.
+
+This pattern is also achieved with activating annotations, except that the body of the activating annotation references a _named animation_ in the model. The `body` MUST be a SpecificResource, where the `source` is the Painting Annotation that paints the model, and the `selector` is of type `AnimationSelector` with the `value` being a string that corresponds to the animation in the model.
+
+The format of the `value` string is implementation-specific, and will depend on how different 3D formats support addressing of animations within models. The same model can be painted multiple times into the scene, and you might want to activate only one model's animation, thus we need to refer to the annotation that paints the model, not the model directly.
+
+
+```jsonc
+{
+ "id": "https://example.org/iiif/3d/activating-animation.json",
+ "type": "Manifest",
+ "label": { "en": ["Music Box with lid that opens as an internal animation"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/scene-with-activation-animation",
+ "type": "Scene",
+ "label": { "en": ["A Scene Containing a Music Box"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene-with-activation-animation/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/painting-anno-for-music-box",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/music-box.glb",
+ "type": "Model"
+ },
+ "target": {
+ // SpecificResource with PointSelector
+ }
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/scene1/page/activators",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/box-opening-commenting-anno",
+ "type": "Annotation",
+ "motivation": ["commenting"],
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "Click the box to open the lid"
+ }
+ ],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/painting-anno-for-music-box",
+ "type": "Annotation"
+ }
+ ]
+ }
+ {
+ "id": "https://example.org/iiif/3d/box-opening-activating-anno",
+ "type": "Annotation",
+ "motivation": ["activating"],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/box-opening-commenting-anno",
+ "type": "Annotation"
+ }
+ ],
+ "body": [
+ {
+ "type": "SpecificResource",
+ "source": "https://example.org/iiif/3d/painting-anno-for-music-box",
+ "selector": [
+ {
+ "type": "AnimationSelector",
+ "value": "open-the-lid"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+### 3D Comments with Cameras
+
+In many complex 3D Scenes, it may not be clear what or how to look at a particular point of interest even when the commenting annotation targets a particular point. The view may be occluded by parts of the model, or other models in the Scene. In the following example, the user can explore the Scene freely, but when they select a particular comment, a specific Camera that was previously hidden (unavailable to the user) is activated, moving the user (i.e., setting the viewport) to a chosen position suitable for looking at the point of interest:
+
+```jsonc
+{
+ "id": "https://example.org/iiif/3d/whale_comment_scope_content_state.json",
+ "type": "Manifest",
+ "label": { "en": ["Whale Cranium and Mandible with Dynamic Commenting Annotations and Custom Per-Anno Views"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "label": { "en": ["A Scene Containing a Whale Cranium and Mandible"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno1",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/whale/whale_mandible.glb",
+ "type": "Model"
+ },
+ "target": {
+ // SpecificResource with PointSelector
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno-that-paints-desired-camera-to-view-tooth",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "behavior": ["hidden"],
+ "body": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/3d/cameras/1",
+ "type": "PerspectiveCamera",
+ "label": {"en": ["Perspective Camera Pointed At Front of Cranium and Mandible"]},
+ "fieldOfView": 50.0,
+ "near": 0.10,
+ "far": 2000.0
+ }
+ ]
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 0.0, "y": 0.15, "z": 0.75
+ }
+ ]
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno2",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/whale/whale_cranium.glb",
+ "type": "Model"
+ },
+ "target": {
+ // SpecificResource with PointSelector
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/annotations/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/commenting-anno-for-mandibular-tooth",
+ "type": "Annotation",
+ "motivation": ["commenting"],
+ "bodyValue": "Mandibular tooth",
+ "target": {
+ // SpecificResource with PointSelector
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/commenting-anno-for-right-pterygoid-hamulus",
+ "type": "Annotation",
+ "motivation": ["commenting"],
+ "bodyValue": "Right pterygoid hamulus",
+ "target": {
+ // SpecificResource with PointSelector
+ }
+ },
+ {
+ "id": "https://example.org/iiif/3d/anno9",
+ "type": "Annotation",
+ "motivation": ["activating"],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/commenting-anno-for-mandibular-tooth",
+ "type": "Annotation"
+ }
+ ],
+ "body": [
+ {
+ "id": "https://example.org/iiif/3d/anno-that-paints-desired-camera-to-view-tooth",
+ "type": "Annotation"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+The client will render a UI that presents the two commenting annotations in some form and allows the user to navigate between them. An active Camera is not provided (while there is a Camera in the Scene it has `behavior` "hidden", i.e., it is inactive: not usable). The commenting annotations are ordered; while the user might explore them freely in the Scene they might also go "forward" from the first to the second commenting annotation and "back" to the first from the second. In either case the above example instructs the client to activate the Camera when the user interacts with the comment. The user is free to move away but any interaction with that comment will bring them back to the specific viewpoint. (forward ref to chains of activation example)
+
+Default camera:
+
+
+
+Camera when annotation selected:
+
+
+
+
+### Modifying resource properties
+
+Many Scene interaction use cases can be accomplished using the `enables` and `disables` properties to toggle the `"behavior": ["hidden"]`, and/or using activating annotations with bodies that can be _activated_: the examples above show a Camera and then an Animation being activated. Models in the Scene can also be shown and hidden via these properties.
+
+> when to use enables and when to use the `body` of the activating anno - are they equivalent for, say, a hidden model: enable it, activate it - interchangeable?
+
+For some interactions it is necessary to do more than show or hide or "activate" resources, by changing just `"behavior": ["hidden"]`. Other properties can also be changed via the [JSON Patch](link) mechanism.
+
+```jsonc
+{
+ "type": "JSONPatch",
+ "patchTarget": "https://example.org/iiif/scene1/scene-with-color-change", // the Scene
+ "operations": [
+ {
+ "op": "replace",
+ "path": "/backgroundColor", // path to the property being changed.
+ "value": "#FF99AA"
+ }
+ ]
+}
+```
+
+> **This is a clear distinction like level0, level1 - a client can simply choose not to support arbitrary patching.**
+
+> Be clear that you still need to have all the patchable resources present from the start, you can't pull them in later.
+
+In the following simple example, the background color of the Scene is changed:
+
+
+```jsonc
+{
+ "id": "https://example.org/iiif/3d/property-change.json",
+ "type": "Manifest",
+ "label": { "en": ["Whale Mandible"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/scene-with-color-change",
+ "type": "Scene",
+ "label": { "en": ["A Scene Containing a Whale Mandible"] },
+ "items": [
+ {
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/painting-anno-for-mandible",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "id": "https://raw.githubusercontent.com/IIIF/3d/main/assets/whale/whale_mandible.glb",
+ "type": "Model"
+ },
+ "target": "https://example.org/iiif/scene1/scene-with-color-change"
+ }
+ ],
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/scene1/page/activators",
+ "type": "AnnotationPage",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/color-change-commenting-anno",
+ "type": "Annotation",
+ "motivation": ["commenting"],
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "Change the background color"
+ }
+ ],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/painting-anno-for-mandible", // or the Scene?
+ "type": "Annotation"
+ }
+ ]
+ }
+ {
+ "id": "https://example.org/iiif/3d/color-change-activating-anno",
+ "type": "Annotation",
+ "motivation": ["activating"],
+ "target": [
+ {
+ "id": "https://example.org/iiif/3d/color-change-commenting-anno",
+ "type": "Annotation"
+ }
+ ],
+ "body": [
+ {
+ "type": "JSONPatch",
+ "patchTarget": "https://example.org/iiif/scene1/scene-with-color-change",
+ "operations": [
+ {
+ "op": "replace",
+ "path": "/backgroundColor",
+ "value": "#FF99AA"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+# Integration
+
+seeAlso, service(s), extensions
+mention search, image api, auth
+
+profile for seeAlso
+
+partOf -
+
+
+
+
+
+# Content State
+
+(this + model doc should relieve Content State spec of modelling concerns and leave it entirely about protocol)
+
+A Content State is simply any valid IIIF Presentation Resource, or part of a Presentation resource. The following are all Content States that describe a "fragment" of IIIF:
+
+A "bare" Manifest URI:
+
+```
+https://example.org/manifests/1
+```
+
+A reference to a Manifest:
+
+```json
+{
+ "id": "https://example.org/manifests/1",
+ "type": "Manifest"
+}
+```
+
+A region of a Canvas within a Manifest:
+
+```json
+{
+ "id": "https://example.org/canvases/aabb#xywh=4500,1266,600,600",
+ "type": "Canvas",
+ "partOf": {
+ "id": "https://example.org/manifests/1",
+ "type": "Manifest"
+ }
+}
+```
+
+Two versions of a painting from different publishers:
+
+```json
+[
+ {
+ "id": "https://gallery-1.org/iiif/sunflowers/canvas1",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://gallery-1.org/iiif/sunflowers",
+ "type": "Manifest"
+ }
+ ]
+ },
+ {
+ "id": "https://gallery-2.org/collection/sunflowers/c1",
+ "type": "Canvas",
+ "partOf": [
+ {
+ "id": "https://gallery-2.org/collection/sunflowers",
+ "type": "Manifest"
+ }
+ ]
+ }
+]
+```
+
+A Scene with a Camera at a particular point:
+
+
+```json
+{
+ "id": "https://example.org/iiif/scene1/page/p1/1",
+ "type": "Scene",
+ "items": [
+ {
+ "id": "https://example.org/iiif/3d/anno8",
+ "type": "Annotation",
+ "motivation": ["painting"],
+ "body": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/3d/cameras/1",
+ "type": "PerspectiveCamera",
+ "label": {
+ "en": [
+ "Perspective Camera Pointed At Front of Cranium and Mandible"
+ ]
+ },
+ "fieldOfView": 50.0,
+ "near": 0.1,
+ "far": 2000.0
+ }
+ ]
+ },
+ "target": {
+ "type": "SpecificResource",
+ "source": [
+ {
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ }
+ ],
+ "selector": [
+ {
+ "type": "PointSelector",
+ "x": 0.0, "y": 0.15, "z": 0.75
+ }
+ ]
+ }
+ }
+ ]
+}
+```
+
+The term _Content State_ is used for any arbitrary fragments of IIIF such as the above when they are used in the particular ways defined by this specification. A Content State is **usually** carried by the `target` of an annotation with the motivation `contentState`, or `body` of an annotation with the motivation `activating`, but in some scenarios may be transferred between client applications without an enclosing annotation, as a "bare" URI (see Content State 2.0 specification).
+
+Annotations with the motivation `contentState` are referred to as _content state_ annotations.
+
+Content States are used for the following applications:
+
+## Load a particular view of a resource or group of resources
+
+In this usage, an annotation with the motivation `contentState` is passed to a client to initialize it with a particular view of a resource. Almost all IIIF Clients initialize from the very simplest form of Content State - a Manifest URI. A more complex Content State might target a particular region of a particular canvas within a Manifest, as in the second example above. A client initialized from such a Content State would load the Manifest, show the particular Canvas, and perhaps zoom in on the target region.
+
+The mechanisms for passing Content State into a client, and exporting a Content State from a client, are given in the Content State Protocol API 2.0 specification, which describes the scenarios in which a URI, or Content State not carried by an annotation, should be interpreted by a Client as a Content State.
+
+
+## Load a particular view of some resource and modify it
+
+âš what are we doing with this? Do we still allow it? It's a good use case...
+
+In the previous usage, the fragment of IIIF carried by the annotation with the motivation `contentState` provides enough information for a Client to load a resource and show it. This fragment can also carry additional IIIF Presentation API resources not shown in the referred-to resource. For example, in the following example the Content State carries additional annotations not present in the original published Manifest. A client initializing from this Content State would show these additional annotations to the user:
+
+What to do about activating annos in the introduced content?
+
+```json
+{
+ "id": "https://example.org/import/3",
+ "type": "Annotation",
+ "motivation": "contentState",
+ "target": {
+ "id": "https://example.org/canvases/aabb#xywh=4500,1266,600,600",
+ "type": "Canvas",
+ "partOf": {
+ "id": "https://example.org/manifests/nook12",
+ "type": "Manifest"
+ },
+ "annotations": [
+ {
+ "id": "https://my-annotation-store.org/user4532/notes-on-book12/p1",
+ "type": "AnnotationPage"
+ }
+ ]
+ }
+}
+```
+
+
+# Interactivity, Guided Viewing and Storytelling
+
+
+A narrative might comprise an AnnotationPage of `commenting` annotations that target different parts of the Container, for example a guided tour of a painting or a map. For a Canvas or Timeline it is usually sufficient to leave the interactivity to the client; the fact that comments target different extents implies the client must offer some affordance for those comments (typically the user can click each one), and in response the client will move the current play point of the Timeline to the commenting annotation target, or pan and zoom the viewport to show the relevant part of an image. For 3D this may not be enough; a particular comment may only make sense from a certain viewpoint (i.e., Camera), or different steps of the story require different Lights to be active.
+
+In a storytelling or exhibition scenario, the non-painting `annotations` might be carrying informative text, or even rich HTML bodies. They can be considered to be _steps_ in the story. The use of activating annotations (back ref) allows a precise storytelling experience to be specified, including:
+
+ - providing a specific viewpoint for each step of the narrative (or even a choice of viewpoints)
+ - modifying the lighting of the Scene for each step, for example shining a spotlight on a point of interest
+ - hiding models in the Scene at a particular step
+ - showing additional models at a particular step
+
+All the annotations referred to by the activating annotations' `target` and `body` properties are already present in the Scene from the beginning. Initially, many of them may have the behavior `hidden`, invisible until activated.
+
+
+## The `sequence` behavior
+
+While all AnnotationPage `items` are inherently ordered, an Annotation Page with the `behavior` "sequence" is explicitly a narrative, and clients should prevent (dissuade) users from jumping about - the annotations, and the effects of them _activating_ other contents of the Container, are intended to be experienced in order and individually. Normally, a client might display all the comments in an AnnotationPage in a sidebar so they are all visible in the UI, but for an AnnotationPage with `behavior` "sequence" only show the currently active annotation text, and next and previous UI.
+
+
+## Chains of activation
+
+Chaining together activating annotations can then allow the implementation of, at least:
+
+* Specific camera position to look at an Annotation
+* Multi-step linear stories
+* Animations, including as part of stories without disrupting the flow, and looping animations (they activate themselves)
+* Interactive components such as light switches (enable/disable a light), jukeboxes (enable/disable Audio Emitter)
+
+
+## Storytelling example
+
+* Something really cool that brings a lot of things together!
+* Use JSONPatch to move a model too.
+
+
+# Conveying Physical Dimensions
+
+In many cases, the dimensions of a Canvas, or the pixel density of a photograph, are not necessarily related to a real-world size of the object they show. A large wall painting and a tiny miniature may both be conveyed by 20 megapixel source images on a 4000 by 3000 unit Canvas. But it can be important to know how big something is or if there is a relationship between pixel density and physical length, especially when comparing objects together. Each pixel in an image may correspond precisely to a physical area, allowing measurement of real world distances from the image. A scanned 3D model may be constructed such that each 3D coordinate unit corresponds to one meter of physical distance.
+
+The `spatialScale` property of a Canvas or Scene provides a corresponding real-world scale for a unit of the Canvas or Scene coordinate system, allowing clients to provide scale information to users, for example by an on-screen virtual ruler. In a 2-up viewer, a client could scale two views to convey the true relative sizes of two objects.
+
+The value of `spatialScale` is a `UnitValue` (ref) that has as a value a length unit. This specification defines only one length unit, "m", i.e., meters, though others may be defined externally as an [extension][prezi30-ldce]. If source size metadata is machine readable (or parse-able) in other measurement systems (e.g., feet and inches) then it should be converted to meters for use in `spatialScale`. Publishers may wish to present the original given measure (e.g., from catalogue metadata) in a `metadata` field for context.
+
+The Presentation API also offers a corresponding `temporalScale` property for the `duration` dimension of a Container, when 1 second in the Container does not correspond to 1 second of real time. This is useful for speeded-up or slowed-down audio or video.
+
+An extreme example of both physical dimension properties together is a Canvas showing an animation of continental drift over the course of Earth history, where the spatialScale could convey that each Canvas unit is several thousand meters, and each second of the Canvas `duration` is several million years.
+
+
+
+# Other stuff
+
+## Embedded Content
+
+e.g., painting TextualBody on Canvas
+
+
+## Style
+
+### Rotation
+
+
+
+
+
+
+# Protocol
+
+This section outlines recommendations and requirements related to URIs, HTTP requests, and authentication for IIIF resources.
+
+## URI Recommendations
+
+While any HTTP(S) URI is technically acceptable for any of the resources in the API, there are several best practices for designing the URIs for the resources.
+
+* The URI _SHOULD_ use the HTTPS scheme, not HTTP.
+* The URI _SHOULD NOT_ include query parameters or fragments.
+* Once published, they _SHOULD_ be as persistent and unchanging as possible.
+* Special characters _MUST_ be encoded.
+
+## HTTP Requests and Responses
+
+This section describes the _RECOMMENDED_ request and response interactions for the API. The REST and simple HATEOAS approach is followed where an interaction will retrieve a description of the resource, and additional calls may be made by following links obtained from within the description. All of the requests use the HTTP GET method; creation and update of resources is not covered by this specification. It is _RECOMMENDED_ that implementations also support HTTP HEAD requests.
+
+### Requests
+
+Clients are only expected to follow links to Presentation API resources. Unlike [IIIF Image API][image-api] requests, or other parameterized services, the URIs for Presentation API resources cannot be assumed to follow any particular pattern.
+
+### Responses
+
+The format for all responses is JSON, as described above. It is good practice for all resources with an HTTP(S) URI to provide their description when the URI is dereferenced. If a resource is [referenced][prezi30-terminology] within a response, rather than being [embedded][prezi30-terminology], then it _MUST_ be able to be dereferenced.
+
+If the server receives a request with an `Accept` header, it _SHOULD_ respond following the rules of [content negotiation][org-rfc-7231-conneg]. Note that content types provided in the `Accept` header of the request _MAY_ include parameters, for example `profile` or `charset`.
+
+If the request does not include an `Accept` header, the HTTP `Content-Type` header of the response _SHOULD_ have the value `application/ld+json` (JSON-LD) with the `profile` parameter given as the context document: `http://iiif.io/api/presentation/4/context.json`.
+
+{% include api/code_header.html %}
+```
+Content-Type: application/ld+json;profile="http://iiif.io/api/presentation/4/context.json"
+```
+{: .urltemplate}
+
+If the `Content-Type` header `application/ld+json` cannot be generated due to server configuration details, then the `Content-Type` header _SHOULD_ instead be `application/json` (regular JSON), without a `profile` parameter.
+
+{% include api/code_header.html %}
+```
+Content-Type: application/json
+```
+{: .urltemplate}
+
+The HTTP server _MUST_ follow the [CORS requirements][org-w3c-cors] to enable browser-based clients to retrieve the descriptions. If the server receives a request with one of the content types above in the Accept header, it _SHOULD_ respond with that content type following the rules of [content negotiation][org-rfc-7231-conneg]. Recipes for enabling CORS and conditional Content-Type headers are provided in the [Apache HTTP Server Implementation Notes][notes-apache].
+
+Responses _SHOULD_ be compressed by the server as there are significant performance gains to be made for very repetitive data structures.
+
+## Authentication
+
+It may be necessary to restrict access to the descriptions made available via the Presentation API. As the primary means of interaction with the descriptions is by web browsers using XmlHttpRequests across domains, there are some considerations regarding the most appropriate methods for authenticating users and authorizing their access. The approach taken is described in the [Authentication][iiif-auth] specification, and requires requesting a token to add to the requests to identify the user. This token might also be used for other requests defined by other APIs.
+
+It is possible to include Image API service descriptions within the Manifest, and within those it is also possible to include links to the Authentication API's services that are needed to interact with the image content. The first time an Authentication API service is included within a Manifest, it _MUST_ be the complete description. Subsequent references _SHOULD_ be just the URI of the service, and clients are expected to look up the details from the full description by matching the URI. Clients _MUST_ anticipate situations where the Authentication service description in the Manifest is out of date: the source of truth is the Image Information document, or other system that references the Authentication API services.
+
+# Accessibility
+
+(new section)
+
+`provides`
+`provides[]`
+
+
+
+
+
+
+
+# Terminology
+
+The principles of [Linked Data][org-linked-data] and the [Architecture of the Web][org-w3c-webarch] are adopted in order to provide a distributed and interoperable framework. The [Shared Canvas data model][shared-canvas] and [JSON-LD][org-w3c-json-ld] are leveraged to create an easy-to-implement, JSON-based format.
+
+This specification uses the following terms:
+
+* __embedded__: When a resource (A) is embedded within an embedding resource (B), the complete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will not result in additional information. Example: Canvas A is embedded in Manifest B.
+* __referenced__: When a resource (A) is referenced from a referencing resource (B), an incomplete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will result in additional information. Example: Manifest A is referenced from Collection B.
+* __HTTP(S)__: The HTTP or HTTPS URI scheme and internet protocol.
+
+The terms _array_, _JSON object_, _number_, _string_, and _boolean_ in this document are to be interpreted as defined by the [Javascript Object Notation (JSON)][org-rfc-8259] specification.
+
+The key words _MUST_, _MUST NOT_, _REQUIRED_, _SHALL_, _SHALL NOT_, _SHOULD_, _SHOULD NOT_, _RECOMMENDED_, _MAY_, and _OPTIONAL_ in this document are to be interpreted as described in [RFC 2119][org-rfc-2119].
+
+
+
+# Appendices
+
+## Versioning
+
+## Acknowledgements
+
+## Change Log
+
+
diff --git a/source/presentation/4.0/model.md b/source/presentation/4.0/model.md
new file mode 100644
index 000000000..b9de672cd
--- /dev/null
+++ b/source/presentation/4.0/model.md
@@ -0,0 +1,2967 @@
+---
+title: "Presentation API 4.0 Properties"
+title_override: "IIIF Presentation API 4.0 Properties"
+id: presentation-api-model
+layout: spec
+cssversion: 3
+tags: [specifications, presentation-api]
+major: 4
+minor: 0
+patch: 0
+pre:
+redirect_from:
+ - /presentation/model.html
+ - /presentation/4/model.html
+editors:
+ - name: Michael Appleby
+ ORCID: https://orcid.org/0000-0002-1266-298X
+ institution: Yale University
+ - name: Tom Crane
+ ORCID: https://orcid.org/0000-0003-1881-243X
+ institution: Digirati
+ - name: Robert Sanderson
+ ORCID: https://orcid.org/0000-0003-4441-6852
+ institution: Yale University
+ - name: Dawn Childress
+ ORCID: https://orcid.org/0000-0003-2602-2788
+ institution: UCLA
+ - name: Julie Winchester
+ ORCID: https://orcid.org/0000-0001-6578-764X
+ institution: Duke University
+ - name: Jeff Mixter
+ ORCID: https://orcid.org/0000-0002-8411-2952
+ institution: OCLC
+hero:
+ image: ''
+---
+
+## Status of this Document
+{:.no_toc}
+__This Version:__ {{ page.major }}.{{ page.minor }}.{{ page.patch }}{% if page.pre != 'final' %}-{{ page.pre }}{% endif %}
+
+__Latest Stable Version:__ [{{ site.data.apis.presentation.latest.major }}.{{ site.data.apis.presentation.latest.minor }}.{{ site.data.apis.presentation.latest.patch }}][prezi-stable-version]
+
+__Previous Version:__ [3.0][prezi30]
+
+**Editors:**
+
+{% include api/editors.md editors=page.editors %}
+
+{% include copyright.md %}
+
+----
+
+# IIIF Presentation API Data Model
+
+
+
+
+## Introduction
+{: #introduction}
+
+The IIIF Presentation API is backed by a standards-based data model inspired by both earlier tree structured representations of cultural heritage objects, as well as linked data approaches with the same goal. It comprises four main types of resource: Structural (such as Collections, Manifests, and Ranges), Presentational Containers (Canvas, Scene and Timeline), Linking (Annotations), and Content (the images, texts, audio, video and models to be displayed). In addition to these, the model includes supporting classes such as Agents, and extensions to the standards for IIIF specific use cases, such as Transforms for manipulating 3d models within a Scene.
+
+The Presentation API data model intentionally does not include any semantic or descriptive relationships or properties, such as the author of a book or the place where a statue was sculpted; it is solely for presenting content in a structured fashion to human users.
+
+
+## Technical Considerations
+{: #technical-considerations}
+
+This section describes features applicable to all of the classes, properties and affordances of the Presentation API.
+
+### Terminology
+{: #terminology}
+
+This specification uses the following terms:
+
+* __embedded__: When a resource (A) is embedded within an embedding resource (B), the complete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will not result in additional information. Example: Canvas A is embedded in Manifest B.
+* __referenced__: When a resource (A) is referenced from a referencing resource (B), an incomplete JSON representation of resource A is present within the JSON representation of resource B, and dereferencing the URI of resource A will result in additional information. Example: Manifest A is referenced from Collection B.
+* __HTTP(S)__: The HTTP or HTTPS URI scheme and internet protocol.
+
+The terms _array_, _JSON object_, _number_, _string_, and _boolean_ in this document are to be interpreted as defined by the [Javascript Object Notation (JSON)][org-rfc-8259] specification.
+
+The key words _MUST_, _MUST NOT_, _REQUIRED_, _SHALL_, _SHALL NOT_, _SHOULD_, _SHOULD NOT_, _RECOMMENDED_, _MAY_, and _OPTIONAL_ in this document are to be interpreted as described in [RFC 2119][org-rfc-2119].
+
+
+### Case Sensitivity
+{: #case-sensitivity}
+
+Keys in JSON objects are [case sensitive][org-w3c-json-ld-case]. The cases of properties and enumerated values in IIIF Presentation API responses _MUST_ match those used in this specification. For example to specify that a resource is a Manifest, the property _MUST_ be given as `type` and not `Type` or `tYpE`, and the value _MUST_ be given as `Manifest` and not `manifest` or `manIfEsT`.
+
+### Properties with Multiple Values
+{: #properties-with-multiple-values}
+
+Any of the properties in the API that can have multiple values _MUST_ always be given as an array of values, even if there is only a single item in that array.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "thumbnail": [
+ {
+ "id": "https://example.org/images/thumb1.jpg",
+ "type": "Image",
+ "format": "image/jpeg"
+ }
+ ]
+}
+```
+
+### Language of Property Values
+{: #language-of-property-values}
+
+Language _SHOULD_ be associated with strings that are intended to be displayed to the user for the `label` and `summary` properties, plus the `label` and `value` properties of the `metadata` and `requiredStatement` objects. This construction is called a Language Map in the [JSON-LD specification](https://www.w3.org/TR/json-ld11/#language-maps).
+
+The values of these properties _MUST_ be JSON objects, with the keys being the [BCP 47][org-bcp-47] language code for the language, or if the language is either not known or the string does not have a language, then the key _MUST_ be the string `none`. The locale, script and other subtags _MAY_ be included. Clients _SHOULD_ process subtags when comparing the values with the user's provided preferences, however _MAY_ simply reduce all tags down to just the language, discarding everything after the first hyphen, and display all matching values. The associated values _MUST_ be arrays of strings, where each item is the content in the given language.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "label": {
+ "en": [
+ "Whistler's Mother",
+ "Arrangement in Grey and Black No. 1: The Artist's Mother"
+ ],
+ "fr": [
+ "Arrangement en gris et noir no 1",
+ "Portrait de la mère de l'artiste",
+ "La Mère de Whistler"
+ ],
+ "none": [ "Whistler (1871)" ]
+ }
+}
+```
+
+In the case where multiple values are supplied, clients _MUST_ use the following algorithm to determine which values to display to the user.
+
+* If all of the values are associated with the `none` key, the client _MUST_ display all of those values.
+* Else, the client should try to determine the user's language preferences, or failing that use some default language preferences. Then:
+ * If any of the values have a language associated with them, the client _MUST_ display all of the values associated with the language that best matches the language preference.
+ * If all of the values have a language associated with them, and none match the language preference, the client _MUST_ select a language and display all of the values associated with that language.
+ * If some of the values have a language associated with them, but none match the language preference, the client _MUST_ display all of the values that do not have a language associated with them.
+
+Note that this does not apply to [embedded][prezi30-terminology] textual bodies in Annotations, which use the Web Annotation pattern of `value` and `language` as separate properties.
+
+### HTML Markup in Property Values
+
+Minimal HTML markup _MAY_ be included for processing in the `summary` property and the `value` property in the `metadata` and `requiredStatement` objects. It _MUST NOT_ be used in `label` or other properties. This is included to allow content publishers to add links and simple formatting instructions to blocks of text. The content _MUST_ be well-formed XML and wrapped in a single element such as `div`, `p` or `span`. There _MUST NOT_ be whitespace on either side of the HTML string, and thus the first character in the string _MUST_ be a '<' character and the last character _MUST_ be '>', allowing a consuming application to test whether the value is HTML or plain text using these. To avoid a non-HTML string matching this, it is _RECOMMENDED_ that an additional whitespace character be added to the end of the value in situations where plain text happens to start and end this way.
+
+In order to avoid HTML or script injection attacks, clients _MUST_ remove:
+
+ * Tags such as `script`, `style`, `object`, `form`, `input` and similar.
+ * All attributes other than `href` on the `a` tag, `src` and `alt` on the `img` tag.
+ * All `href` attributes that start with the strings other than "http:", "https:", and "mailto:".
+ * CData sections.
+ * XML Comments.
+ * Processing instructions.
+
+Clients _SHOULD_ allow only `a`, `b`, `br`, `div`, `i`, `img`, `p`, `small`, `span`, `sub` and `sup` tags. Clients _MAY_ choose to remove any and all tags, therefore it _SHOULD NOT_ be assumed that the formatting will always be rendered. Note that publishers _MAY_ include arbitrary HTML content for processing using customized or experimental applications, and the requirements for clients assume an untrusted or unknown publisher.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "summary": { "en": [ "Short summary of the resource.
" ] } }
+```
+
+### Resource Availability on the Web
+
+JSON descriptions _SHOULD_ be embedded within the JSON of parent resources, and _MAY_ also be available via separate requests from the HTTP(S) URI given in the resource's `id` property. Links to Content Resources _MUST_ be given as a JSON object with the `id` and `type` properties and _SHOULD_ have `format` or `profile` to give a hint as to what sort of resource is being referred to.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "rendering": [
+ {
+ "id": "https://example.org/content/book.pdf",
+ "type": "Text",
+ "label": { "en": [ "Example Book (pdf)" ] },
+ "format": "application/pdf"
+ }
+ ]
+}
+```
+
+### JSON-LD Contexts and Extensions
+{: #json-ld-contexts-and-extensions}
+
+The top level resource in the response _MUST_ have the `@context` property, and it _SHOULD_ appear as the very first key/value pair of the JSON representation. This tells Linked Data processors how to interpret the document. The IIIF Presentation API context, below, _MUST_ occur once per response in the top-most resource, and thus _MUST NOT_ appear within [embedded][prezi30-terminology] resources. For example, when embedding a Canvas within a Manifest, the Canvas will not have the `@context` property.
+
+The value of the `@context` property _MUST_ be either the URI `http://iiif.io/api/presentation/{{ page.major }}/context.json` or a JSON array with the URI `http://iiif.io/api/presentation/{{ page.major }}/context.json` as the last item. Further contexts, such as those for local or [registered extensions][registry], _MUST_ be added at the beginning of the array.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "@context": "http://iiif.io/api/presentation/{{ page.major }}/context.json"
+}
+```
+
+Any additional properties beyond those defined in this specification or the Web Annotation Data Model _SHOULD_ be mapped to RDF predicates using further context documents. These extensions _SHOULD_ be added to the top level `@context` property, and _MUST_ be added before the above context. The JSON-LD 1.1 functionality of predicate specific context definitions, known as [scoped contexts][org-w3c-json-ld-scoped-contexts], _MUST_ be used to minimize cross-extension collisions. Extensions intended for community use _SHOULD_ be [registered in the extensions registry][registry], but registration is not mandatory.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "@context": [
+ "http://example.org/extension/context.json",
+ "http://iiif.io/api/presentation/{{ page.major }}/context.json"
+ ]
+}
+```
+
+The JSON representation _MUST NOT_ include the `@graph` key at the top level. This key might be created when serializing directly from RDF data using the JSON-LD 1.0 compaction algorithm. Instead, JSON-LD framing and/or custom code should be used to ensure the structure of the document is as defined by this specification.
+
+## Classes
+
+The following sub-sections define the classes used in the IIIF Presentation Data Model. Only the semantics and core structural requirements are defined within this section, along with any deviations from other specifications that the classes might be drawn from. The descriptions do not define how the classes are used together, which is done in the Presentation API Overview.
+
+The name of each class is given at the top of its definition below. The exact string _MUST_ be used as the value of `type` in the JSON for the class.
+
+__Properties__
+All resources _MUST_ have the following property: [type](#type).
+{: .note}
+
+### Collection
+{: #Collection}
+
+> `"type": "Collection"`
+
+A Collection is an ordered list of Manifests, and/or Collections.
+
+A Collection _MUST_ have an HTTP(S) URI given in `id`. It _MUST_ be able to be dereferenced to retrieve the JSON description.
+
+The members of a Collection are typically listed in the `items` property or in a series of Collection Pages. The members _MAY_ include both other Collections and Manifests, in order, to form a tree-structured hierarchy. Collections without any members are allowed but discouraged. For example, a collection that had its last member removed might still be valuable to maintain as an empty collection.
+
+If there are too many members in the collection to fit within a single document, then the members _MAY_ be listed in Collection Pages. A reference to the first page of members is given in the `first` property, and the last page in the `last` property. In this case, the Collection _MUST NOT_ use the `items` property. Collections with pages _MUST_ have at least two pages, otherwise the members should be included in `items` on the Collection. Collection Pages _MUST NOT_ be embedded within the Collection for the same reason.
+
+Member Collections _MAY_ be embedded inline within other Collections, however Manifests _MUST NOT_ be embedded within Collections. An embedded Collection _SHOULD_ also have its own URI from which the JSON description is available.
+
+Manifests or Collections _MAY_ be [referenced][prezi30-terminology] from more than one Collection. For example, an institution might define four Collections: one for modern works, one for historical works, one for newspapers and one for books. The Manifest for a modern newspaper would then appear in both the modern Collection and the newspaper Collection. Alternatively, the institution may choose to have two separate newspaper Collections, and reference each as a sub-Collection of modern and historical.
+
+
+Collections or Manifests referenced in the `items` property _MUST_ have the `id`, `type` and `label` properties. They _SHOULD_ have the `thumbnail` property.
+
+__Properties__
+A Collection _MUST_ have the following properties: [id](#id), [type](#type), and [label](#label)
+A Collection _SHOULD_ have the following properties: [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), and [items](#items)
+A Collection _MAY_ have the following properties: [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [placeholderContainer](#placeholderContainer), [accompanyingContainer](#accompanyingContainer), [viewingDirection](#viewingDirection), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [services](#services), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [start](#start), [first](#first), [last](#last), [total](#total), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+
+#### Collection Page
+{: #CollectionPage}
+
+> `"type": "CollectionPage"`
+
+A Collection Page is an arbitrary division of members within the Collection to make it easier to consume by clients. It does not have any semantic implications by itself. The Collection Page model follows the ActivityStreams OrderedCollection model, as also used in Annotation Collections, the IIIF Change Discovery API, and the IIIF Search API.
+
+A Collection Page _MUST_ have an HTTP(S) URI given in `id`. It _MUST_ be able to be dereferenced to retrieve the JSON description. Collection Pages _MUST NOT_ be embedded within Collections.
+
+All Collection Pages in a Collection, with the exception of the last page, _MUST_ have the `next` property, which provides a reference to the following Collection Page. All Collection Pages in a Collection, with the exception of the first page, _MUST_ have the `prev` property, which provides a reference to the preceding Collection Page. These properties allow the navigation backwards and forwards within the overall set of pages. There is no way to jump to arbitrary positions in the sequence of pages, and clients _MUST NOT_ attempt to infer such methods from the structure of the URI of the Collection Page. Collection Pages _MUST_ have the `partOf` property, refering to the Collection of which they are part.
+
+__Properties__
+A Collection Page _MUST_ have the following properties: [id](#id), [type](#type), [partOf](#partOf) and [items](#items)
+A Collection Page _SHOULD_ have the following properties: [next](#next), and [prev](#prev)
+A Collection Page _MAY_ have the following properties: [startIndex](#startIndex), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+### Manifest
+{: #Manifest}
+
+> `"type": "Manifest"`
+
+A Manifest is the primary unit of distribution of IIIF and provides a description of the structure and properties of a single item to be presented to the user.
+
+Manifests _MUST_ be identified by a URI and it _MUST_ be an HTTP(S) URI, given in the `id` property. It _MUST_ be able to be dereferenced to retrieve the JSON description.
+
+The members of a Manifest are listed in the `items` property. The members of Manifests _MUST_ be Containers, defined below, and are embedded within the Manifest. The Containers in a single Manifest _MAY_ be of different classes. The Manifest _MAY_ have a `structures` property listing one or more [Ranges][#range] which describe additional structure of the content, such as might be rendered as a table of contents. The Manifest _MAY_ have an `annotations` property, which includes Annotation Page resources where the Annotations have the Manifest as their `target`. These Annotations _MUST NOT_ have `painting` as their `motivation`.
+
+
+__Properties__
+A Manifest _MUST_ have the following properties: [id](#id), [type](#type), [label](#label), and [items](#items)
+A Manifest _SHOULD_ have the following properties: [metadata](#metadata), [summary](#summary), [provider](#provider), and [thumbnail](#thumbnail)
+A Manifest _MAY_ have the following properties: [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [placeholderContainer](#placeholderContainer), [accompanyingContainer](#accompanyingContainer), [viewingDirection](#viewingDirection), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [services](#services), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [start](#start), [canonical](#canonical), [via](#via), [structures](#structures), and [annotations](#annotations).
+{: .note}
+
+### Container Classes
+{: #Containers}
+
+A Container is a frame of reference that allows the relative positioning of content.
+
+All Containers _MUST_ be identified by a URI and it _MUST_ be an HTTP(S) URI. The URI of the Container _MUST NOT_ contain a fragment (a `#` followed by further characters), as this would make it impossible to refer to a segment of the Container's area using the [media fragment syntax][org-w3c-media-frags] of `#xywh=` for spatial regions, and/or `#t=` for temporal segments. The temporal segment _MUST_ be expressed using seconds. Containers _MAY_ be able to be dereferenced separately from the Manifest via their URIs as well as being embedded.
+
+Containers _MUST_ have an `items` property which is a list of Annotation Pages. Each Annotation Page, defined below, maintains a list of Annotations, which associate Content Resources to be rendered as part of the Container. Annotations that do not associate content to be rendered, but instead are about the Container such as a comment or tag, are recorded using Annotation Pages in the `annotations` property of the Container.
+
+For Timelines and Canvases, Annotations _MUST NOT_ target spatial or temporal points or regions outside of the bounds of the Container. For Scenes with a `duration`, Annotations _MUST NOT_ target temporal points or regions outside of that duration. Scenes, Canvases and other content with spatial extents _MUST NOT_ be annotated directly onto a Timeline which does not have a spatial extent. Resources with a `duration`, including Timelines and Canvases, _MAY_ be painted into Canvases and Scenes without a `duration`, however the playback of the resource will not able to be controlled or synchronized without other time-based media.
+
+__Properties__
+All Containers _MUST_ have the following properties: [id](#id), and [type](#type)
+All Containers _SHOULD_ have the following properties: [label](#label), and [items](#items)
+All Containers _MAY_ have the following properites: [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [placeholderContainer](#placeholderContainer), [accompanyingContainer](#accompanyingContainer), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+#### Timeline
+{: #Timeline}
+
+> `"type": "Timeline"`
+
+A Timeline is a Container that represents only a temporal duration, measured in seconds. Timelines allow audio content to be presented, but do not allow anything with a height or width like an image or video. The duration of the Timeline is given in the `duration` property.
+
+__Properties__
+A Timeline _MUST_ have the following additional properties: [duration](#duration).
+{: .note}
+
+#### Canvas
+{: #Canvas}
+
+> `"type": "Canvas"`
+
+A Canvas is a Container that represents a particular rectangular 2 dimensional view of the object and has content resources associated with it or with parts of it. This aspect ratio is defined by the `height` and `width` properties. The values of these properties are not pixels, but arbitrary square units into which pixel-based resources can be scaled. A Canvas _MAY_ also have a duration, given in the `duration` property, allowing audio and video to be correctly positioned in time as well as the 2 dimensional space.
+
+__Properties__
+A Canvas _MUST_ have the following additional properties: [height](#height), and [width](#width).
+A Canvas _MAY_ have the following additional properties: [duration](#duration).
+{: .note}
+
+
+#### Scene
+{: #Scene}
+
+> `"type": "Scene"`
+
+A Scene is a Container that represents an infinitely large three-dimensional space, with an optional `duration` property. Scenes have infinite height (y axis), width (x axis) and depth (z axis), where 0 on each axis (the origin of the coordinate system) is treated as the center of the scene's space. From a perspective looking along the z axis towards negative infinity, the positive y axis points upwards and the positive x axis points to the right (a [right-handed Cartesian coordinate system](https://en.wikipedia.org/wiki/Right-hand_rule)).
+
+
+
+The axes of the coordinate system are measured in arbitrary units. All axes use the same unit scaling and do not necessarily correspond to any physical unit of measurement, unless `spatialScale` is supplied.
+
+All resources that can be added to a Scene have an implicit (e.g. Lights, Cameras) or explicit (e.g. Models, Scenes), local coordinate space.
+
+__Properties__
+A Scene _MAY_ have the following additional properties: [duration](#duration).
+{: .note}
+
+
+### Annotation Classes
+{: #Annotations}
+
+The following set of classes are defined by the W3C's [Web Annotation Data Model][org-w3c-webanno] and Vocabulary, and are heavily used within the IIIF Data Model. Any necessary deviations from those specifications are explicitly noted and explained, such as the need for internationalization of labels.
+
+#### Annotation
+{: #Annotation}
+
+> `"type": "Annotation"`
+
+Annotations are used to associate content resources with Containers, as well as for transcriptions, commentary, tags and the association of other content. This provides a single, unified method for aligning information, and provides a standards-based framework for distinguishing parts of resources and parts of Canvases.
+
+An Annotation _MUST_ have an HTTP(S) URI given in `id`. The JSON-LD description of the Annotation _SHOULD_ be returned if the URI is dereferenced, according to the [Web Annotation Protocol][org-w3c-webanno-protocol].
+
+When Annotations are used to associate content resources with a Canvas, the content resource is linked in the `body` of the Annotation. The URI of the Canvas _MUST_ be repeated in the `target` property of the Annotation, or the `source` property of a Specific Resource used in the `target` property. Content that is to be rendered as part of the Container _MUST_ be associated by an Annotation that has the `motivation` value `painting`.
+
+Annotations _SHOULD NOT_ use the `bodyValue` property defined by the Web Annotation Data Model, but instead use the more consistent TextualBody class.
+
+__Properties__
+An Annotation _MUST_ have the following properties: [id](#id), [type](#type), [target](#target), [motivation](#motivation).
+An Annotation _SHOULD_ have the following properties: [body](#body).
+An Annotation _MAY_ have the following properties: [label](#label), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [provides](#provides), [behavior](#behavior), [timeMode](#timeMode), [stylesheet](#stylesheet), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [canonical](#canonical), and [via](#via).
+{: .note}
+
+
+#### Annotation Collection
+{: #AnnotationCollection}
+
+> `"type": "AnnotationCollection"`
+
+Annotation Collections allow groups of Annotations to be recorded. For example, all of the English translation Annotations of a medieval French document could be kept separate from the transcription or an edition in modern French, or the director's commentary on a film can be separated from the script.
+
+Annotation Collections _MUST_ have an HTTP(S) URI. The JSON-LD description _SHOULD_ be returned if the URI is dereferenced.
+
+Annotation Collections are always paged using `first` and `last`, rather than `items` as with IIIF Collections.
+
+__Properties__
+An Annotation Collection _MUST_ have the following properties: [id](#id), [type](#type), [label](#label), [first](#first), and [last](#last).
+An Annotation Collection _SHOULD_ have the following properties: [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail).
+An Annotation Collection _MAY_ have the following properties: [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [placeholderContainer](#placeholderContainer), [accompanyingContainer](#accompanyingContainer), [viewingDirection](#viewingDirection), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [services](#services), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [start](#start), [first](#first), [last](#last), [total](#total), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+#### Annotation Page
+{: #AnnotationPage}
+
+> `"type": "AnnotationPage"`
+
+An ordered list of Annotations, typically associated with a Container, but may be referenced from other types of resource as well. Annotation Pages enumerate and order lists of Annotations, in the same way that Collection Pages order lists of Manifests and Collections within the containing Collection.
+
+An Annotation Page _MUST_ have an HTTP(S) URI given in `id`. The Annotations are listed in the `items` property of the Annotation Page.
+
+__Properties__
+An Annotation Page _MUST_ have the following properties: [id](#id), [type](#type), and [items](#items)
+An Annotation Page _SHOULD_ have the following properties: [next](#next), [prev](#prev), and [partOf](#partOf)
+An Annotation Page _MAY_ have the following properties: [label](#label), [startIndex](#startIndex), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+#### Specific Resource
+{: #SpecificResource}
+
+> `"type": "SpecificResource"`
+
+A Specific Resource is a resource in the context of an Annotation. They are used to record further properties or relationships needed to understand the particular contextual use, such as which part of the resource is used or how it should be rendered. In IIIF, the Specific Resource model from the Web Annotation Data Model has some additional properties beyond those defined by the W3C, such as `transform` and `position`.
+
+A Specific Resource _MUST_ have an HTTP(S) URI given in `id`. This allows for it to be addressed by other parts of the model, such as Content State Annotations.
+
+__Properties__
+A Specific Resource _MUST_ have the following properties: [id](#id), [type](#type), [source](#source)
+A Specific Resource _SHOULD_ have the following properties: [selector](#selector)
+A Specific Resource _MAY_ have the following properties: [position](#position), [transform](#transform), [scope](#scope), [styleClass](#styleClass), [height](#height), [width](#width), [duration](#duration), [language](#language), [label](#label), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+#### Textual Body
+{: #TextualBody}
+
+> `"type": "TextualBody"`
+
+A Textual Body is an embedded resource within an Annotation that carries, as the name suggests, a text as the body of the Annotation. It is defined by the Web Annotation Data Model, and this specification defines a new property for `position` that allows it to be positioned within a Container.
+
+
+__Properties__
+A Textual Body _MUST_ have the following properties: [type](#type), [value](#value)
+A Specific Resource _MAY_ have the following properties: [id](#id), [position](#position), [transform](#transform), [scope](#scope), [styleClass](#styleClass), [height](#height), [width](#width), [duration](#duration), [language](#language), [format](#format), [label](#label), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+#### Choice
+{: #Choice}
+
+> `"type": "Choice"`
+
+A Choice is a Web Annotation construction that allows one entry from a list to be selected for processing or display.
+The client may use any method to determine which item to select, including presenting the Choice to the user for a decision or using the properties of the items to make the decision. In the absence of any information, the client _SHOULD_ select the first item in the array and publishers _SHOULD_ list the items in order of preference. This specification allows `behavior` and other properties to be added to a Choice to influence how it is processed.
+
+A Choice _SHOULD_ have a `label` in order to present the choice to the user, along with its items.
+
+__Properties__
+A Choice _MUST_ have the following properties: [type](#type), [items](#items)
+A Choice _SHOULD_ have the following properties: [label](#label)
+A Choice _MAY_ have the following properties: [id](#id), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [behavior](#behavior), and [seeAlso](#seeAlso).
+{: .note}
+
+
+### Content Resources
+{: #ContentResources}
+
+Content Resources are resources on the Web such as images, audio, video, 3d models, or text which can be associated with a Container via an Annotation, or be used with `thumbnail`, `rendering` or similar properties.
+
+Content Resources _MUST_ have an HTTP(s) given in `id`. It _MUST_ be able to be dereferenced to retrieve the representation of the Content Resource.
+
+If the Content Resource is an Image, and a IIIF Image service is available for it, then the `id` property of the Content Resource _MAY_ be a complete URI to any particular representation supported by the Image Service, such as `https://example.org/image1/full/1000,/0/default.jpg`, but _MUST NOT_ be just the URI of the Image Service. The Image _SHOULD_ have the service referenced from it using the `service` property.
+
+If the Content Resource is a 3d Model, then regardless of the file format, it is treated as being within an infinitely large three dimensional space with an origin (0 on all three axes).
+
+If there is a need to distinguish between Content Resources, then the resource _SHOULD_ have the `label` property.
+
+Containers _MAY_ be treated as content resources for the purposes of annotating on to other Containers. In this situation, the Container _MAY_ be [embedded][prezi30-terminology] within the Annotation, be a reference within the same Manifest, or require dereferencing to obtain its description.
+
+__Properties__
+A Content Resource _MUST_ have the following properties: [id](#id), and [type](#type)
+A Content Resource _SHOULD_ have the following properties: [label](#label)
+A Content Resource _MAY_ have the following properties: [height](#height), [width](#width), [duration](#duration), [language](#language), [format](#format), [fileSize](#fileSize),[metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [behavior](#behavior), [profile](#profile), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+### Selectors
+{: #Selectors}
+
+The Web Annotation Data Model defines several Selectors, which describe how to find a specific segment of that resource to be used. As noted, the nature of Selectors are dependent on the type of resources that they select out of, and the methods needed for those descriptions will vary. The Selectors from the Web Annotation Data Model and other sources can be used within the IIIF Data Model. This specification defines additional Selector classes for use.
+
+#### FragmentSelector
+{: #FragmentSelector}
+
+> `"type": "FragmentSelector"`
+
+Fragment Selectors use the fragment part of the URI specification to define a selection mechanism for parts of resources. The definition of the representation's media type specifies the structure of the value of the fragment. This is commonly used in IIIF to include the media fragment syntax of `xywh=,,,` to define a 2 dimension region.
+
+For more information about Fragment Selectors, see the [Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#fragment-selector).
+
+__Properties__
+A Fragment Selector _MUST_ have the following properties: [type](#type), and [value](#value)
+A Fragment Selector _MAY_ have the following properties: [id](#id) and [conformsTo](#conformsTo).
+{: .note}
+
+
+#### SvgSelector
+{: #SvgSelector}
+
+> `"type": "SvgSelector"`
+
+SVG Selectors use the [SVG specification](https://www.w3.org/TR/SVG11/) to define a non-rectangular part of a resource. This allows for polygons, circles and multiple shapes to be used to highlight or otherwise select regions of images or other 2 dimensional resources.
+
+For more information about SVG Selectors, see the [Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#svg-selector).
+
+__Properties__
+An SVG Selector _MUST_ have the following properties: [type](#type), and [value](#value).
+A Fragment Selector _MAY_ have the following properties: [id](#id).
+{: .note}
+
+
+#### Point Selector
+{: #PointSelector}
+
+> `"type": "PointSelector"`
+
+There are common use cases in which a point, rather than a range or area, is the target of the Annotation. For example, putting a pin in a map should result in an exact point, not a very small rectangle. Points in time are not very short durations, and user interfaces should, equally, treat these differently. This is particularly important when zooming in (either spatially or temporally) beyond the scale of the frame of reference.
+
+If `instant` is not supplied, and the target resource has a `duration`, the selector is interpreted as targeting the entire duration. If `instant` is supplied, but no spatial point, the selector is interpreted as targeting the entire spatial aspect of the resource.
+
+__Properties__
+A Point Selector _MUST_ have the following properties: [type](#type)
+A Point Selector _MAY_ have the following properties: [id](#id), [x](#x), [y](#y), [z](#z), and [instant](#instant).
+{: .note}
+
+```json
+{
+ "id": "https://example.org/selectors/1",
+ "type": "PointSelector",
+ "x": 0.001,
+ "y": 12.3,
+ "z": 0,
+ "instant": 180.0
+}
+```
+
+
+#### WKT Selector
+{: #WktSelector}
+
+> `"type": "WktSelector"`
+
+Well-known text, or WKT, is an ISO standard method for describing 2 and 3 dimensional geometries. This selector thus goes beyond what the Web Annotation's SvgSelector enables by incorporating the z axis, as well as additional types of selection such as MULTIPOLYGON. Additional types, such as CIRCULARSTRING may also be supported.
+
+The text representation is given in the `value` property of the selector.
+
+__Properties__
+A WKT Selector _MUST_ have the following properties: [type](#type), and [value](#value).
+A WKT Selector _MAY_ have the following properties: [id](#id)
+{: .note}
+
+```json
+{
+ "id": "https://example.org/selectors/2",
+ "type": "WktSelector",
+ "value": "POLYGON Z (0 0 0, 10 0.5 3.2 10 5.0 0, 0 0 0)"
+}
+```
+
+#### Audio Content Selector
+{: #AudioContentSelector}
+
+> `"type": "AudioContentSelector"`
+
+Video content resources consist of both visual and audio content within the same bit-level representation. There are situations when it is useful to refer to only one aspect of the content – either the visual or the audio, but not both. For example, an Annotation might associate only the visual content of a video that has spoken English in the audio, and an audio file that has the translation of that content in Spanish. The Audio Content Selector selects all of the audio content from an A/V content resource, and may be further refined with subsequent selectors to select a segment of it.
+
+__Properties__
+An Audio Content Selector _MUST_ have the following properties: [type](#type).
+An Audio Content Selector _MAY_ have the following properties: [id](#id)
+{: .note}
+
+```json
+{
+ "id": "https://example.org/selectors/3",
+ "type": "AudioContentSelector"
+}
+```
+
+
+#### Visual Content Selector
+{: #VisualContentSelector}
+
+> `"type": "VisualContentSelector"`
+
+Similar to Audio Content Selectors, Visual Content Selectors select the visual aspects of the content of an A/V content resource. They may be further refined by subsequent selectors that select an area or temporal segment of it.
+
+```json
+{
+ "id": "https://example.org/selectors/4",
+ "type": "VisualContentSelector"
+}
+```
+
+__Properties__
+A Visual Content Selector _MUST_ have the following properties: [type](#type).
+A Visual Content Selector _MAY_ have the following properties: [id](#id)
+{: .note}
+
+
+#### Animation Selector
+{: #AnimationSelector}
+> `"type": "AnimationSelector"`
+
+More interactive content resources, such as 3D models, may have animations or similar features that can be _activated_ by user interaction. For example, a model of a box might have an animation that opens the lid and a second animation that closes the lid. In order to activate those animations, they need to be selectable, and thus the specification defines an Animation Selector. The identity of the activatable aspect is given in the `value` property.
+
+__Properties__
+An Animation Selector _MUST_ have the following properties: [id](#id), [type](#type), and [value](#value).
+An Animation Selector _MAY_ have the following properties: [id](#id)
+{: .note}
+
+```json
+{
+ "id": "https://example.org/selectors/5",
+ "type": "AnimationSelector",
+ "value": "opening-1"
+}
+```
+
+#### IIIF Image API Selector
+{: #ImageApiSelector}
+> `"type": "ImageApiSelector"`
+
+The Image API Selector is used to describe the operations available via the IIIF Image API in order to retrieve a particular image representation. In this case the resource is the abstract image as identified by the [IIIF Image API][image-api] base URI plus identifier, and the retrieval process involves adding the correct parameters after that base URI.
+
+The Image API Selector has properties following the parameters from the API, and record the values needed to fill out the URL structure in the request. If the property is not given, then a default should be used.
+
+| Property | Default | Description |
+| -------- | --------- | ----------------------------------------------------- |
+| region | "full" | The string to put in the region parameter of the URI. |
+| size | "max" | The string to put in the size parameter of the URI. If used with a version 2.0 Image API server, the default should be considered to be "full". |
+| rotation | "0" | The string to put in the rotation parameter of the URI. Note that this must be a string in order to allow mirroring, for example "!90". |
+| quality | "default" | The string to put in the quality parameter of the URI. |
+| format | "jpg" | The string to put in the format parameter of the URI. Note that the '.' character is not part of the format, just the URI syntax. |
+
+
+
+__Properties__
+A IIIF Image API Selector _MUST_ have the following properties: [type](#type).
+A IIIF Image API Selector _MAY_ have the following properties: [id](#id), [region](#region), [size](#size), [rotation](#rotation), [quality](#quality), [format](#format).
+{: .note}
+
+```json
+{
+ "id": "https://example.org/selectors/6",
+ "type": "ImageApiSelector",
+ "region": "0,0,256,256",
+ "rotation": "90"
+}
+```
+
+### Range
+{: #Range}
+> `"type": "Range"`
+
+Ranges are used to represent structure within a Manifest beyond the default order of the Containers in the `items` property.
+
+Ranges _MUST_ have an HTTP(s) given in `id`. Top level Ranges are embedded or externally referenced within the Manifest in a `structures` property. These top level Ranges then embed or reference other Ranges, Containers or parts of Containers in the `items` property. Each entry in the `items` property _MUST_ be a JSON object, and it _MUST_ have the `id` and `type` properties. If a top level Range needs to be dereferenced by the client, then it _MUST NOT_ have the `items` property, such that clients are able to recognize that it should be retrieved.
+
+The included Containers and parts of Containers need not be contiguous or in the same order as in the Manifest's `items` property or any other Range. Examples include newspaper articles that are continued in different sections, a chapter that starts half way through a page, or time segments of a single canvas that represent different sections of a piece of music.
+
+__Properties__
+A Range _MUST_ have the following properties: [id](#id), and [type](#type).
+A Range _SHOULD_ have the following properties: [label](#label), and [items](#items)
.
+A Range _MAY_ have the following properties: [start](#start), [supplementary](#supplementary), [metadata](#metadata), [summary](#summary), [provider](#provider), [thumbnail](#thumbnail), [requiredStatement](#requiredStatement), [rights](#rights), [navDate](#navDate), [navPlace](#navPlace), [placeholderContainer](#placeholderContainer), [accompanyingContainer](#accompanyingContainer), [viewingDirection](#viewingDirection), [behavior](#behavior), [seeAlso](#seeAlso), [service](#service), [homepage](#homepage), [rendering](#rendering), [partOf](#partOf), [canonical](#canonical), [via](#via), and [annotations](#annotations).
+{: .note}
+
+
+### Scene Components
+{: #scene-components}
+
+The following classes are typically used within Scenes. They might have utility in other contexts, however those uses have not been defined in this specification.
+
+#### Cameras
+{: #Camera}
+
+A Camera provides a view of a region of a Scene's space from a particular position within the Scene; the client constructs a viewport into the Scene and uses the Camera to render that region. The size and aspect ratio of the viewport is client and device dependent. The first Camera defined in a Scene without the `hidden` behavior is the default Camera.
+
+If either the position or direction is not specified, then the position defaults to the origin of the Scene, and the direction defaults to pointing along the z axis towards negative infinity.
+
+__Properties__
+All Cameras _MUST_ have the following properties: [type](#type).
+All Cameras _MAY_ have the following properties: [id](#id), [label](#label), [lookAt](#lookAt), [near](#near), and [far](#far)
+{: .note}
+
+
+##### Orthographic Camera
+{: #OrthographicCamera}
+
+> `"type": "OrthographicCamera"`
+
+An Orthographic Camera removes visual perspective, resulting in object size remaining constant regardless of its distance from the camera.
+
+__Properties__
+Orthographic Cameras _SHOULD_ have the following additional properties: [viewHeight](#viewHeight).
+{: .note}
+
+```json
+{
+ "id": "https://example.org/iiif/camera/1",
+ "type": "OrthographicCamera",
+ "near": 1.0,
+ "far": 100.0,
+ "viewHeight": 40.0
+}
+```
+
+
+##### Perspective Camera
+{: #PerspectiveCamera}
+> `"type": "PerspectiveCamera"`
+
+A Perspective Camera mimics the way the human eye sees, in that objects further from the camera are smaller.
+
+The region of the Scene's space that is observable by the camera is bounded by two planes orthogonal to the direction the camera is facing, given in the `near` and `far` properties, and a vertical projection angle that provides the top and bottom planes of the region in the `fieldOfView` property.
+
+
+
+__Properties__
+Perspective Cameras _SHOULD_ have the following additional properties: [fieldOfView](#fieldOfView).
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/camera/2",
+ "type": "PerspectiveCamera",
+ "near": 1.0,
+ "far": 100.0,
+ "fieldOfView": 45.0
+}
+```
+
+#### Lights
+{: #Light}
+
+It is necessary for there to be a Light within a Scene that illuminates the objects. If no Light is provided by the Scene's description, then the client _MUST_ provide default lighting.
+
+This specification does not define other aspects of Lights, such as the rate of decay of the intensity of the light over a distance, the maximum range of the light, or the penumbra of a cone. Implementation of these aspects is client-dependent.
+
+The specification defines four types of Light, below.
+
+__Properties__
+All Lights _MUST_ have the following properties: [type](#type).
+All Lights _SHOULD_ have the following properties: [color](#color), and [intensity](#intensity).
+All Lights _MAY_ have the following properties: [id](#id), and [label](#label).
+{: .note}
+
+
+##### Ambient Light
+{: #AmbientLight}
+> `"type": "AmbientLight"`
+
+Ambient Light evenly illuminates all objects in the Scene, and does not have a direction or position. It does not have any new properties. The Light itself _MUST_ be added into the scene at a specific position, however this is only such that editing interfaces can render the object to the user.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/light/1",
+ "type": "AmbientLight",
+ "color": "#F0A0F0",
+}
+```
+
+##### Directional Light
+{: #DirectionalLight}
+> `"type": "DirectionalLight"`
+
+Directional Lights emit their light in a specific direction as if infinitely far away, and as such the light does not come from a specific position. The rays produced are all parallel. The Light itself _MUST_ be added into the scene at a specific position, however this is only such that editing interfaces can render the object to the user.
+
+The light is emitted in the negative Y direction by default, thus straight down, but the orientation of the light can be altered with `lookAt` or with a `RotationTransform`.
+
+__Properties__
+Directional Lights _MAY_ have the following additional properties: [lookAt](#lookAt)
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/light/2",
+ "type": "DirectionalLight",
+ "color": "#A0A0F0",
+ "lookAt": {"id": "https://example.org/iiif/annotations/models/1"}
+}
+```
+
+##### Point Light
+{: #PointLight}
+> `"type": "PointLight"`
+
+Point Lights emit in all directions from a single point within the Scene.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/light/3",
+ "type": "PointLight",
+ "color": "#A0F0F0"
+}
+```
+
+
+##### Spot Light
+{: #SpotLight}
+> `"type": "SpotLight"`
+
+Spot Light emits a cone of light in a given direction from a single point. The Spot Light's `angle` property defines the radius of the cone. The default angle is client dependent if not specified.
+
+The Spot Light emits in the negative Y direction by default, but the orientation of the light can be altered by subsequent transforms, or by setting the `lookAt` property.
+
+
+
+__Properties__
+Spot Lights _SHOULD_ have the following additional properties: [angle](#angle)
+Spot Lights _MAY_ have the following additional properties: [lookAt](#lookAt)
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/spotlight/1",
+ "type": "SpotLight",
+ "angle": 15.0,
+ "color": "#FFFFFF",
+ "intensity": {
+ "id": "https://example.org/iiif/spotlight/1/value",
+ "type": "Quantity",
+ "unit": "relative",
+ "quantityValue": 0.5
+ }
+}
+```
+
+#### Audio Emitters
+{: #AudioEmitters}
+
+Audio is supported through the use of Audio Emitter resources annotated into Scenes, in the same way that light is emitted from the various subclasses of Light.
+
+As the audio content must come from an audio resource, the Audio Emitter classes are subclasses of SpecificResource. Note that the `source` of the Audio could be a Timeline, or could be further constrained with additional specifiers as to start point, end point or other transformations.
+
+Volume is given relative to the input audio content's volume, and thus a volume of 1.0 is the volume as provided, 0.5 is half the volume, and 2.0 is double the volume.
+
+__Properties__
+All Audio Emitters _MUST_ have the following properties: [type](#type) and [source](#source).
+All Audio Emitters _SHOULD_ have the following properties: [volume](#volume).
+All Audio Emitters _MAY_ have the following properties: [id](#id) and [label](#label).
+{: .note}
+
+##### Ambient Audio
+{: #AmbientAudio}
+> `"type": "AmbientAudio"`
+
+Ambient Audio emits equally throughout the Scene, and does not have a position or direction. The Emitter _MUST_ be annotated somewhere within the Scene so that it can be rendered by editing interfaces, and exists within the Scene's hierarchy.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/audio/1",
+ "type": "AmbientAudio",
+ "source": {
+ "id": "https://example.org/media/path/to/my.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ }
+}
+```
+
+##### Point Audio
+{: #PointAudio}
+> `"type": "PointAudio"`
+
+Point Audio emits in all directions from a single point in the Scene.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/audio/2",
+ "type": "PointAudio",
+ "source": {
+ "id": "https://example.org/media/path/to/my.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ }
+}
+```
+
+##### Spot Audio
+{: #SpotAudio}
+
+> `"type": "SpotAudio"`
+
+Spot Audio emits a cone of sound in a given direction from a single point. The Spot Audio's `angle` property defines the radius of the cone. The default angle is client dependent if not specified.
+
+The Spot Audio emits in the negative Y direction by default, but the orientation of the sound can be altered by subsequent transforms, or by setting the `lookAt` property.
+
+__Properties__
+Spot Audio Emitters _SHOULD_ have the following additional properties: [angle](#angle)
+Spot Audio Emitters _MAY_ have the following additional properties: [lookAt](#lookAt)
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/audio/3",
+ "type": "SpotAudio",
+ "source": {
+ "id": "https://example.org/media/path/to/my.mp3",
+ "type": "Audio",
+ "format": "audio/mp3"
+ },
+ "angle": 45.0,
+ "volume": {
+ "id": "https://example.org/iiif/value/1",
+ "type": "Quantity",
+ "unit": "relative",
+ "quantityValue": 1.0
+ }
+}
+```
+
+#### Transforms
+{: #Transforms}
+
+An operation to apply a transformation to a resource. Transforms are specified by the [transform](#transform) property on a Specific Resource. In the context of Scenes, transforms are carried out on a resource in the implicit or explicit local coordinate space of the resource, and are performed prior to painting that resource into any subsequent coordinate space.
+
+__Properties__
+All Transforms _MUST_ have the following properties: [type](#type).
+All Transforms _MAY_ have the following properties: [id](#id), [label](#label), [x](#x), [y](#y), and [z](#z).
+{: .note}
+
+##### Rotate Transform
+{: #RotateTransform}
+> `"type": "RotateTransform"`
+
+A Rotate Transform rotates the resource around one or more axes. If present, the values of properties `x`, `y`, and `z` _MUST_ be angular values in degrees that specify the extent of rotation around each axis. Positive angular values indicate counter-clockwise rotation around the axis due to coordinate right-handedness. Axis rotation is performed with a pivot point at the origin of the local coordinate space. As an example, for a point at (1, 1, 0) in local coordinate space, rotating 90 degrees around the x axis would transform the point to be at (1, 0, 1). If any property `x`, `y`, or `z` is not specified or is specified to be 0.0, rotation around that axis does not occur. When more than one axis rotation is specified through multiple non-zero values for `x`, `y`, and `z`, rotations comprise a Euler angle with ordering x-y-z, and rotation _MUST_ be carried out first around the x axis, second around the y axis, and third around the z axis.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/transform/1",
+ "type": "RotateTransform",
+ "x": 0.0,
+ "y": 180.0,
+ "z": 0.0
+}
+```
+
+##### Scale Transform
+{: #ScaleTransform}
+> `"type": "ScaleTransform"`
+
+A Scale Transform scales the resource along one or more axes. If present, the values of properties `x`, `y`, and `z` _MUST_ be multiplicative scale factors that specify the extent of scaling along each axis. As an example, for a point at 3.5 along the x axis in local coordinate space, scaling along the x axis by 2.0 would result in the point being at 7.0. If any property `x`, `y`, or `z` is not specified or is specified to be 1.0, scaling does not occur along that axis. Negative scale factor values indicate mirroring as well as scaling along that axis.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/transform/2",
+ "type": "ScaleTransform",
+ "x": 2.0,
+ "y": 2.0,
+ "z": 2.0
+}
+```
+
+##### Translate Transform
+{: #TranslateTransform}
+> `"type": "TranslateTransform"`
+
+A Translate Transform translates or moves the resource across one or more axes. If present, the values of properties `x`, `y`, and `z` _MUST_ be coordinate unit distances that specify the distance across each axis to translate the resource. As an example, for a point at 1.0 along the x axis, translating across the x axis by 3.0 would result in the point being at 4.0. If any property `x`, `y`, or `z` is not present or is specified to be 0.0, translation does not occur across that axis.
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/transform/3",
+ "type": "TranslateTransform",
+ "x": -1.0,
+ "y": 0.0,
+ "z": 0.0
+}
+```
+
+### Utility Classes
+{: #utility-classes}
+
+#### Agent
+{: #Agent}
+> `"type": "Agent"`
+
+An Agent represents a person or organization, typically referenced with the `provider` property.
+The Agent is not intended to be used as a primary identifier for the person or organization, nor to provide structured metadata, but instead to ensure that the information to be rendered to the user can be kept together in the situation when there are multiple agents being referenced.
+
+__Properties__
+An Agent _MUST_ have the following properties: [type](#type) and [label](#label).
+An Agent _SHOULD_ have the following properties: [homepage](#homepage) and [logo](#logo)
.
+An Agent _MAY_ have the following properties: [id](#id), [seeAlso](#seeAlso) and [summary](#summary).
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/agent/1",
+ "type": "Agent",
+ "label": {"en": ["IIIF Consortium"]},
+ "summary": {"en": ["The IIIF Consortium is a global community of organizations and individuals working to develop and promote the International Image Interoperability Framework (IIIF)."]},
+ "homepage": [
+ {
+ "id": "https://iiif.io/",`
+ "type": "Text",
+ "label": {"en": ["IIIF Home Page"]},
+ "format": "text/html"
+ }
+ ],
+ "logo": [
+ {
+ "id": "https://iiif.io/assets/images/logos/logo-sm.png",
+ "type": "Image",
+ "format": "image/png",
+ "height": 30,
+ "width": 34
+ }
+ ]
+}
+```
+
+
+#### Service
+{: #Service}
+
+> `"type": "Service"`
+
+A Service is an external software application that a client might interact with to gain additional information or functionality for the resource that is associated with the Service. The IIIF Image API is an example of a Service, as are the Auth API services. Known types of Service are registered in the Service Registry.
+
+For cross-version consistency, this specification defines the following values for the `type` or `@type` property for backwards compatibility with other IIIF APIs. Future versions of these APIs will define their own types. These `type` values are necessary extensions for compatibility of the older versions.
+
+| Value | Specification |
+| -------------------- | ------------- |
+| ImageService1 | [Image API version 1][image11] |
+| ImageService2 | [Image API version 2][image21] |
+| SearchService1 | [Search API version 1][search1] |
+| AutoCompleteService1 | [Search API version 1][search1-autocomplete] |
+| AuthCookieService1 | [Authentication API version 1][auth1-cookie-service] |
+| AuthTokenService1 | [Authentication API version 1][auth1-token-service] |
+| AuthLogoutService1 | [Authentication API version 1][auth1-logout-service] |
+{: .api-table #table-service-types}
+
+Implementations _SHOULD_ be prepared to recognize the `@id` and `@type` property names used by older specifications, as well as `id` and `type`. Note that the `@context` key _SHOULD NOT_ be present within the `service`, but instead included at the beginning of the document.
+
+__Properties__
+A Service _MUST_ have the following properties: [id](#id), and [type](#type).
+A Service _SHOULD_ have the following properties: [label](#label), [profile](#profile).
+A Service _MAY_ have the following properties: [service](#service), `@id` and `@type`.
+Services will also have specific requirements as to additional properties based on the type of service.
+{: .note}
+
+
+#### Quantity
+{: #Quantity}
+
+> `"type": "Quantity"`
+
+A Quantity expresses a quantity through a numerical value and associated unit of measurement. The value of `unit` _MUST_ be drawn from the list of possible units, or a registered extension. The definition of `unit` defines the [list of possible units](#unit).
+
+__Properties__
+A Quantity _MUST_ have the following properties: [type](#type), [quantityValue](#value), and [unit](#unit).
+A Quantity _MAY_ have the following properties: [id](#id) and [label](#label).
+{: .note}
+
+{% include api/code_header.html %}
+```json
+{
+ "id": "https://example.org/iiif/unit/2",
+ "type": "Quantity",
+ "quantityValue": 1.0,
+ "unit": "m"
+}
+```
+
+
+## Properties
+{: #properties}
+
+### accompanyingContainer
+{: #accompanyingContainer}
+
+A Container that provides additional content for use while the resource that has the `accompanyingContainer` property is shown or played. Examples include an image to show while a duration-only Canvas is playing audio; or background audio to play while a user is navigating an image-only Manifest.
+
+Clients _MAY_ display the content of an accompanying Container when presenting the resource. As with `placeholderContainer` above, when more than one accompanying Container is available, the client _SHOULD_ pick the one most specific to the content. Publishers _SHOULD NOT_ assume that the accompanying Container will be processed by all clients. Clients _SHOULD_ take care to avoid conflicts between time-based media in the accompanying Container and the content of the resource that has the `accompanyingContainer` property.
+
+The value of `accompanyingContainer` _MUST_ be a JSON object with the `id` and `type` properties. The value of `type` _MUST_ be a Container type. The JSON object _MAY_ have other properties valid for that Container type.
+
+ * A Collection _MAY_ have the `accompanyingContainer` property.
+ Clients _MAY_ render `accompanyingContainer` on a Collection.
+ * A Manifest _MAY_ have the `accompanyingContainer` property.
+ Clients _MAY_ render `accompanyingContainer` on a Manifest.
+ * All Container types _MAY_ have the `accompanyingContainer` property.
+ Clients _MAY_ render `accompanyingContainer` on Containers.
+ * A Range _MAY_ have the `accompanyingContainer` property.
+ Clients _MAY_ render `accompanyingContainer` on a Range.
+ * Other types of resource _MUST NOT_ have the `accompanyingContainer` property.
+ Clients _SHOULD_ ignore `accompanyingContainer` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "accompanyingContainer": {
+ "id": "https://example.org/iiif/1/timeline/accompany",
+ "type": "Timeline",
+ "duration": 180.0
+ }
+}
+```
+
+### angle
+{: #angle}
+
+The `angle` property is used with SpotLights and Spot Audio Emitters to define the radius of the cone of emitted light or sound. Note that the `fieldOfView` property is defined as the entire field of view, not half (as might be inferred from `angle` using radius).
+
+The value _MUST_ be a floating point number greater than 0 and less than 90, and is measure in degrees. If this property is not specified, then the default value is client-dependent.
+
+* A SpotLight _SHOULD_ have the `angle` property.
+ Clients _SHOULD_ process the `angle` property on SpotLights.
+* A Spot Audio Emitter _SHOULD_ have the `angle` property.
+ Clients _SHOULD_ process the `angle` property on Spot Audio Emitters.
+
+{% include api/code_header.html %}
+```json
+ "angle": 15.0
+```
+
+### annotations
+{: #annotations}
+
+An ordered list of Annotation Pages that contain commentary or other Annotations about this resource, separate from the Annotations that are used to paint content on to a Container. The `motivation` of the Annotations _MUST NOT_ be `painting`, and the target of the Annotations _MUST_ include this resource, or part of it, or some resource within its `items` hierarchy.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have at least the `id` and `type` properties.
+
+ * A Collection _MAY_ have the `annotations` property with at least one item.
+ Clients _SHOULD_ process `annotations` on a Collection.
+ * A Manifest _MAY_ have the `annotations` property with at least one item.
+ Clients _SHOULD_ process `annotations` on a Manifest,.
+ * A Canvas _MAY_ have the `annotations` property with at least one item.
+ Clients _SHOULD_ process `annotations` on a Canvas.
+ * A Range _MAY_ have the `annotations` property with at least one item.
+ Clients _SHOULD_ process `annotations` on a Range.
+ * A content resource _MAY_ have the `annotations` property with at least one item.
+ Clients _SHOULD_ process `annotations` on a content resource.
+ * Other types of resource _MUST NOT_ have the `annotations` property.
+ Clients _SHOULD_ ignore `annotations` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "annotations": [
+ {
+ "id": "https://example.org/iiif/annotationPage/1",
+ "type": "AnnotationPage",
+ "items": [ { ... } ]
+ }
+ ]
+}
+```
+
+### backgroundColor
+{: #backgroundColor}
+
+This property sets the background color behind any painted resources on a spatial Container, such as a Canvas or Scene.
+
+The value _MUST_ be string, which defines an RGB color. It SHOULD be a hex value starting with "#" and is treated in a case-insensitive fashion. If this property is not specified, then the default value is client-dependent.
+
+ * A Canvas _MAY_ have the `backgroundColor` property
+ Clients _SHOULD_ render `backgroundColor` on any resource type.
+ * A Scene _MAY_ have the `backgroundColor` property
+ Clients _SHOULD_ render `backgroundColor` on any resource type.
+ * Other resources _MUST NOT_ have the `backgroundColor` property.
+
+{% include api/code_header.html %}
+```json-doc
+{ "backgroundColor": "#FFFFFF" }
+```
+
+### behavior
+{: #behavior}
+
+A set of user experience features that the publisher of the content would prefer the client to use when presenting the resource. This specification defines the values in the table below. Others may be defined externally as an [extension][prezi30-ldce].
+
+In order to determine the behaviors that are governing a particular resource, there are four inheritance rules from resources that reference the current resource:
+* Collections inherit behaviors from their referencing Collection.
+* Manifests **DO NOT** inherit behaviors from any referencing Collections.
+* Containers inherit behaviors from their referencing Manifest, but **DO NOT** inherit behaviors from any referencing Ranges, as there might be several with different behaviors.
+* Ranges inherit behaviors from any referencing Range and referencing Manifest.
+
+Clients should interpret behaviors on a Range only when that Range is selected or is in some other way the context for the user's current interaction with the resources. A Range with the `behavior` value `continuous`, in a Manifest with the `behavior` value `paged`, would mean that the Manifest's Containers should be rendered in a paged fashion, unless the range is selected to be viewed, and its included Containers would be rendered in that context only as being virtually stitched together. This might occur, for example, when a physical scroll is cut into pages and bound into a codex with other pages, and the publisher would like to provide the user the experience of the scroll in its original form.
+
+The descriptions of the behavior values have a set of which other values they are disjoint with, meaning that the same resource _MUST NOT_ have both of two or more from that set. In order to determine which is in effect, the client _SHOULD_ follow the inheritance rules above, taking the value from the closest resource. The user interface effects of the possible permutations of non-disjoint behavior values are client dependent, and implementers are advised to look for relevant recipes in the [IIIF cookbook][annex-cookbook].
+
+The value _MUST_ be an array of strings.
+
+ * Any resource type _MAY_ have the `behavior` property with at least one item.
+ Clients _SHOULD_ process `behavior` on any resource type.
+
+
+TODO: Address https://github.com/IIIF/api/issues/2318
+
+| Value | Description |
+| ----- | ----------- |
+|| **Temporal Behaviors** |
+| `auto-advance`{: style="white-space:nowrap;"} | Valid on Collections, Manifests, Containers, and Ranges that include or are Containers with at least the `duration` dimension. When the client reaches the end of a Canvas, or segment thereof as specified in a Range, with a duration dimension that has this behavior, it _SHOULD_ immediately proceed to the next Container or segment and render it. If there is no subsequent Container in the current context, then this behavior should be ignored. When applied to a Collection, the client should treat the first Container of the next Manifest as following the last Container of the previous Manifest, respecting any `start` property specified. Disjoint with `no-auto-advance`. |
+| `no-auto-advance`{: style="white-space:nowrap;"} | Valid on Collections, Manifests, Containers, and Ranges that include or are Containers with at least the `duration` dimension. When the client reaches the end of a Container or segment with a duration dimension that has this behavior, it _MUST NOT_ proceed to the next Container, if any. This is a default temporal behavior if not specified. Disjoint with `auto-advance`.|
+| `repeat` | Valid on Collections and Manifests, that include Containers that have at least the `duration` dimension. When the client reaches the end of the duration of the final Container in the resource, and the `behavior` value `auto-advance`{: style="white-space:nowrap;"} is also in effect, then the client _SHOULD_ return to the first Container, or segment of a Container, in the resource that has the `behavior` value `repeat` and start playing again. If the `behavior` value `auto-advance` is not in effect, then the client _SHOULD_ render a navigation control for the user to manually return to the first Container or segment. Disjoint with `no-repeat`.|
+| `no-repeat` | Valid on Collections and Manifests, that include Containers that have at least the `duration` dimension. When the client reaches the end of the duration of the final Container in the resource, the client _MUST NOT_ return to the first Container, or segment of Container. This is a default temporal behavior if not specified. Disjoint with `repeat`.|
+| | **Layout Behaviors** |
+| `unordered` | Valid on Collections, Manifests and Ranges. The resources included in resources that have this behavior have no inherent order, and user interfaces _SHOULD_ avoid implying an order to the user. Disjoint with `individuals`, `continuous`, and `paged`.|
+| `individuals` | Valid on Collections, Manifests, and Ranges. For Collections that have this behavior, each of the included Manifests are distinct objects in the given order. For Manifests and Ranges, the included Containers are distinct views, and _SHOULD NOT_ be presented in a page-turning interface. This is the default layout behavior if not specified. Disjoint with `unordered`, `continuous`, and `paged`. |
+| `continuous` | Valid on Collections, Manifests and Ranges, which include Canvases. Canvases included in resources that have this behavior are partial views and an appropriate rendering might display all of the Canvases virtually stitched together, such as a long scroll split into sections. This behavior has no implication for audio resources. The `viewingDirection` of the Manifest will determine the appropriate arrangement of the Canvases. Disjoint with `unordered`, `individuals` and `paged`. |
+| `paged` | Valid on Collections, Manifests and Ranges, which include Canvases. Canvases included in resources that have this behavior represent views that _SHOULD_ be presented in a page-turning interface if one is available. The first canvas is a single view (the first recto) and thus the second canvas likely represents the back of the object in the first canvas. If this is not the case, see the `behavior` value `non-paged`. Disjoint with `unordered`, `individuals`, and `continuous`. |
+| `facing-pages`{: style="white-space:nowrap;"} | Valid only on Canvases. Canvases that have this behavior, in a Manifest that has the `behavior` value `paged`, _MUST_ be displayed by themselves, as they depict both parts of the opening. If all of the Canvases are like this, then page turning is not possible, so simply use `individuals` instead. Disjoint with `non-paged`.|
+| `non-paged` | Valid only on Canvases. Canvases that have this behavior _MUST NOT_ be presented in a page-turning interface, and _MUST_ be skipped over when determining the page order. This behavior _MUST_ be ignored if the current Manifest does not have the `behavior` value `paged`. Disjoint with `facing-pages`. |
+| | **Collection Behaviors** |
+| `multi-part` | Valid only on Collections. Collections that have this behavior consist of multiple Manifests or Collections which together form part of a logical whole or a contiguous set, such as multi-volume books or a set of journal issues. Clients might render these Collections as a table of contents rather than with thumbnails, or provide viewing interfaces that can easily advance from one member to the next. Disjoint with `together`.|
+| `together` | Valid only on Collections. A client _SHOULD_ present all of the child Manifests to the user at once in a separate viewing area with its own controls. Clients _SHOULD_ catch attempts to create too many viewing areas. This behavior _SHOULD NOT_ be interpreted as applying to the members of any child resources. Disjoint with `multi-part`.|
+| | **Navigation Behaviors** |
+| `sequence` | Valid on Ranges, where the Range is [referenced][prezi30-terminology] in the `structures` property of a Manifest, and Annotation Collection Pages. Ranges that have this behavior represent different orderings of the Containers listed in the `items` property of the Manifest, and user interfaces that interact with this order _SHOULD_ use the order within the selected Range, rather than the default order of `items`. On an Annotation Collection Page, this behavior indicates that the Annotations within the Page are ...
+
+FIXME: do we define the processing model here?
+
+Disjoint with `thumbnail-nav` and `no-nav`.|
+| `thumbnail-nav`{: style="white-space:nowrap;"} | Valid only on Ranges. Ranges that have this behavior _MAY_ be used by the client to present an alternative navigation or overview based on thumbnails, such as regular keyframes along a timeline for a video, or sections of a long scroll. Clients _SHOULD NOT_ use them to generate a conventional table of contents. Child Ranges of a Range with this behavior _MUST_ have a suitable `thumbnail` property. Disjoint with `sequence` and `no-nav`.|
+| `no-nav` | Valid only on Ranges. Ranges that have this behavior _MUST NOT_ be displayed to the user in a navigation hierarchy. This allows for Ranges to be present that capture unnamed regions with no interesting content, such as the set of blank pages at the beginning of a book, or dead air between parts of a performance, that are still part of the Manifest but do not need to be navigated to directly. Disjoint with `sequence` and `thumbnail-nav`.|
+| | **Miscellaneous Behaviors** |
+| `hidden`{: #hidden-value} | Valid on Annotation Collections, Annotation Pages, Annotations, Specific Resources, Lights, Cameras and Choices. If this behavior is provided, then the client _SHOULD NOT_ render the resource by default, but allow the user to turn it on and off. This behavior does not inherit, as it is not valid on Collections, Manifests, Ranges or Canvases. |
+{: .api-table #table-behavior}
+
+{% include api/code_header.html %}
+``` json-doc
+{ "behavior": [ "auto-advance", "individuals" ] }
+```
+
+### body
+{: #body}
+
+The list of bodies of an Annotation. As there _MAY_ be more than one body, the value _MUST_ be an array, even though the W3C specification does not require this. The resources listed in `body` can be instances of `TextualBody`, `SpecificResource`, core Structural Resources, or Content Resources.
+
+Some Annotations do not have bodies at all. For example a highlighting annotation only needs to visually highlight the region targeted. Note that use of the W3C `bodyValue` property is prohibited in IIIF, and the `TextualBody` class _MUST_ be used instead.
+
+For more information about Annotation bodies, see the [W3C Annotation Model](https://www.w3.org/TR/annotation-model/#bodies-and-targets).
+
+The value _MUST_ be an array of JSON objects.
+
+* An Annotation _SHOULD_ have the `body` property.
+ Clients _MUST_ process the `body` property on Annotations.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "body": [ {"type": "TextualBody", "value": "Great!"} ] }
+```
+
+### canonical
+{: #canonical}
+
+The URI that SHOULD be used to track the resource's identity, regardless of where it is made accessible or its `id` property. The canonical URI can then be used as the target for annotations, regardless of the URI from which it was retrieved. If this property is set, then clients _MUST NOT_ change or delete it. Clients _MUST NOT_ assign a canonical URI if one is not present, as the resource might already have one assigned by a different system but it was not included in the representation received. Any reference to the `canonical` URI _MUST_ be treated as a reference to this resource.
+
+As the W3C model allows the property to be used on bodies and targets, and any resource _MAY_ be a body or target of an Annotation, this property _MAY_ be used on any resource in the IIIF specifications.
+
+For more information about `canonical`, see the [W3C Annotation Model](https://www.w3.org/TR/annotation-model/#other-identities).
+
+The value _MUST_ be a string, and the value must be an absolute HTTP(S) URI.
+
+* Any resource _MAY_ have the `canonical` property.
+ Clients _MAY_ process the `canonical` property on any resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "canonical": "https://example.org/annotations/123569" }
+```
+
+
+### color
+{: #color}
+
+This property sets the color of a Light.
+
+The value _MUST_ be string, which defines an RGB color. It SHOULD be a hex value starting with "#" and is treated in a case-insensitive fashion. If this property is not specified, then the default value is "#FFFFFF".
+
+ * A Light _SHOULD_ have the `color` property
+ Clients _SHOULD_ render `color` on any resource type.
+ * Other resources _MUST NOT_ have the `color` property.
+
+```json
+"color": "#FFA0A0"
+```
+
+### duration
+{: #duration}
+
+The duration of a container or external content resource, given in seconds.
+
+The value _MUST_ be a positive floating point number.
+
+ * A Timeline _MUST_ have the `duration` property.
+ Clients _MUST_ process `duration` on a Timeline.
+ * A Canvas or Scene _MAY_ have the `duration` property.
+ Clients _MUST_ process `duration` on a Canvas or Scene, if present.
+ * Content resources _SHOULD_ have the `duration` property, if appropriate to the resource type.
+ Clients _SHOULD_ process `duration` on content resources.
+ * Other types of resource _MUST NOT_ have a `duration`.
+ Clients _SHOULD_ ignore `duration` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "duration": 125.0 }
+```
+
+### exclude
+{: #exclude}
+
+Just as a Scene may contain multiple Annotations with model, light, and camera resources, a single 3D model file may contain a collection of 3D resources, including model geometry, assemblages of lights, and/or multiple cameras, with some of these potentially manipulated by animations. When painting Scenes or models that themselves may contain groups of resources within a single Scene, it may not always be appropriate to include all possible cameras, lights, or other resources, and it may be desirable to opt not to import some of these resources. This is accomplished through the Annotation property `exclude`, which prevents the import of audio, lights, cameras, or animations from a particular Scene or model prior to the Annotation being painted into a Scene. When `exclude` is used, the excluded resource type or functionality should not be loaded into the Scene, and it is not possible to reactivate or turn on these excluded resources after loading.
+
+| Value | Description |
+|------------|-------------|
+| Audio | Exclude all sound from resources, including audio tracks, audio emitters, and audio from video |
+| Animations | Exclude all definitions of animations from resources |
+| Cameras | Exclude all cameras from resources |
+| Lights | Exclude all lights from resources |
+
+The value of `exclude` is an array of strings, each of which is one of the values listed above. If the `exclude` property is not specified, then no resources are excluded.
+
+* An Annotation _MAY_ have the `exclude` property.
+ Clients _SHOULD_ process the `exclude` property.
+
+```json
+"exclude": [ "Audio", "Lights", "Cameras", "Animations" ]
+```
+
+### far
+{: #far}
+
+This property gives the distance along the axis of the camera's orientation after which objects are no longer visible. Objects further from the camera than the `far` distance cannot be seen.
+
+The value is a non-negative floating point number, in the coordinate space of the Scene in which the Camera is positioned. The value _MUST_ be greater than the value for `near` of the same Camera. If this property is not specified, then the default value is client-dependent.
+
+* A Camera _MAY_ have the `far` property
+ Clients _SHOULD_ process the `far` property on Cameras.
+
+```json-doc
+{ "far": 200.0 }
+```
+
+### fieldOfView
+{: #fieldOfView}
+
+The vertical projection angle from the top plane to the bottom plane of the camera's field of view, specified in degrees. The horizontal projection angle is dependent on the aspect ratio of the client's viewport.
+
+The value _MUST_ be a floating point number greater than 0 and less than 180, and is measured in degrees. If this property is not specified, then the default value is client-dependent.
+
+* A PerspectiveCamera _SHOULD_ have the `fieldOfView` property.
+ Clients _SHOULD_ process the `fieldOfView` property on Cameras.
+
+```json-doc
+{ "fieldOfView": 50.0 }
+```
+
+### fileSize
+
+The size of a content resource in bytes. This will allow clients to determine whether the resource should be retrieved in the user's current context. For example, the same 3d Model or AV file might be available in multiple formats, and the client can choose the most appropriate one based on the `fileSize` property.
+
+The value _MUST_ be a positive integer.
+
+* Any Content Resource _MAY_ have the `fileSize` property.
+ Clients _SHOULD_ process the `fileSize` property on Resources.
+
+```json-doc
+{ "fileSize": 132465987 }
+```
+
+### first
+{: #first}
+
+This property references the first Annotation Page within an Annotation Collection, or the first CollectionPage within a Collection. Note that Collections will only have the `first` property if there is a large number of items, more than could conveniently be included in a single page.
+
+The value _MUST_ be a JSON object with `id` and `type` properties. The `id` _MUST_ be the HTTP(S) URI of the referenced Annotation or Collection Page. The value of `type` _MUST_ be `AnnotationPage` or `CollectionPage`.
+
+* A non-empty AnnotationCollection _MUST_ have the `first` property.
+ Clients _MUST_ process the `first` property on an AnnotationCollection.
+* A non-empty Collection _MAY_ have the `first` property.
+ Clients _MUST_ process the `first` property on a Collection.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "first": {
+ "id": "https://example.org/iiif/annotationPage/1",
+ "type": "AnnotationPage"
+ }
+}
+```
+
+
+### format
+{: #format}
+
+For Content resources, the `format` property records the specific media type (often called a MIME type) for a content resource, for example `image/jpeg`. This is important for distinguishing different formats of the same overall type of resource, such as distinguishing text in XML from plain text. The value of the property should thus be the same as the value of the `Content-Type` header returned when the URI of the Content Resource is dereferenced.
+
+For the IIIF Image API Selector class however, the value of `format` is the parameter to use in the Image API URL construction, and thus to request a jpeg image, the value would be `jpg` instead.
+
+The value _MUST_ be a string, and _SHOULD_ either be a valid media type or an image extension format valid for the IIIF Image Api.
+
+ * A content resource _SHOULD_ have the `format` property.
+ Clients _MAY_ render the `format` of any content resource.
+ * A IIIF Image API Selector class _SHOULD_ have the `format` property.
+ Clients _MUST_ process the `format` property on a IIIF Image API Selector.
+ * Other types of resource _MUST NOT_ have the `format` property.
+ Clients _SHOULD_ ignore `format` on other types of resource.
+
+
+For a Content Resource:
+{% include api/code_header.html %}
+``` json-doc
+{ "format": "application/xml" }
+```
+
+For a IIIF Image API Selector:
+{% include api/code_header.html %}
+``` json-doc
+{ "format": "jpg" }
+```
+
+
+### height
+{: #height}
+
+The height of the Canvas or external content resource. For content resources, the value is in pixels. For Canvases, the value does not have a unit. In combination with the width, it conveys an aspect ratio for the space in which content resources are located.
+
+The value _MUST_ be a positive integer.
+
+ * A Canvas _MUST_ have the `height` property.
+ Clients _MUST_ process `height` on a Canvas.
+ * Content resources _SHOULD_ have the `height` property, with the value given in pixels, if appropriate to the resource type.
+ Clients _SHOULD_ process `height` on content resources.
+ * Other types of resource _MUST NOT_ have the `height` property.
+ Clients _SHOULD_ ignore `height` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "height": 1800 }
+```
+### homepage
+{: #homepage}
+
+A web page that is about the object represented by the resource that has the `homepage` property. The web page is usually published by the organization responsible for the object, and might be generated by a content management system or other cataloging system. The resource _MUST_ be able to be displayed directly to the user. Resources that are related, but not home pages, _MUST_ instead be added into the `metadata` property, with an appropriate `label` or `value` to describe the relationship.
+
+The value of this property _MUST_ be an array of JSON objects, each of which _MUST_ have the `id`, `type`, and `label` properties, _SHOULD_ have a `format` property, and _MAY_ have the `language` property.
+
+ * Any resource type _MAY_ have the `homepage` property.
+ Clients _SHOULD_ render `homepage` on a Collection, Manifest or Container, and _MAY_ render `homepage` on other types of resource.
+
+__Model Alignment__
+Please note that this specification has stricter requirements about the JSON pattern used for the `homepage` property than the [Web Annotation Data Model][org-w3c-webanno]. The IIIF requirements are compatible, but the home page of an Agent found might have only a URI, or might be a JSON object with other properties. See the section on [collisions between contexts][prezi30-context-collisions] for more information.
+{: .note}
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "homepage": [
+ {
+ "id": "https://example.com/info/",
+ "type": "Text",
+ "label": { "en": [ "Homepage for Example Object" ] },
+ "format": "text/html",
+ "language": [ "en" ]
+ }
+ ]
+}
+```
+
+### id
+{: #id}
+
+The URI that identifies the resource. If the resource is only available embedded within another resource (see the [terminology section][prezi30-terminology] for an explanation of "embedded"), such as a Range within a Manifest, then the URI _MAY_ be the URI of the embedding resource with a unique fragment on the end. This is not true for Containers, which _MUST_ have their own URI without a fragment.
+
+The value _MUST_ be a string, and the value _MUST_ be an absolute HTTP(S) URI for resource classes defined or described in this specification. If the resource is retrievable via HTTP(S), then the URI _MUST_ be the URI at which it is published. External resources, such as profiles, _MAY_ have non-HTTP(S) URIs defined by other communities.
+
+The existence of an HTTP(S) URI in the `id` property does not mean that the URI will always be dereferenceable. If the resource with the `id` property is embedded, it _MAY_ also be dereferenceable. If the resource is referenced, it _MUST_ be dereferenceable.
+
+If a publisher wishes for a resource be able to be referenced, such as in an Annotation, then the resource _MUST_ have an `id` property.
+
+ * Collections, Collection Pages, Manifests, Timelines, Canvases, Scenes, Annotations, Annotation Pages, Annotation Collections, Ranges, Content Resources, and Services _MUST_ have the `id` property.
+ Clients _MAY_ render `id` on any resource type, and _SHOULD_ render `id` on Collections, Manifests and Containers.
+ * All other resources _MAY_ have the `id` property.
+ Clients _MAY_ render `id` on any resource type.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "id": "https://example.org/iiif/1/manifest" }
+```
+
+### instant
+{: #instant}
+
+A floating point number giving the time of the point in seconds from the beginning of the temporal resource. For example, an `instant` value of 4.5 means the exact point 4.5 seconds from the beginning of the resource.
+
+* PointSelector _MAY_ have the `instant` property.
+ Clients _SHOULD_ process `instant`.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "instant": 4.5 }
+```
+
+
+### intensity
+{: #intensity}
+
+This property sets the strength or brightness of a Light. The `value` of the referenced Quantity indicates the desired intensity on a linear scale between 0.0 (no brightness) and 1.0 (as bright as the client will render). If this property is not specified, then the default intensity value is client-dependent.
+
+The value of this property _MUST_ be a Quantity.
+The value of the `unit` property of the Quantity _MUST_ be `relative`.
+The value of the `quantityValue` property of the Quantity _MUST_ be between 0.0 and 1.0.
+
+* A Light _SHOULD_ have the `intensity` property.
+ Clients _SHOULD_ process the `intensity` property on a Light.
+
+```json
+{
+ "intensity": {
+ "id": "https://example.org/iiif/intensity/1",
+ "type": "Quantity",
+ "quantityValue": 0.5,
+ "unit": "relative"}
+}
+```
+### interactionMode
+{: #interactionMode}
+
+A set of features that guide or limit user interaction with content within a Container that the publisher of the content would prefer the client to use when presenting the resource. This specification defines values in the table below that guide interactions with Cameras within a Scene. Other values for other Container types or specifying other interaction modes for 3D content may be defined externally as an [extension][prezi30-ldce]. For interaction modes pertaining to Cameras within a Scene, the client _SHOULD_ use `interactionMode` to determine the user experience features and approaches whereby users are permitted to change or adjust Cameras when viewing content within a Scene (e.g., orbiting around the scene or locking the user to a first-person perspective).
+
+When more than one interaction mode is present, the client _SHOULD_ pick the first interaction mode that the client is capable of supporting.
+
+For interaction modes that involve a Camera orbiting around a target point, the target point _SHOULD_ be the same as the Camera's `lookAt` property.
+
+The value _MUST_ be an array of strings.
+
+> TODO: Undecided whether this is Camera and/or Container
+
+* A Camera _MAY_ have the `interactionMode` property.
+ Clients _SHOULD_ process `interactionMode` on a Camera.
+* A Container _MAY_ have the `interactionMode` property.
+ Clients _SHOULD_ process `interactionMode` on a Container.
+* Other types of resource _MUST NOT_ have the `interactionMode` property.
+ Clients _SHOULD_ ignore `interactionMode` on other types of resource.
+
+| Value | Description |
+| ----- | ----------- |
+| `locked` | Camera is locked. User interaction _MUST NOT_ modify Camera. |
+| `orbit` | Camera orbits around a target point in response to user interaction. |
+| `hemisphere-orbit` | Camera orbits around a target point in response to user interaction, but orbital freedom is limited to a hemisphere. |
+| `free` | Camera mimics a first-person perspective. User interaction pans or tilts Camera perspective, trucks Camera position, and/or dollies or zooms Camera. |
+| `free-direction` | Camera mimics a first-person perspective, but Camera position is fixed. User interaction pans or tilts Camera perspective. |
+{: .api-table #table-interaction}
+
+{% include api/code_header.html %}
+``` json-doc
+{ "interactionMode": [ "hemisphere-orbit", "orbit" ] }
+```
+### items
+{: #items}
+
+Much of the functionality of the IIIF Presentation API is simply recording the order in which child resources occur within a parent resource, such as Collections or Manifests within a parent Collection, or Canvases within a Manifest. All of these situations are covered with a single property, `items`.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have the `id` and `type` properties. The items will be resources of different types, as described below.
+
+ * A Collection _MUST_ have the `items` property. Each item _MUST_ be either a Collection or a Manifest.
+ Clients _MUST_ process `items` on a Collection.
+ * A Manifest _MUST_ have the `items` property with at least one item. Each item _MUST_ be a Container.
+ Clients _MUST_ process `items` on a Manifest.
+ * A Container _SHOULD_ have the `items` property with at least one item. Each item _MUST_ be an Annotation Page.
+ Clients _MUST_ process `items` on a Container.
+ * An Annotation Page _SHOULD_ have the `items` property with at least one item. Each item _MUST_ be an Annotation.
+ Clients _MUST_ process `items` on an Annotation Page.
+ * A Range _MUST_ have the `items` property with at least one item. Each item _MUST_ be a Range, a Canvas or a Specific Resource where the source is a Canvas.
+ Clients _SHOULD_ process `items` on a Range.
+ * Other types of resource _MUST NOT_ have the `items` property.
+ Clients _SHOULD_ ignore `items` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "items": [
+ {
+ "id": "https://example.org/iiif/manifest1",
+ "type": "Manifest"
+ },
+ {
+ "id": "https://example.org/iiif/collection1",
+ "type": "Collection"
+ }
+ // ...
+ ]
+}
+```
+### label
+{: #label}
+
+A human readable label, name or title. The `label` property is intended to be displayed as a short, textual surrogate for the resource if a human needs to make a distinction between it and similar resources, for example between objects, pages, or options for a choice of images to display. The `label` property can be fully internationalized, and each language can have multiple values. This pattern is described in more detail in the [languages][prezi40-languages] section.
+
+The value of the property _MUST_ be a JSON object, as described in the [languages][prezi40-languages] section.
+
+ * A Collection _MUST_ have the `label` property with at least one entry.
+ Clients _MUST_ render `label` on a Collection.
+ * A Manifest _MUST_ have the `label` property with at least one entry.
+ Clients _MUST_ render `label` on a Manifest.
+ * All Container types _SHOULD_ have the `label` property with at least one entry.
+ Clients _MUST_ render `label` on Container types, and _SHOULD_ generate a `label` for Containers that do not have them.
+ * All Content Resource types _MAY_ have the `label` property with at least one entry. If there is a Choice of Content Resource for the same Container, then they _SHOULD_ each have the `label` property with at least one entry.
+ Clients _MAY_ render `label` on Content Resources, and _SHOULD_ render them when part of a Choice.
+ * A Range _SHOULD_ have the `label` property with at least one entry.
+ Clients _MUST_ render `label` on a Range.
+ * An Annotation Collection _SHOULD_ have the `label` property with at least one entry.
+ Clients _SHOULD_ render `label` on an Annotation Collection.
+ * Other types of resource _MAY_ have the `label` property with at least one entry.
+ Clients _MAY_ render `label` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "label": { "en": [ "Example Object Title" ] } }
+```
+### language
+{: #language}
+
+The language or languages used in the content of this external resource. This property is already available from the Web Annotation model for content resources that are the body or target of an Annotation, however it _MAY_ also be used for resources [referenced][prezi30-terminology] from `homepage`, `rendering`, and `partOf`.
+
+The value _MUST_ be an array of strings. Each item in the array _MUST_ be a valid language code, as described in the [languages section][prezi30-languages].
+
+ * An external resource _SHOULD_ have the `language` property with at least one item.
+ Clients _SHOULD_ process the `language` of external resources.
+ * Other types of resource _MUST NOT_ have the `language` property.
+ Clients _SHOULD_ ignore `language` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "language": [ "en" ] }
+```
+
+### last
+{: #last}
+
+This property references the last Annotation Page within an Annotation Collection, or last Collection Page within a Collection.
+
+The value _MUST_ be a JSON object with `id` and `type` properties. The `id` _MUST_ be the HTTP(S) URI of the referenced Annotation or Collection Page. The value of `type` _MUST_ be `AnnotationPage` or `CollectionPage`.
+
+* A non-empty AnnotationCollection _SHOULD_ have the `last` property.
+ Clients _SHOULD_ process the `last` property on an AnnotationCollection.
+* A non-empty Collection _MAY_ have the `last` property.
+ Clients _MAY_ process the `last` property on a Collection.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "last": {
+ "id": "https://example.org/iiif/annotationPage/17",
+ "type": "AnnotationPage"
+ }
+}
+```
+
+### logo
+{: #logo}
+
+A small image resource that represents the Agent resource it is associated with. The logo _MUST_ be clearly rendered when the resource is displayed or used, without cropping, rotating or otherwise distorting the image. It is _RECOMMENDED_ that a [IIIF Image API][image-api] service be available for this image for other manipulations such as resizing.
+
+When more than one logo is present, the client _SHOULD_ pick only one of them, based on the information in the logo properties. For example, the client could select a logo of appropriate aspect ratio based on the `height` and `width` properties of the available logos. The client _MAY_ decide on the logo by inspecting properties defined as [extensions][prezi30-ldce].
+
+The value of this property _MUST_ be an array of JSON objects, each of which _MUST_ have `id` and `type` properties, and _SHOULD_ have `format`. The value of `type` _MUST_ be `Image`.
+
+ * Agent resources _SHOULD_ have the `logo` property.
+ Clients _MUST_ render `logo` on Agent resources.
+
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "logo": [
+ {
+ "id": "https://example.org/img/logo.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "height": 100,
+ "width": 120
+ }
+ ]
+}
+```
+
+### lookAt
+{: #lookAt}
+
+It is useful to be able to rotate a light or camera or audio resource such that it is facing another object or point in the Scene, rather than calculating the angles within the Scene's coordinate space. This is accomplished with a property called `lookAt`, valid on DirectionalLight, SpotLight, and all Cameras. The value of the property is either a PointSelector, a WktSelector, the URI of an Annotation which paints something into the current Scene, or a Specific Resource with a selector identifying a point or region in an arbitrary container.
+
+If the value is a PointSelector, then the light or camera resource is rotated around the x and y axes such that it is facing the given point. If the value is a WktSelector, then the resource should be rotated to face the given region. If the value is an Annotation which targets a point via a PointSelector, URI fragment or other mechanism, then the resource should be rotated to face that point. If the value is a Specific Resource, the source container for the Specific Resource must be painted into the current Scene, and the Specific Resource selector should identify a point or region in the source container. In this case, the light or camera resource should be rotated to face the point or region in the source container where the point or region is located within the current Scene's coordinate space. This allows light or camera resources to face a specific 2D point on a Canvas painted into a 3D scene.
+
+This rotation happens after the resource has been added to the Scene, and thus after any transforms have taken place in the local coordinate space.
+
+
+The value _MUST_ be a JSON object, conforming to either a reference to an Annotation, or an embedded PointSelector. If this property is not specified, then the default value for cameras is to look straight backwards (-Z) and for lights to point straight down (-Y).
+
+* A Camera _MAY_ have the `lookAt` property.
+ Clients _SHOULD_ process the `lookAt` property on Cameras.
+* A SpotLight or a DirectionalLight _SHOULD_ have the `lookAt` property.
+* A SpotAudio _SHOULD_ have the `lookAt` property.
+
+{% include api/code_header.html %}
+```json
+"lookAt": {
+ "type": "PointSelector",
+ "x": 3,
+ "y": 0,
+ "z": -10
+}
+```
+
+### metadata
+{: #metadata}
+
+An ordered list of descriptions to be displayed to the user when they interact with the resource, given as pairs of human readable `label` and `value` entries. The content of these entries is intended for presentation only; descriptive semantics _SHOULD NOT_ be inferred. An entry might be used to convey information about the creation of the object, a physical description, ownership information, or other purposes.
+
+The value of the `metadata` property _MUST_ be an array of JSON objects, where each item in the array has both `label` and `value` properties. The values of both `label` and `value` _MUST_ be JSON objects, as described in the [languages][prezi40-languages] section.
+
+ * A Collection _SHOULD_ have the `metadata` property with at least one item.
+ Clients _MUST_ render `metadata` on a Collection.
+ * A Manifest _SHOULD_ have the `metadata` property with at least one item.
+ Clients _MUST_ render `metadata` on a Manifest.
+ * All Container types _MAY_ have the `metadata` property with at least one item.
+ Clients _SHOULD_ render `metadata` on Containers.
+ * Other types of resource _MAY_ have the `metadata` property with at least one item.
+ Clients _MAY_ render `metadata` on other types of resource.
+
+Clients _SHOULD_ display the entries in the order provided. Clients _SHOULD_ expect to encounter long texts in the `value` property, and render them appropriately, such as with an expand button, or in a tabbed interface.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "metadata": [
+ {
+ "label": { "en": [ "Creator" ] },
+ "value": { "en": [ "Anne Artist (1776-1824)" ] }
+ }
+ ]
+}
+```
+
+### navDate
+{: #navDate}
+
+A date that clients may use for navigation purposes when presenting the resource to the user in a date-based user interface, such as a calendar or timeline. More descriptive date ranges, intended for display directly to the user, _SHOULD_ be included in the `metadata` property for human consumption. If the resource contains Canvases that have the `duration` property, the datetime given corresponds to the navigation datetime of the start of the resource. For example, a Range that includes a Canvas that represents a set of video content recording a historical event, the `navDate` is the datetime of the first moment of the recorded event.
+
+The value _MUST_ be an [XSD dateTime literal][org-w3c-xsd-datetime]. The value _MUST_ have a timezone, and _SHOULD_ be given in UTC with the `Z` timezone indicator, but _MAY_ instead be given as an offset of the form `+hh:mm`.
+
+ * A Collection _MAY_ have the `navDate` property.
+ Clients _MAY_ render `navDate` on a Collection.
+ * A Manifest _MAY_ have the `navDate` property.
+ Clients _MAY_ render `navDate` on a Manifest.
+ * A Range _MAY_ have the `navDate` property.
+ Clients _MAY_ render `navDate` on a Range.
+ * All Container types _MAY_ have the `navDate` property.
+ Clients _MAY_ render `navDate` on Containers.
+* Annotations _MAY_ have the `navDate` property.
+ Clients _MAY_ render `navDate` on Annotations.
+ * Other types of resource _MUST NOT_ have the `navDate` property.
+ Clients _SHOULD_ ignore `navDate` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "navDate": "2010-01-01T00:00:00Z" }
+```
+
+### navPlace
+{: #navPlace}
+
+A geographic location that clients may use for navigation purposes when presenting the resource to the user in a map-based user interface. The location is identified using structured data, described below, with latitude and longitude based points or polygons. If the location is only textual, then the information should instead be included in the `metadata` property.
+
+The value of the property _MUST_ be a [GeoJSON Feature Collection] [link] containing one or more [Features] [link]. The value _SHOULD_ be embedded and _MAY_ be a reference. Feature Collections referenced in the `navPlace` property _MUST_ have the `id` and `type` properties and _MUST NOT_ have the `features` property.
+
+* A Collection _MAY_ have the `navPlace` property.
+ Clients _MAY_ render `navPlace` on a Collection.
+* A Manifest _MAY_ have the `navPlace` property.
+ Clients _MAY_ render `navPlace` on a Manifest.
+* A Range _MAY_ have the `navPlace` property.
+ Clients _MAY_ render `navPlace` on a Range.
+* All Container types _MAY_ have the `navPlace` property.
+ Clients _MAY_ render `navPlace` on Containers.
+* Annotations _MAY_ have the `navPlace` property.
+ Clients _MAY_ render `navPlace` on Annotations.
+* Other types of resource _MUST NOT_ have the `navPlace` property.
+ Clients _SHOULD_ ignore `navPlace` on other types of resource.
+
+
+{% include api/code_header.html %}
+```json-doc
+{
+ "navPlace":{
+ "id": "https://example.com/feature-collection/1",
+ "type": "FeatureCollection",
+ "features":[
+ {
+ "id": "https://example.com/feature/1",
+ "type": "Feature",
+ "geometry":{
+ "id": "https://example.com/geometry/1",
+ "type": "Point",
+ "coordinates":[
+ 9.938,
+ 51.533
+ ]
+ }
+ }
+ ]
+ }
+}
+```
+
+### near
+{: #near}
+
+This property gives the distance along the cameria's axis of orientation from which objects are visible. Objects closer to the camera than the `near` distance cannot be seen.
+
+The value is a non-negative floating point number, in the coordinate space of the Scene in which the Camera is positioned. The value _MUST_ be less than the value for `far` for the same Camera. If this property is not specified, then the default value is client-dependent.
+
+* A Camera _MAY_ have the `near` property
+ Clients _SHOULD_ process the `near` property on Cameras.
+
+```json-doc
+{ "near": 1.5 }
+```
+
+### next
+{: #next}
+
+A reference from an Annotation Page to the following Annotation Page within an Annotation Collection, or from a Collection Page to the following Collection Page.
+
+The value must be a JSON object, with the `id` and `type` properties. The value of the `id` property must be a string, and must be the HTTP(S) URI of the following Annotation or Collection Page. The value of the `type` property must be the string `AnnotationPage` or `CollectionPage`.
+
+* An AnnotationPage _MUST_ have the `next` property, unless it is the last page in the AnnotationCollection or Collection.
+ Clients _MUST_ processs the `next` property on an AnnotationPage or CollectionPage.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "next": {
+ "id": "https://example.org/iiif/annotationPage/3",
+ "type": "AnnotationPage"
+ }
+}
+```
+
+### partOf
+{: #partOf}
+
+A containing resource that includes the resource that has the `partOf` property. When a client encounters the `partOf` property, it might retrieve the [referenced][prezi30-terminology] containing resource, if it is not [embedded][prezi30-terminology] in the current representation, in order to contribute to the processing of the contained resource. For example, the `partOf` property on a Canvas can be used to reference an external Manifest in order to enable the discovery of further relevant information. Similarly, a Manifest can reference a containing Collection using `partOf` to aid in navigation.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have the `id` and `type` properties, and _SHOULD_ have the `label` property.
+
+ * Any resource type _MAY_ have the `partOf` property with at least one item
+ Clients _MAY_ render `partOf` on any resource type.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "partOf": [ { "id": "https://example.org/iiif/1", "type": "Manifest" } ] }
+```
+
+The resources referred to by the `accompanyingContainer` and `placeholderContainer` properties are `partOf` that referring Container.
+
+### placeholderContainer
+{: #placeholderContainer}
+
+A single Container that provides additional content for use before the main content of the resource that has the `placeholderContainer` property is rendered, or as an advertisement or stand-in for that content. Examples include images, text and sound standing in for video content before the user initiates playback; or a film poster to attract user attention. The content provided by `placeholderContainer` differs from a thumbnail: a client might use `thumbnail` to summarize and navigate multiple resources, then show content from `placeholderContainer` as part of the initial presentation of a single resource. A placeholder Container is likely to have different dimensions to those of the Container(s) of the resource that has the `placeholderContainer` property. A placeholder Container may be of a different type from the resource that has the `placeholderContainer` property. For example, a `Scene` may have a placeholder Container of type `Canvas`.
+
+Clients _MAY_ display the content of a linked placeholder Container when presenting the resource. When more than one such Container is available, for example if `placeholderContainer` is provided for the currently selected Range and the current Manifest, the client _SHOULD_ pick the one most specific to the content. Publishers _SHOULD NOT_ assume that the placeholder Container will be processed by all clients. Clients _SHOULD_ take care to avoid conflicts between time-based media in the rendered placeholder Container and the content of the resource that has the `placeholderContainer` property.
+
+The value of `placeholderContainer` _MUST_ be a JSON object with the `id` and `type` properties. The value of `type` _MUST_ be a Container type. The JSON object _MAY_ have other properties valid for that Container type.
+
+ * A Collection _MAY_ have the `placeholderContainer` property.
+ Clients _MAY_ render `placeholderContainer` on a Collection.
+ * A Manifest _MAY_ have the `placeholderContainer` property.
+ Clients _MAY_ render `placeholderContainer` on a Manifest.
+ * All Container types _MAY_ have the `placeholderContainer` property.
+ Clients _MAY_ render `placeholderContainer` on Containers.
+ * A Range _MAY_ have the `placeholderContainer` property.
+ Clients _MAY_ render `placeholderContainer` on a Range.
+ * Other types of resource _MUST NOT_ have the `placeholderContainer` property.
+ Clients _SHOULD_ ignore `placeholderContainer` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "placeholderContainer": {
+ "id": "https://example.org/iiif/1/canvas/placeholder",
+ "type": "Canvas",
+ "height": 1400,
+ "width": 1200
+ }
+}
+```
+### position
+{: #position}
+
+It is important to be able to position the (textual) body of an annotation within the Container's space that the annotation also targets. For example, a description of part of an image in a Canvas should be positioned such that it does not obscure the image region itself and labels to be displayed as part of a Scene should not be rendered such that the text is hidden by the three dimensional geometry of the model. If this property is not supplied, then the client should do its best to ensure the content is visible to the user.
+
+The value of this property _MUST_ be a JSON object conforming to the `SpecificResource` pattern of the Web Annotation Model. The Specific Resource _MUST_ have a `source` property that refers to a Container, and a `selector` that describes a point or region within the Container.
+
+* A TextualBody _MAY_ have the `position` property.
+ Clients _SHOULD_ process the `position` property on TextualBody instances.
+* Other classes _MUST NOT_ have the `position` property.
+ Clients _MUST_ ignore the `position` property on all other classes.
+
+```json-doc
+{ "position": {
+ "type": "SpecificResource",
+ "source": [{
+ "id": "https://example.org/iiif/scene1",
+ "type": "Scene"
+ }],
+ "selector": [{
+ "type": "PointSelector",
+ "x": 1.0,
+ "y": 19.2,
+ "z": 2.7
+ }]
+ }
+}
+
+```
+
+### prev
+{: #prev}
+
+A reference from an Annotation Page to the preceding Annotation Page within an Annotation Collection, or from a Collection Page to the preceding Collection Page.
+
+The value must be a JSON object, with the `id` and `type` properties. The value of the `id` property must be a string, and must be the HTTP(S) URI of the preceding Annotation or Collection Page. The value of the `type` property must be the string `AnnotationPage` or `CollectionPage`.
+
+* An AnnotationPage _SHOULD_ have the `prev` property, unless it is the first page in the AnnotationCollection.
+ Clients _SHOULD_ processs the `prev` property on an AnnotationPage.
+* A CollectionPage _SHOULD_ have the `prev` property, unless it is the first page in the Collection.
+ Clients _SHOULD_ processs the `prev` property on a CollectionPage.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "prev": {
+ "id": "https://example.org/iiif/annotationPage/1",
+ "type": "AnnotationPage"
+ }
+}
+```
+
+### profile
+{: #profile}
+
+A schema or named set of functionality available from the resource. The profile can further clarify the `type` and/or `format` of an external resource or service, allowing clients to customize their handling of the resource that has the `profile` property.
+
+The value _MUST_ be a string, either taken from the [profiles registry][registry-profiles] or a URI.
+
+* Resources [referenced][prezi30-terminology] by the `seeAlso` or `service` properties _SHOULD_ have the `profile` property.
+ Clients _SHOULD_ process the `profile` of a service or external resource.
+* Other types of resource _MAY_ have the `profile` property.
+ Clients _MAY_ process the `profile` of other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "profile": "https://example.org/profile/statuary" }
+```
+
+### provider
+{: #provider}
+
+An organization or person that contributed to providing the content of the resource. Clients can then display this information to the user to acknowledge the provider's contributions. This differs from the `requiredStatement` property, in that the data is structured, allowing the client to do more than just present text but instead have richer information about the people and organizations to use in different interfaces.
+
+The organization or person is represented as an `Agent` resource.
+
+* Agents _MUST_ have the `id` property, and its value _MUST_ be a string. The string _MUST_ be a URI that identifies the agent.
+* Agents _MUST_ have the `type` property, and its value _MUST_ be the string `Agent`.
+* Agents _MUST_ have the `label` property, and its value _MUST_ be a JSON object as described in the [languages][prezi30-languages] section.
+* Agents _SHOULD_ have the `homepage` property, and its value _MUST_ be an array of JSON objects as described in the [homepage][prezi30-homepage] section.
+* Agents _SHOULD_ have the `logo` property, and its value _MUST_ be an array of JSON objects as described in the [logo][prezi30-logo] section.
+* Agents _MAY_ have the `seeAlso` property, and its value _MUST_ be an array of JSON object as described in the [seeAlso][prezi30-seealso] section.
+
+The value _MUST_ be an array of JSON objects, where each item in the array conforms to the structure of an Agent, as described above.
+
+ * A Collection _SHOULD_ have the `provider` property with at least one item.
+ Clients _MUST_ render `provider` on a Collection.
+ * A Manifest _SHOULD_ have the `provider` property with at least one item.
+ Clients _MUST_ render `provider` on a Manifest.
+ * Other types of resource _MAY_ have the `provider` property with at least one item.
+ Clients _SHOULD_ render `provider` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "provider": [
+ {
+ "id": "https://example.org/about",
+ "type": "Agent",
+ "label": { "en": [ "Example Organization" ] },
+ "homepage": [
+ {
+ "id": "https://example.org/",
+ "type": "Text",
+ "label": { "en": [ "Example Organization Homepage" ] },
+ "format": "text/html"
+ }
+ ],
+ "logo": [
+ {
+ "id": "https://example.org/images/logo.png",
+ "type": "Image",
+ "format": "image/png",
+ "height": 100,
+ "width": 120
+ }
+ ],
+ "seeAlso": [
+ {
+ "id": "https://data.example.org/about/us.jsonld",
+ "type": "Dataset",
+ "format": "application/ld+json",
+ "profile": "https://schema.org/"
+ }
+ ]
+ }
+ ]
+}
+```
+### provides
+{: #provides}
+
+A set of features or additional functionality that a linked resource enables relative to the linking or including resource, often for accessibility purposes and which are not defined by the `type`, `format` or `profile` of the linked resource. It provides information as to why and how a client might want to interact with the resource, rather than what the resource is. For example, a text file (linked resource) that `provides` a `closedCaptions` for a Video (context resource), or an audio file (linked resource) that `provides` an `audioDescription` of a Canvas (context resource).
+
+The value _MUST_ be an array of strings, each string identifies a particular feature and _MUST_ be taken from the table below or the [provides registry][link].
+
+Note that the majority of the values have been selected from [accessibility feature spec][link] and thus use the original form rather than being consistent with the hyphen-based form of the values of `behavior` and `viewingDirection`.
+
+* Annotations with the `supplementing` motivation _MAY_ have the `provides` property.
+ Clients _SHOULD_ ignore the `provides` property on all other resource.
+
+| Value | Description |
+| ----- | ----------- |
+| `closedCaptions` | ... |
+| `alternativeText` | ... |
+| `audioDescription` | ... |
+| `longDescription` | ... |
+| `signLanguage` | ... |
+| `highContrastAudio` | ... |
+| `highContrastDisplay` | ... |
+| `braille` | ... |
+| `tactileGraphic` | ... |
+| `transcript` | ... |
+| `translation` | (IIIF Defined) ... |
+| `subtitles` | (IIIF Defined) ... |
+{: .api-table #table-behavior}
+
+{% include api/code_header.html %}
+``` json-doc
+{ "provides": [ "closedCaption" ] }
+```
+
+### quality
+{: #quality}
+
+The value of the quality parameter in the IIIF Image API URL structure, as recorded in an Image API Selector.
+
+* The IIIF Image API Selector _MAY_ have the `quality` property with exactly one value.
+ Clients _MUST_ process the `quality` property on a IIIF Image API Selector.
+* Other types of resource _MUST NOT_ have the `quality` property.
+ Clients _MUST_ ignore the `quality` property on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "quality": "default" }
+```
+
+### quantityValue
+{: #quantityValue}
+
+The `quantityValue` property of a Quantity conveys its numerical component.
+
+The value of `quantityValue` _MUST_ be a floating point number.
+
+* A Quantity _MUST_ have the `quantity` property.
+ Clients _MUST_ process the `quantity` property on a Quantity.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "quantity": 0.1234123 }
+```
+
+### refinedBy
+{: #refinedBy}
+
+The `refinedBy` property allows Selectors to be chained together to incrementally select more specific aspects of the resource given in `source` on the Specific Resource. The first selector on a Specific Resource describes how to select part of the main resource, and a subsequent selector in `refinedBy` then describes how to further select part of that part. This can be used, for example, to extract a rectangular region with a `FragmentSelector` and then further refine that region with an `SvgSelector` or `WktSelector`.
+
+For more information about `refinedBy`, please see the [Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#refinement-of-selection).
+
+The value of the `refinedBy` property _MUST_ be a JSON Object, which _MUST_ describe a Selector.
+
+* A Selector _MAY_ have the `refinedBy` property with exactly one value.
+ Clients _SHOULD_ process the `refinedBy` property on Selectors.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "refinedBy": { "type": "WktSelector", "wktLiteral": "POLYGON ((0 0, 0 100, 100 100, 100 0, 0 0))" } }
+```
+
+
+### region
+{: #region}
+
+The value of the region parameter in the IIIF Image API URL structure, as recorded in an Image API Selector.
+
+* The IIIF Image API Selector _MAY_ have the `region` property with exactly one value.
+ Clients _MUST_ process the `region` property on a IIIF Image API Selector.
+* Other types of resource _MUST NOT_ have the `region` property.
+ Clients _MUST_ ignore the `region` property on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "region": "full" }
+```
+
+
+### rendering
+{: #rendering}
+
+A resource that is an alternative, non-IIIF representation of the resource that has the `rendering` property. Such representations typically cannot be painted onto a single Canvas, as they either include too many views, have incompatible dimensions, or are compound resources requiring additional rendering functionality. The `rendering` resource _MUST_ be able to be displayed directly to a human user, although the presentation may be outside of the IIIF client. The resource _MUST NOT_ have a splash page or other interstitial resource that mediates access to it. If access control is required, then the [IIIF Authentication API][iiif-auth] is _RECOMMENDED_. Examples include a rendering of a book as a PDF or EPUB, a slide deck with images of a building, or a 3D model of a statue.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have the `id`, `type` and `label` properties, and _SHOULD_ have the `format` and `language` properties.
+
+ * Any resource type _MAY_ have the `rendering` property with at least one item.
+ Clients _SHOULD_ render `rendering` on a Collection, Manifest or Canvas, and _MAY_ render `rendering` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "rendering": [
+ {
+ "id": "https://example.org/1.pdf",
+ "type": "Text",
+ "label": { "en": [ "PDF Rendering of Book" ] },
+ "format": "application/pdf"
+ }
+ ]
+}
+```
+### requiredStatement
+{: #requiredStatement}
+
+Text that _MUST_ be displayed when the resource is displayed or used. For example, the `requiredStatement` property could be used to present copyright or ownership statements, an acknowledgement of the owning and/or publishing institution, or any other text that the publishing organization deems critical to display to the user. Given the wide variation of potential client user interfaces, it will not always be possible to display this statement to the user in the client's initial state. If initially hidden, clients _MUST_ make the method of revealing it as obvious as possible.
+
+The value of the property _MUST_ be a JSON object, that has the `label` and `value` properties, in the same way as a `metadata` property entry. The values of both `label` and `value` _MUST_ be JSON objects, as described in the [languages][prezi40-languages] section.
+
+ * Any resource type _MAY_ have the `requiredStatement` property.
+ Clients _MUST_ render `requiredStatement` on every resource type.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "requiredStatement": {
+ "label": { "en": [ "Attribution" ] },
+ "value": { "en": [ "Provided courtesy of Example Institution" ] }
+ }
+}
+```
+
+### resets
+{: #resets}
+
+FIXME: write this
+
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "resets": []
+}
+```
+
+
+### rights
+{: #rights}
+
+A string that identifies a license or rights statement that applies to the content of the resource, such as the JSON of a Manifest or the pixels of an image. The value _MUST_ be drawn from the set of [Creative Commons][org-cc-licenses] license URIs, the [RightsStatements.org][org-rs-terms] rights statement URIs, or those added via the [extension][prezi40-ldce] mechanism. The inclusion of this property is informative, and for example could be used to display an icon representing the rights assertions.
+
+!!! registration not extension
+
+If displaying rights information directly to the user is the desired interaction, or a publisher-defined label is needed, then it is _RECOMMENDED_ to include the information using the `requiredStatement` property or in the `metadata` property.
+
+The value _MUST_ be a string. If the value is drawn from Creative Commons or RightsStatements.org, then the string _MUST_ be a URI defined by that specification.
+
+ * Any resource type _MAY_ have the `rights` property.
+ Clients _MAY_ render `rights` on any resource type.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "rights": "http://creativecommons.org/licenses/by/4.0/" }
+```
+
+__Machine actionable URIs and links for users__
+The machine actionable URIs for both Creative Commons licenses and RightsStatements.org right statements are `http` URIs. In both cases, human readable descriptions are available from equivalent `https` URIs. Clients may wish to rewrite links presented to users to use these equivalent `https` URIs.
+{: .note}
+
+
+### rotation
+{: #rotation}
+
+The value of the rotation parameter in the IIIF Image API URL structure, as recorded in an Image API Selector. Note well that the value _MUST_ be a string, not a number, in order to allow for the "!" character which indicates a mirror image.
+
+* The IIIF Image API Selector _MAY_ have the `rotation` property with exactly one value.
+ Clients _MUST_ process the `rotation` property on a IIIF Image API Selector.
+* Other types of resource _MUST NOT_ have the `rotation` property.
+ Clients _MUST_ ignore the `rotation` property on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "rotation": "0" }
+```
+
+### seeAlso
+{: #seeAlso}
+
+A machine-readable resource such as an XML or RDF description that is related to the current resource that has the `seeAlso` property. Properties of the resource should be given to help the client select between multiple descriptions (if provided), and to make appropriate use of the document. If the relationship between the resource and the document needs to be more specific, then the document should include that relationship rather than the IIIF resource. Other IIIF resources are also valid targets for `seeAlso`, for example to link to a Manifest that describes a related object. The URI of the document _MUST_ identify a single representation of the data in a particular format. For example, if the same data exists in JSON and XML, then separate resources should be added for each representation, with distinct `id` and `format` properties.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have the `id` and `type` properties, and _SHOULD_ have the `label`, `format` and `profile` properties.
+
+ * Any resource type _MAY_ have the `seeAlso` property with at least one item.
+ Clients _MAY_ process `seeAlso` on any resource type.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "seeAlso": [
+ {
+ "id": "https://example.org/library/catalog/book1.xml",
+ "type": "Dataset",
+ "label": { "en": [ "Bibliographic Description in XML" ] },
+ "format": "text/xml",
+ "profile": "https://example.org/profiles/bibliographic"
+ }
+ ]
+}
+```
+
+
+### service
+{: #service}
+
+A service that the client might interact with directly and gain additional information or functionality for using the resource that has the `service` property, such as from an Image to the base URI of an associated [IIIF Image API][image-api] service. The service resource _SHOULD_ have additional information associated with it in order to allow the client to determine how to make appropriate use of it. Please see the [Service Registry][registry-services] document for the details of currently known service types.
+
+The value _MUST_ be an array of JSON objects. Each object will have properties depending on the service's definition, but _MUST_ have either the `id` or `@id` and `type` or `@type` properties. Each object _SHOULD_ have a `profile` property.
+
+ * Any resource type _MAY_ have the `service` property with at least one item.
+ Clients _MAY_ process `service` on any resource type, and _SHOULD_ process the IIIF Image API service.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "service": [
+ {
+ "id": "https://example.org/service",
+ "type": "ExampleExtensionService",
+ "profile": "https://example.org/docs/service"
+ }
+ ]
+}
+```
+
+For cross-version consistency, this specification defines the following values for the `type` or `@type` property for backwards compatibility with other IIIF APIs. Future versions of these APIs will define their own types. These `type` values are necessary extensions for compatibility of the older versions.
+
+| Value | Specification |
+| -------------------- | ------------- |
+| ImageService1 | [Image API version 1][image11] |
+| ImageService2 | [Image API version 2][image21] |
+| SearchService1 | [Search API version 1][search1] |
+| AutoCompleteService1 | [Search API version 1][search1-autocomplete] |
+| AuthCookieService1 | [Authentication API version 1][auth1-cookie-service] |
+| AuthTokenService1 | [Authentication API version 1][auth1-token-service] |
+| AuthLogoutService1 | [Authentication API version 1][auth1-logout-service] |
+{: .api-table #table-service-types}
+
+Implementations _SHOULD_ be prepared to recognize the `@id` and `@type` property names used by older specifications, as well as `id` and `type`. Note that the `@context` key _SHOULD NOT_ be present within the `service`, but instead included at the beginning of the document. The example below includes both version 2 and version 3 IIIF Image API services.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "service": [
+ {
+ "@id": "https://example.org/iiif2/image1/identifier",
+ "@type": "ImageService2",
+ "profile": "http://iiif.io/api/image/2/level2.json"
+ },
+ {
+ "id": "https://example.org/iiif3/image1/identifier",
+ "type": "ImageService3",
+ "profile": "level2"
+ }
+ ]
+}
+```
+### services
+{: #services}
+
+A list of one or more service definitions on the top-most resource of the document, that are typically shared by more than one subsequent resource. This allows for these shared services to be collected together in a single place, rather than either having their information duplicated potentially many times throughout the document, or requiring a consuming client to traverse the entire document structure to find the information. The resource that the service applies to _MUST_ still have the `service` property, as described above, where the service resources have at least the `id` and `type` or `@id` and `@type` properties. This allows the client to know that the service applies to that resource. Usage of the `services` property is at the discretion of the publishing system.
+
+A client encountering a `service` property where the definition consists only of an `id` and `type` _SHOULD_ then check the `services` property on the top-most resource for an expanded definition. If the service is not present in the `services` list, and the client requires more information in order to use the service, then it _SHOULD_ dereference the `id` (or `@id`) of the service in order to retrieve a service description.
+
+The value _MUST_ be an array of JSON objects. Each object _MUST_ be a service resource, as described above.
+
+* A Collection _MAY_ have the `services` property, if it is the topmost Collection in a response document.
+ Clients _SHOULD_ process `services` on a Collection.
+* A Manifest _MAY_ have the `services` property.
+ Clients _SHOULD_ process `services` on a Manifest.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "services": [
+ {
+ "@id": "https://example.org/iiif/auth/login",
+ "@type": "AuthCookieService1",
+ "profile": "http://iiif.io/api/auth/1/login",
+ "label": "Login to Example Institution",
+ "service": [
+ {
+ "@id": "https://example.org/iiif/auth/token",
+ "@type": "AuthTokenService1",
+ "profile": "http://iiif.io/api/auth/1/token"
+ }
+ ]
+ }
+ ]
+}
+```
+
+### size
+{: #size}
+
+The value of the size parameter in the IIIF Image API URL structure, as recorded in an Image API Selector.
+
+* A IIIF Image API Selector _MAY_ have the `size` property with exactly one value.
+ Clients _MUST_ process the `size` property on a IIIF Image API Selector.
+* Other types of resource _MUST NOT_ have the `size` property.
+ Clients _MUST_ ignore the `size` property on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "size": "max" }
+```
+
+### source
+{: #source}
+
+The `source` property refers to the URI of the resource that the Specific Resource is a more constrained version or representation of.
+
+For more information about source and Specific Resources, see the [W3C Annotation Model](For more information about Annotation bodies, see the [W3C Annotation Model](https://www.w3.org/TR/annotation-model/#bodies-and-targets).
+
+The value _MUST_ be a string, and the value _MUST_ be a URI.
+
+* A SpecificResource _MUST_ have the `source` property with exactly one value.
+ Clients _MUST_ process the `source` property on a SpecificResource.
+* Other types of resource _MUST NOT_ have the `source` property.
+ Clients _MUST_ ignore the `source` property on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "source": "https://example.org/museum/images/1" }
+```
+
+
+### spatialScale
+{: #spatialScale}
+
+A single Quantity that defines a real-world scale factor for the coordinate units of a Canvas or Scene. For a Canvas, this defines the physical distance corresponding to the length of a single Canvas coordinate unit. A Canvas with a `width` of 5000 and a `spatialScale` with `quantityValue` of 0.00008 and a `unit` of `m` represents a physical space 0.4 meters wide. For a Scene, this defines the physical distance corresponding to the XYZ coordinate units, or in other words, the physical distance length of a unit vector in the 3D coordinate space. The value of `unit` _MUST_ be a length unit. In this specification, the only length unit defined is `m`, i.e., meters. Unless other values are defined externally as an [extension][prezi30-ldce], the value of `unit` _SHOULD_ always be `m`.
+
+To assert a `spatialScale` for a Content Resource, the resource _MUST_ first be painted into a Container and the `spatialScale` is asserted on that Container. For example, a 3d model would be painted into a Scene, and then `spatialScale` is asserted on the Scene.
+
+ * A Canvas _MAY_ have the `spatialScale` property.
+ Clients _SHOULD_ process `spatialScale` on a Canvas.
+ * A Scene _MAY_ have the `spatialScale` property.
+ Clients _SHOULD_ process `spatialScale` on a Scene.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "type": "Canvas",
+ "spatialScale": {
+ "type": "Quantity",
+ "quantityValue": 0.00008,
+ "unit": "m"
+ }
+}
+```
+
+
+### start
+{: #start}
+
+A Container, or part of a Container, which the client _SHOULD_ show on initialization for the resource that has the `start` property. The reference to part of a Container is handled in the same way that Ranges reference parts of Containers by using either its URI, a URI with a fragment specifier, or a SpecificResource with a Selector. This property allows the client to begin with the first Container that contains interesting content rather than requiring the user to manually navigate to find it.
+
+If the resource with the `start` property is a Collection, then the Container (or SpecificResource) _MUST_ have the `partOf` property referring to the Manifest that it is part of, such that the client can retrieve it.
+
+The value _MUST_ be a JSON object, which _MUST_ have the `id` and `type` properties. The object _MUST_ be either a Container (as in the first example below), or a Specific Resource with a Selector and a `source` property where the value is a Canvas (as in the second example below).
+
+ * A Collection _MAY_ have the `start` property.
+ Clients _SHOULD_ process `start` on a Collection.
+ * A Manifest _MAY_ have the `start` property.
+ Clients _SHOULD_ process `start` on a Manifest.
+ * A Range _MAY_ have the `start` property.
+ Clients _SHOULD_ process `start` on a Range.
+ * Other types of resource _MUST NOT_ have the `start` property.
+ Clients _SHOULD_ ignore `start` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "start": { "id": "https://example.org/iiif/1/canvas/1", "type": "Canvas" } }
+```
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "start": {
+ "id": "https://example.org/iiif/1/canvas-segment/1",
+ "type": "SpecificResource",
+ "source": "https://example.org/iiif/1/canvas/1",
+ "selector": {
+ "type": "PointSelector",
+ "t": 14.5
+ }
+ }
+}
+```
+
+### startIndex
+{: #startIndex}
+
+A non-negative, 0-based integer value identifying the relative position of the first entry in the `items` list of a Collection Page or Annotation Collection Page within the overall logical order of its parent Collection or Annotation Collection. If this is the second page, and there are 100 entries on the first page, then the value is 100 (the first page contains entries 0 through 99 inclusive).
+
+The value of `startIndex` must be an integer greater than -1.
+
+* An Annotation Page _MAY_ have the `startIndex` property.
+ Clients _MAY_ process `startIndex` on an Annotation Page.
+* A Collection Page _MAY_ have the `startIndex` property.
+ Clients _MAY_ process `startIndex` on a Collection Page.
+
+
+### structures
+{: #structures}
+
+The structure of an object represented as a Manifest can be described using a hierarchy of Ranges. Ranges can be used to describe the "table of contents" of the object or other structures that the user can interact with beyond the order given by the `items` property of the Manifest. The hierarchy is built by nesting the child Range resources in the `items` array of the higher level Range. The top level Ranges of these hierarchies are given in the `structures` property.
+
+The value _MUST_ be an array of JSON objects. Each item _MUST_ have the `id` and `type` properties, and the `type` _MUST_ be `Range`.
+
+ * A Manifest _MAY_ have the `structures` property.
+ Clients _SHOULD_ process `structures` on a Manifest. The first hierarchy _SHOULD_ be presented to the user by default, and further hierarchies _SHOULD_ be able to be selected as alternative structures by the user.
+ * Other types of resource _MUST NOT_ have the `structures` property.
+ Clients _SHOULD_ ignore `structures` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "structures": [
+ {
+ "id": "https://example.org/iiif/range/1",
+ "type": "Range",
+ "items": [ { ... } ]
+ }
+ ]
+}
+```
+
+### styleClass
+{: #styleClass}
+
+The name of a CSS class to apply when rendering the Specific Resource the style class is associated with. This might change the color of the text, the background color, add borders to the element, change the font size or family, or any other CSS-based styling. The class definition is given using the `stylesheet` property, defined below, which can be used on an Annotation. While Specific Resources _MAY_ appear outside of Annotations, `styleClass` is not valid in these circumstances as there will not be a corresponding `stylesheet` to define the style. If the stylesheet does not define the class given in `styleClass`, then the class _MUST_ be ignored.
+
+The value of the `styleClass` _MUST_ be a string.
+
+For more information about `styleClass`, see the [Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#styles).
+
+* A Specific Resource _MAY_ have the `styleClass` property.
+ Clients _SHOULD_ process the `styleClass` property.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "styleClass": "red" }
+```
+
+### stylesheet
+{: #stylesheet}
+
+The `stylesheet` property conveys either a reference to an external CSS stylesheet document, or carries an embedded stylesheet. This stylesheet is used to resolve CSS classes for processing the `styleClass` directive on Specific Resources, described above.
+
+The value for `stylesheet` _MUST_ be a JSON object. If the stylesheet is referenced, then the JSON object _MUST_ have the `id` and `type` properties. Conversely, if the stylesheet's content is embedded, then it _MUST_ have the `type` and `value` properties, and _MUST NOT_ have the `id` property. The value of `type` _MUST_ be "CssStylesheet".
+
+For more information about `stylesheet`, see the [Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#styles).
+
+* An Annotation _MAY_ have the `stylesheet` property.
+ Clients _SHOULD_ process the `stylesheet` property on Annotations.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "stylesheet":
+ {
+ "type": "CssStylesheet",
+ "value": ".red { color: red }"
+ }
+}
+```
+
+
+### summary
+{: #summary}
+
+A short textual summary intended to be conveyed to the user when the `metadata` entries for the resource are not being displayed. This could be used as a brief description for item level search results, for small-screen environments, or as an alternative user interface when the `metadata` property is not currently being rendered. The `summary` property follows the same pattern as the `label` property described above.
+
+The value of the property _MUST_ be a JSON object, as described in the [languages][prezi40-languages] section.
+
+ * A Collection _SHOULD_ have the `summary` property with at least one entry.
+ Clients _SHOULD_ render `summary` on a Collection.
+ * A Manifest _SHOULD_ have the `summary` property with at least one entry.
+ Clients _SHOULD_ render `summary` on a Manifest.
+ * All Container types _MAY_ have the `summary` property with at least one entry.
+ Clients _SHOULD_ render `summary` on Containers.
+ * Other types of resource _MAY_ have the `summary` property with at least one entry.
+ Clients _MAY_ render `summary` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "summary": { "en": [ "This is a summary of the object." ] } }
+```
+
+### supplementary
+{: #supplementary}
+
+A link from this Range to an Annotation Collection that includes the `supplementing` Annotations of content resources for the Range. Clients might use this to present additional content to the user from a different Canvas when interacting with the Range, or to jump to the next part of the Range within the same Canvas. For example, the Range might represent a newspaper article that spans non-sequential pages, and then uses the `supplementary` property to reference an Annotation Collection that consists of the Annotations that record the text, split into Annotation Pages per newspaper page. Alternatively, the Range might represent the parts of a manuscript that have been transcribed or translated, when there are other parts that have yet to be worked on. The Annotation Collection would be the Annotations that transcribe or translate, respectively.
+
+The value _MUST_ be a JSON object, which _MUST_ have the `id` and `type` properties, and the `type` _MUST_ be `AnnotationCollection`.
+
+ * A Range _MAY_ have the `supplementary` property.
+ Clients _MAY_ process `supplementary` on a Range.
+ * Other types of resource _MUST NOT_ have the `supplementary` property.
+ Clients _SHOULD_ ignore `supplementary` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "supplementary": { "id": "https://example.org/iiif/1/annos/1", "type": "AnnotationCollection" } }
+```
+
+### target
+{: #target}
+
+The list of targets of an Annotation. As there _MAY_ be more than one target, the value _MUST_ be an array, even though the W3C specification does not require this. The resources listed in `target` can be instances of `SpecificResource`, core Structural Resources, or Content Resources.
+
+For more information about Annotation targets, see the [W3C Annotation Model](https://www.w3.org/TR/annotation-model/#bodies-and-targets).
+
+The value _MUST_ be an array of JSON objects.
+
+* An Annotation _MUST_ have the `target` property.
+ Clients _MUST_ process the `target` property on Annotations.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "target": [ { "id": "https://example.org/iiif/1/canvas/1", "type": "Canvas" } ] }
+```
+
+
+### temporalScale
+{: #temporalScale}
+
+A single Quantity that defines a multiplier or scale factor for the `duration` property of a Container, indicating that one second in "Container time" represents some other real world duration. A Canvas with a `duration` of 450 seconds and a `temporalScale` with `quantityValue` of 1000 and a `unit` of `s` represents a real-world duration of 450,000 seconds (5.2 days), for example a time-lapse video of a growing plant. The value of `unit` _MUST_ be a time unit. In this specification, the only time unit defined is `s`, i.e., seconds. Unless other values are defined externally as an [extension][prezi30-ldce], the value of `unit` _SHOULD_ always be `s`.
+
+To assert a `temporalScale` for a Content Resource, the resource _MUST_ first be painted into a Container with a `duration` and the `temporalScale` is asserted on that Container. For example, an Audio file is painted into a Timeline, and then `temporalScale` is asserted on the Timeline.
+
+ * A Timeline _MAY_ have the `temporalScale` property.
+ Clients _MAY_ process `temporalScale` on a Timeline.
+ * A Canvas _MAY_ have the `temporalScale` property.
+ Clients _MAY_ process `temporalScale` on a Canvas.
+ * A Scene _MAY_ have the `temporalScale` property.
+ Clients _MAY_ process `temporalScale` on a Scene.
+
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "type": "Canvas",
+ "temporalScale": {
+ "type": "Quantity",
+ "quantityValue": 1000.0,
+ "unit": "s"
+ }
+}
+```
+
+### thumbnail
+{: #thumbnail}
+
+A content resource, such as a small image or short audio clip, that represents the resource that has the `thumbnail` property. A resource _MAY_ have multiple thumbnail resources that have the same or different `type` and `format`.
+
+The value _MUST_ be an array of JSON objects, each of which _MUST_ have the `id` and `type` properties, and _SHOULD_ have the `format` property. Images and videos _SHOULD_ have the `width` and `height` properties, and time-based media _SHOULD_ have the `duration` property. It is _RECOMMENDED_ that a [IIIF Image API][image-api] service be available for images to enable manipulations such as resizing.
+
+ * A Collection _SHOULD_ have the `thumbnail` property with at least one item.
+ Clients _SHOULD_ render `thumbnail` on a Collection.
+ * A Manifest _SHOULD_ have the `thumbnail` property with at least one item.
+ Clients _SHOULD_ render `thumbnail` on a Manifest.
+ * All Container types _SHOULD_ have the `thumbnail` property with at least one item.
+ Clients _SHOULD_ render `thumbnail` on Containers.
+ * Content Resource types _MAY_ have the `thumbnail` property with at least one item. Content Resources _SHOULD_ have the `thumbnail` property with at least one item if it is an option in a Choice of resources.
+ Clients _SHOULD_ render `thumbnail` on a content resource.
+ * Other types of resource _MAY_ have the `thumbnail` property with at least one item.
+ Clients _MAY_ render `thumbnail` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{
+ "thumbnail": [
+ {
+ "id": "https://example.org/img/thumb.jpg",
+ "type": "Image",
+ "format": "image/jpeg",
+ "width": 300,
+ "height": 200
+ }
+ ]
+}
+```
+
+### timeMode
+{: #timeMode}
+
+A mode associated with an Annotation that is to be applied to the rendering of any time-based media, or otherwise could be considered to have a duration, used as a body resource of that Annotation. Note that the association of `timeMode` with the Annotation means that different resources in the body cannot have different values. This specification defines the values specified in the table below. Others may be defined externally as an [extension][prezi30-ldce].
+
+The value _MUST_ be a string.
+
+ * An Annotation _MAY_ have the `timeMode` property.
+ Clients _SHOULD_ process `timeMode` on an Annotation.
+
+| Value | Description |
+| ----- | ----------- |
+| `trim` | (default, if not supplied) If the content resource has a longer duration than the duration of the portion of the Canvas it is associated with, then at the end of the Canvas's duration, the playback of the content resource _MUST_ also end. If the content resource has a shorter duration than the duration of the portion of the Canvas it is associated with, then, for video resources, the last frame _SHOULD_ persist on-screen until the end of the Canvas portion's duration. For example, a video of 120 seconds annotated to a Canvas with a duration of 100 seconds would play only the first 100 seconds and drop the last 20 seconds. |
+| `scale` | Fit the duration of content resource to the duration of the portion of the Canvas it is associated with by scaling. For example, a video of 120 seconds annotated to a Canvas with a duration of 60 seconds would be played at double-speed. |
+| `loop` | If the content resource is shorter than the `duration` of the Canvas, it _MUST_ be repeated to fill the entire duration. Resources longer than the `duration` _MUST_ be trimmed as described above. For example, if a 20 second duration audio stream is annotated onto a Canvas with a duration of 30 seconds, it will be played one and a half times. |
+{: .api-table #table-timemode}
+
+{% include api/code_header.html %}
+``` json-doc
+{ "timeMode": "trim" }
+```
+
+
+### total (totalItems)
+{: #total}
+
+For compatability with ActivityStreams and the Change Discovery API, clients _SHOULD_ also accept `totalItems` as the name of this property.
+{: .note}
+
+The `total` property indicates the total number of annotations contained in an Annotation Collection.
+
+The value of this property _MUST_ be a non-negative integer.
+
+* An AnnotationCollection _SHOULD_ have the `total` property.
+ Clients _SHOULD_ process the `total` property on an AnnotationCollection.
+* A Collection with Collection Pages _SHOULD_ have the `total` property.
+ Clients _SHOULD_ process the `total` property on a Collection.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "total": 1701 }
+```
+
+
+### transform
+{: #transform}
+
+An ordered list of 3D transform operations (translation, rotation, and scale) to be performed on a resource prior to painting that resource into a Scene. Transforms _MUST_ be applied to the resource in the order given. The resulting state of the resource after applying a transform _MUST_ be the input state for the subsequent transform in the ordered list. Therefore, transforms are not independent, and different orders of the same set of transforms can produce different results. The list of transforms _MAY_ include multiple transforms of the same type, e.g., multiple rotation operations.
+
+The value of this property _MUST_ be array of JSON objects, each of which _MUST_ be a Transform.
+
+* A Specific Resource _MAY_ have the `transform` property.
+ Clients _SHOULD_ process the `transform` property on Specific Resources.
+* Other classes _MUST NOT_ have the `transform` property.
+ Clients _MUST_ ignore the `transform` property on all other classes.
+
+{% include api/code_header.html %}
+```json
+{
+ "transform": [
+ {
+ "type": "RotateTransform",
+ "x": 0.0,
+ "y": 180.0,
+ "z": 0.0
+ }
+ ]
+}
+```
+
+### type
+{: #type}
+
+The type or class of the resource. For classes defined for this specification, the value of `type` will be described in the sections below describing each individual class.
+
+For content resources, the value of `type` is drawn from other specifications. Recommendations for common content types such as image, text or audio are given in the table below.
+
+The JSON objects that appear in the value of the `service` property will have many different classes, and can be used to distinguish the sort of service, with specific properties defined in a [registered context document][prezi30-ldce].
+
+The value _MUST_ be a string.
+
+ * All resource types _MUST_ have the `type` property.
+ Clients _MUST_ process, and _MAY_ render, `type` on any resource type.
+
+| Class | Description |
+| ------------- | -------------------------------- |
+| `Audio` | Auditory resources primarily intended to be heard, such as might be rendered with an <audio> HTML tag |
+| `Dataset` | Data not intended to be rendered to humans directly, such as a CSV, an RDF serialization or a zip file |
+| `Image` | Two dimensional visual resources primarily intended to be seen, such as might be rendered with an <img> HTML tag |
+| `Model` | A three dimensional spatial model intended to be visualized, such as might be rendered with a 3d javascript library |
+
+| `Text` | Resources primarily intended to be read |
+| `Video` | Moving images, with or without accompanying audio, such as might be rendered with a <video> HTML tag |
+{: .api-table #table-type}
+
+!!! note
+For compatibility with previous versions, clients _SHOULD_ accept `Sound` as a synonym for `Audio`.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "type": "Image" }
+```
+
+### unit
+
+The unit of measurement of a quantity expressed by a Quantity.
+
+The value _MUST_ be a string value. This specification defines the values in the table below. Others may be defined externally as an [extension][prezi30-ldce].
+
+| Value | Unit |
+|----------|-----------|
+| m | meters |
+| s | seconds |
+| relative | relative |
+
+* A Quantity _MUST_ have the `unit` property.
+ Clients _SHOULD_ process the `unit` property on Quantity instances.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "unit": "m" }
+```
+
+
+### value
+
+The `value` property is used in several situations to convey a value of a resource. The value is always string-based, however the strings might be wrapped in the language map construction.
+
+In the `metadata` and `requiredStatement` properties, the `value` property is used to record the text of the metadata field or statement. The value of the property in this case is a [language map](#language-of-property-values) represented as a JSON object, as previously described.
+
+Many selector classes use `value` to convey a string representation of the selection definition, such as `FragmentSelector` and `WktSelector`. The `TextualBody` similarly uses `value` to convey the string of the body of an Annotation. In these cases the value of `value` _MUST_ be a string.
+
+
+Language Map `value`:
+{% include api/code_header.html %}
+```json-doc
+{"value": { "en": [ "Example Description" ]}}
+```
+
+Selector or TextualBody `value`:
+{% include api/code_header.html %}
+```json-doc
+{ "value": "Example Textual Body" }
+```
+
+
+### via
+
+The `via` property of a resource _MAY_ be used to indicate one or more URIs which are the chain of sources from which the current resource was obtained. Each URI in the `via` list _MUST_ be different from the URI in `id`, but _MAY_ be the same as the URI in `canonical` if it is present. Recording `via` allows servers to provide the provenance chain of the resource, regardless of how many copy operations have occurred in the past.
+
+The value of the `via` property _MUST_ be an array of strings, and each string _MUST_ be a valid URI.
+
+* Any resource _MAY_ have the `via` property.
+ Clients _SHOULD_ process `via` on any resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "via": [ "https://example.com/manifests/6" ] }
+```
+
+
+### viewingDirection
+{: #viewingDirection}
+
+!!! Rewrite to be where is the navigation control to step to the next/ previous in the items of hte manifest
+
+
+The direction in which a list of Containers _SHOULD_ be displayed to the user. This specification defines four direction values in the table below. Others may be defined externally [as an extension][prezi30-ldce]. For example,
+if the `viewingDirection` value is `left-to-right`, then backwards in the list is to the left, and forwards in the
+list is to the right.
+
+The value _MUST_ be a string.
+
+ * A Collection _MAY_ have the `viewingDirection` property.
+ Clients _SHOULD_ process `viewingDirection` on a Collection.
+ * A Manifest _MAY_ have the `viewingDirection` property.
+ Clients _SHOULD_ process `viewingDirection` on a Manifest.
+ * A Range _MAY_ have the `viewingDirection` property.
+ Clients _MAY_ process `viewingDirection` on a Range.
+ * Other types of resource _MUST NOT_ have the `viewingDirection` property.
+ Clients _SHOULD_ ignore `viewingDirection` on other types of resource.
+
+| Value | Description |
+| ----- | ----------- |
+| `left-to-right` | The object is displayed from left to right. The default if not specified. |
+| `right-to-left` | The object is displayed from right to left. |
+| `top-to-bottom` | The object is displayed from the top to the bottom. |
+| `bottom-to-top` | The object is displayed from the bottom to the top. |
+{: .api-table #table-direction}
+
+{% include api/code_header.html %}
+``` json-doc
+{ "viewingDirection": "left-to-right" }
+```
+
+### volume
+{: #volume}
+
+The volume property represents the relative volume of an audio source. The `quantityValue` of the specified Quantity represents the desired volume on a linear scale from 0.0 (silence) to 1.0 (maximum volume). If this property is not specified, then the default volume value is client-dependent.
+
+The value of this property _MUST_ be a Quantity.
+The `unit` property of the Quantity _MUST_ be `relative`.
+The `value` property of the Quantity _MUST_ be between 0.0 and 1.0.
+
+* Audio resource types _SHOULD_ have the `volume` property.
+ Clients _SHOULD_ process the `volume` property on an Audio resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "volume": { "type": "Quantity", "unit": "relative", "quantityValue": 0.5 } }
+```
+
+
+### width
+{: #width}
+
+The width of the Canvas or external content resource. For content resources, the value is in pixels. For Canvases, the value does not have a unit. In combination with the height, it conveys an aspect ratio for the space in which content resources are located.
+
+The value _MUST_ be a positive integer.
+
+ * A Canvas _MUST_ have the `width` property.
+ Clients _MUST_ process `width` on a Canvas.
+ * Content resources _SHOULD_ have the `width` property, with the value given in pixels, if appropriate to the resource type.
+ Clients _SHOULD_ process `width` on content resources.
+ * Other types of resource _MUST NOT_ have the `width` property.
+ Clients _SHOULD_ ignore `width` on other types of resource.
+
+{% include api/code_header.html %}
+``` json-doc
+{ "width": 1200 }
+```
+
+### x
+{: #x}
+
+A number (floating point or integer) giving the x coordinate of the point, relative to the dimensions of the source resource
+
+
+{% include api/code_header.html %}
+``` json-doc
+{ "x": 100 }
+```
+
+### y
+{: #y}
+
+A number (floating point or integer) giving the y coordinate of the point, relative to the dimensions of the source resource
+
+
+
+{% include api/code_header.html %}
+``` json-doc
+{ "y": 100 }
+```
+
+### z
+{: #z}
+
+A number (floating point) giving the z coordinate of the point, relative to the dimensions of the source resource
+
+
+{% include api/code_header.html %}
+``` json-doc
+{ "z": 100 }
+```
+
+### 3.5. Values
+
+##### Values for motivation
+
+This specification defines two values for the Web Annotation property of `motivation`, or `purpose` when used on a Specific Resource or Textual Body.
+
+While any resource _MAY_ be the `target` of an Annotation, this specification defines only motivations for Annotations that target Canvases. These motivations allow clients to determine how the Annotation should be rendered, by distinguishing between Annotations that provide the content of the Canvas, from ones with externally defined motivations which are typically comments about the Canvas.
+
+Additional motivations may be added to the Annotation to further clarify the intent, drawn from [extensions][prezi30-ldce] or other sources. Clients _MUST_ ignore motivation values that they do not understand. Other motivation values given in the Web Annotation specification _SHOULD_ be used where appropriate, and examples are given in the [Presentation API Cookbook][annex-cookbook].
+
+| Value | Description |
+| ----- | ----------- |
+| `painting` | Resources associated with a Container by an Annotation that has the `motivation` value `painting` _MUST_ be presented to the user as the representation of the Container. The content can be thought of as being _of_ the Container. The use of this motivation with target resources other than Containers is undefined. For example, an Annotation that has the `motivation` value `painting`, a body of an Image and the target of a Canvas is an instruction to present that Image as (part of) the visual representation of the Canvas. Similarly, a textual body is to be presented as (part of) the visual representation of the Container and not positioned in some other part of the user interface.|
+| `supplementing` | Resources associated with a Container by an Annotation that has the `motivation` value `supplementing` _MAY_ be presented to the user as part of the representation of the Container, or _MAY_ be presented in a different part of the user interface. The content can be thought of as being _from_ the Container. The use of this motivation with target resources other than Containers is undefined. For example, an Annotation that has the `motivation` value `supplementing`, a body of an Image and the target of part of a Canvas is an instruction to present that Image to the user either in the Canvas's rendering area or somewhere associated with it, and could be used to present an easier to read representation of a diagram. Similarly, a textual body is to be presented either in the targeted region of the Container or otherwise associated with it, and might be OCR, a manual transcription or a translation of handwritten text, or captions for what is being said in a Timeline with audio content. |
+| `contentState` | An annotation with the motivation `contentState` has any valid IIIF Resource, or list of IIIF resources, or references to IIIF resources as its `target` property. The client either loads the resource(s) indicated by the Content State annotation `target`, or modifies the view of a currently loaded resource by applying the changes implied by the annotation target - for example, adding a new Light to a Scene where the Light is first introduced in the annotation `target`. The expected interaction depends on how the annotation is linked to the resource the client is currently rendering, or how the annotation is introduced to the client. The _Content State Protocol API 2.0_ describes the ways in which a Content State may be conveyed into a Client or exported from a Client, e.g., as an initialization parameter, or as an exported "Share..." state. Other parts (...) of this specification describe how a Content State in the context of a `commenting` or other annotation modifies the Container when the user selects that annotation, such as changing the camera, lighting or even the models in a Scene as the user progresses though the steps of a narrative conveyed by `describing` annotations. |
+| `activating` | An annotation with the motivation `activating` has any valid IIIF Resource, or list of IIIF resources, or references to IIIF resources as its `target` property. It indicates that a user interaction will trigger a change in either the Container itself, or play a named animation in a Model. If the `body` of the Annotation is of type `TextualBody` and the `target` is of type `SpecificResource` with a `selector` property of type `AnimationSelector`, then the client offers a UI such that when the user selects an interactive element labelled by the TextualBody, the named animation in the model painted by the `source` is played. If the `body` contains IIIF resources, then the body is interpreted as a Content State, and when the user interacts with the IIIF resource provided by the `target`, the content state is applied to modify the Container. |
+
+// See notes on activating in index
+
+{: .api-table #table-motivations}
+
+
+
+## JSON-LD and Extensions
+{: #json-ld-and-extensions}
+
+
+
+### Term Collisions between Contexts
+{: #term-collisions-between-contexts}
+
+There are some common terms used in more than one JSON-LD context document. Every attempt has been made to minimize these collisions, but some are inevitable. In order to know which specification is in effect at any given point, the class of the resource that has the property is the primary governing factor. Thus properties on Annotation based resources use the context from the [Web Annotation Data Model][org-w3c-webanno], whereas properties on classes defined by this specification use the IIIF Presentation API context's definition.
+
+There is one property that is in direct conflict - the `label` property is defined by both and is available for every resource. The use of `label` in IIIF follows modern best practices for internationalization by allowing the language to be associated with the value using the language map construction [described above][prezi30-languages], also allowing multiple languages to be used. The Web Annotation Data Model uses it only for [Annotation Collections][prezi30-annocoll], and mandates the format is a string. For this property, the API overrides the definition from the Annotation model to ensure that labels can consistently be represented in multiple languages.
+
+__Incompatibility Warning__
+The definition of `label` in the Web Annotation specification does not produce JSON conformant with the structure defined in this specification for languages. Given the absolute requirement for internationalized labels and the strong desire for consistently handling properties, the `label` property on Annotation model classes does not conform to the string requirement of the Web Annotation Data Model. This [issue has been filed with the W3C][github-webanno-437] and will hopefully be addressed in a future version of the standard.
+{: .warning}
+
+The following properties are defined by both, and the IIIF representation is more specific than the Web Annotation Data Model but are not in conflict, or are never used on the same resource:
+
+* `homepage`: In IIIF the home page of a resource is represented as a JSON object, whereas in the Web Annotation Data Model it can also be a string.
+* `type`: In IIIF the type is singular, whereas in the Web Annotation Data Model there can be more than one type.
+* `format`: In IIIF the format of a resource is also singular, whereas in the Web Annotation Data Model there can be more than one format.
+* `language`: In IIIF the `language` property always takes an array, whereas in the Web Annotation Data Model it can be a single string.
+* `start`: The `start` property is used on a Manifest to refer to the start Canvas or part of a Canvas and thus is a JSON object, whereas in the Web Annotation Data Model it is used on a TextPositionSelector to give the start offset into the textual content and is thus an integer.
+
+The `rights`, `partOf`, and `items` properties are defined by both in the same way.
+
+### Keyword Mappings
+
+The JSON-LD keywords `@id`, `@type` and `@none` are mapped to `id`, `type` and `none` by the Presentation API [linked data context][prezi30-ldce]. Thus in content conforming to this version of the Presentation API, the only JSON key beginning with `@` will be `@context`. However, the content may include data conforming to older specifications or external specifications that use keywords beginning with `@`. Clients should expect to encounter both syntaxes.
+
+### Registries of Values
+
+FIXME: Describe the registries
+
+{: #scrolly-mc-scroll-face}
diff --git a/source/presentation/4.0/presentation_data_model.png b/source/presentation/4.0/presentation_data_model.png
new file mode 100644
index 000000000..fd0ae407b
Binary files /dev/null and b/source/presentation/4.0/presentation_data_model.png differ
diff --git a/source/presentation/4.0/scratch.md b/source/presentation/4.0/scratch.md
new file mode 100644
index 000000000..4091dccf7
--- /dev/null
+++ b/source/presentation/4.0/scratch.md
@@ -0,0 +1,37 @@
+
+In the example Manifest above the first Container is a Timeline. One content resource, an MP3 file, is associated with the Timeline via a Painting Annotation for its entire duration. Typically the duration of the Timeline matches the duration of its content. This is the simplest time-based use case. The `target` property of the Painting Annotation is the whole Timeline, because it is simply the `id` of the Timeline without further qualification. In this simple case, playing the Timeline is the same as playing the MP3.
+
+The second Container is a Canvas, representing a 2D surface. In this case the Canvas represents an artwork, and there is no duration property. The content resource, a JPEG image of the artwork, is associated with the Canvas via a Painting Annotation. The unit integer coordinates of the Canvas (12000 x 9000) are not the same as the pixel dimensions of the JPEG image (4000 x 3000), but they are proportional - the Canvas has a 4:3 landscape aspect ratio, and so does the JPEG image. The `target` property of the Annotation is the Canvas `id`, unqualified by any particular region; this is taken to mean the content (the image) should fill the Canvas completely. As the Canvas and the image are the same aspect ratio, no distortion will occur. This approach allows the current image to be replaced by a higher resolution image in future, on the same Canvas. The Canvas dimensions establish a coordinate system for _painting annotations_ and other kinds of annotation that link content with the Canvas; they are not pixels of images.
+
+The third Container is a Scene. Unlike a Canvas, it is not a bounded spatial extent, but may be a bounded temporal extent if it has the optional duration property. It still establishes a coordinate space (x, y, z) but doesn't need any spatial properties to do so as it is always the same, infinite unbounded space. The Annotation paints the astronaut model into the Scene. As no further qualification is given, the astronaut model is placed at the (0,0,0) origin of the Scene. Later examples will show how to control the lighting and camera position(s) and properties, but this is not required; a IIIF viewer is expected to supply ambient light and a default camera position in the absence of specific values.
+
+
+This requires careful consideration of the URI schemes for `id` properties of Containers and their Manifests to ensure they remain referenceable in the future.
+
+
+use this in an example:
+The point around which RotateTransform rotates the space is the origin. This "pivot point" cannot be changed directly, but instead a TranslateTransform can be used to move the desired pivot point to the be at the origin, then the RotateTransform applied.
+
+
+
+
+ "body": [
+ {
+ "type": "TextualBody",
+ "value": "A label for the activation may be provided as a TextualBody"
+ },
+ {
+ "type": "SpecificResource",
+ "source": {
+ "id": "https://example.org/iiif/scene1/scene-with-activation",
+ "type": "Scene"
+ },
+ "transform": [
+ {
+ "type": "PropertyTransform",
+ "propertyName": "backgroundColor",
+ "propertyValue": "#FF99AA"
+ }
+ ]
+ }
+ ],
\ No newline at end of file
diff --git a/source/presentation/4/context.json b/source/presentation/4/context.json
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/source/presentation/4/context.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/source/registry/profiles/index.md b/source/registry/profiles/index.md
index 8c38c1130..79c524561 100644
--- a/source/registry/profiles/index.md
+++ b/source/registry/profiles/index.md
@@ -68,7 +68,7 @@ This table summarizes the known profiles available, for use with the [Presentati
| http://www.loc.gov/standards/alto | The URI for identifying [ALTO](https://www.loc.gov/standards/alto/) which is used for encoding OCR text. |
| http://www.loc.gov/standards/marcxml | The URI for identifying [MarcXML](https://www.loc.gov/standards/marcxml/) metadata records. |
| http://purl.org/dc/terms/ | The URI for identifying records that follow the [Dublin Core Metadata Initiative Metadata Terms](https://www.dublincore.org/specifications/dublin-core/dcmi-terms/) (NB: these are different from the legacy Dublin Core Metadata Element Set, Version 1.1, refered to as http://purl.org/dc/elements/1.1/). |
-| http://www.europeana.eu/schemas/edm/ | The URI for identifying [EDM (Europeana Data Model)](https://pro.europeana.eu/page/edm-documentation) metadata records. |
+| https://www.europeana.eu/schemas/edm/ | The URI for identifying [EDM (Europeana Data Model)](https://pro.europeana.eu/page/edm-documentation) metadata records. |
{: .api-table}