├── .gitignore
├── LICENSE
├── README.md
├── build.sbt
├── downloads
├── LICENSE.md
├── README.md
├── cite-1.15.0.html
├── citeApp-js
│ ├── Control.FullScreen.css
│ ├── Control.FullScreen.js
│ ├── citeImage.js
│ ├── images
│ │ ├── 161728.png
│ │ ├── button_grouphover.png
│ │ ├── button_hover.png
│ │ ├── button_pressed.png
│ │ ├── button_rest.png
│ │ ├── fullpage_grouphover.png
│ │ ├── fullpage_hover.png
│ │ ├── fullpage_pressed.png
│ │ ├── fullpage_rest.png
│ │ ├── guidehorizontal_grouphover.png
│ │ ├── guidehorizontal_hover.png
│ │ ├── guidehorizontal_pressed.png
│ │ ├── guidehorizontal_rest.png
│ │ ├── guidevertical_grouphover.png
│ │ ├── guidevertical_hover.png
│ │ ├── guidevertical_pressed.png
│ │ ├── guidevertical_rest.png
│ │ ├── home_grouphover.png
│ │ ├── home_hover.png
│ │ ├── home_pressed.png
│ │ ├── home_rest.png
│ │ ├── icon-fullscreen-2x.png
│ │ ├── icon-fullscreen.png
│ │ ├── img_254851.png
│ │ ├── next_grouphover.png
│ │ ├── next_hover.png
│ │ ├── next_pressed.png
│ │ ├── next_rest.png
│ │ ├── previous_grouphover.png
│ │ ├── previous_hover.png
│ │ ├── previous_pressed.png
│ │ ├── previous_rest.png
│ │ ├── rotateleft_grouphover.png
│ │ ├── rotateleft_hover.png
│ │ ├── rotateleft_pressed.png
│ │ ├── rotateleft_rest.png
│ │ ├── rotateright_grouphover.png
│ │ ├── rotateright_hover.png
│ │ ├── rotateright_pressed.png
│ │ ├── rotateright_rest.png
│ │ ├── selection_cancel_grouphover.png
│ │ ├── selection_cancel_hover.png
│ │ ├── selection_cancel_pressed.png
│ │ ├── selection_cancel_rest.png
│ │ ├── selection_confirm_grouphover.png
│ │ ├── selection_confirm_hover.png
│ │ ├── selection_confirm_pressed.png
│ │ ├── selection_confirm_rest.png
│ │ ├── selection_grouphover.png
│ │ ├── selection_hover.png
│ │ ├── selection_pressed.png
│ │ ├── selection_rest.png
│ │ ├── zoomin_grouphover.png
│ │ ├── zoomin_hover.png
│ │ ├── zoomin_pressed.png
│ │ ├── zoomin_rest.png
│ │ ├── zoomout_grouphover.png
│ │ ├── zoomout_hover.png
│ │ ├── zoomout_pressed.png
│ │ └── zoomout_rest.png
│ ├── marked.min.js
│ ├── openseadragon-guides.js
│ ├── openseadragon-guides.js.map
│ ├── openseadragon.js
│ ├── openseadragon.js.map
│ ├── openseadragon.min.js
│ ├── openseadragon.min.js.map
│ └── textExtensions.js
└── image_archive
│ └── fufolio
│ └── papyri
│ └── 2018a
│ ├── POxy0017n2099a01.dzi
│ ├── POxy0017n2099a01.jpg
│ └── POxy0017n2099a01_files
│ ├── 0
│ └── 0_0.jpeg
│ ├── 1
│ └── 0_0.jpeg
│ ├── 2
│ └── 0_0.jpeg
│ ├── 3
│ └── 0_0.jpeg
│ ├── 4
│ └── 0_0.jpeg
│ ├── 5
│ └── 0_0.jpeg
│ ├── 6
│ └── 0_0.jpeg
│ ├── 7
│ └── 0_0.jpeg
│ ├── 8
│ └── 0_0.jpeg
│ ├── 9
│ ├── 0_0.jpeg
│ ├── 0_1.jpeg
│ ├── 1_0.jpeg
│ └── 1_1.jpeg
│ ├── 10
│ ├── 0_0.jpeg
│ ├── 0_1.jpeg
│ ├── 0_2.jpeg
│ ├── 1_0.jpeg
│ ├── 1_1.jpeg
│ ├── 1_2.jpeg
│ ├── 2_0.jpeg
│ ├── 2_1.jpeg
│ └── 2_2.jpeg
│ └── 11
│ ├── 0_0.jpeg
│ ├── 0_1.jpeg
│ ├── 0_2.jpeg
│ ├── 0_3.jpeg
│ ├── 0_4.jpeg
│ ├── 1_0.jpeg
│ ├── 1_1.jpeg
│ ├── 1_2.jpeg
│ ├── 1_3.jpeg
│ ├── 1_4.jpeg
│ ├── 2_0.jpeg
│ ├── 2_1.jpeg
│ ├── 2_2.jpeg
│ ├── 2_3.jpeg
│ ├── 2_4.jpeg
│ ├── 3_0.jpeg
│ ├── 3_1.jpeg
│ ├── 3_2.jpeg
│ ├── 3_3.jpeg
│ ├── 3_4.jpeg
│ ├── 4_0.jpeg
│ ├── 4_1.jpeg
│ ├── 4_2.jpeg
│ ├── 4_3.jpeg
│ └── 4_4.jpeg
├── project
├── build.properties
├── build.sbt
└── buildinfo.sbt
├── releases.md
├── scripts
├── InsecureChrome.lnk
├── dz2.sh
├── macOS_insecure_chrome.sh
└── make_ptiff_3.sh
└── src
└── main
├── resources
├── LICENSE.txt
├── application.css
├── cite-TEMPLATE1.html
├── cite-TEMPLATE2.html
├── citeApp-js
│ ├── Control.FullScreen.css
│ ├── Control.FullScreen.js
│ ├── citeImage.js
│ ├── images
│ │ ├── 161728.png
│ │ ├── button_grouphover.png
│ │ ├── button_hover.png
│ │ ├── button_pressed.png
│ │ ├── button_rest.png
│ │ ├── fullpage_grouphover.png
│ │ ├── fullpage_hover.png
│ │ ├── fullpage_pressed.png
│ │ ├── fullpage_rest.png
│ │ ├── guidehorizontal_grouphover.png
│ │ ├── guidehorizontal_hover.png
│ │ ├── guidehorizontal_pressed.png
│ │ ├── guidehorizontal_rest.png
│ │ ├── guidevertical_grouphover.png
│ │ ├── guidevertical_hover.png
│ │ ├── guidevertical_pressed.png
│ │ ├── guidevertical_rest.png
│ │ ├── home_grouphover.png
│ │ ├── home_hover.png
│ │ ├── home_pressed.png
│ │ ├── home_rest.png
│ │ ├── icon-fullscreen-2x.png
│ │ ├── icon-fullscreen.png
│ │ ├── img_254851.png
│ │ ├── next_grouphover.png
│ │ ├── next_hover.png
│ │ ├── next_pressed.png
│ │ ├── next_rest.png
│ │ ├── previous_grouphover.png
│ │ ├── previous_hover.png
│ │ ├── previous_pressed.png
│ │ ├── previous_rest.png
│ │ ├── rotateleft_grouphover.png
│ │ ├── rotateleft_hover.png
│ │ ├── rotateleft_pressed.png
│ │ ├── rotateleft_rest.png
│ │ ├── rotateright_grouphover.png
│ │ ├── rotateright_hover.png
│ │ ├── rotateright_pressed.png
│ │ ├── rotateright_rest.png
│ │ ├── selection_cancel_grouphover.png
│ │ ├── selection_cancel_hover.png
│ │ ├── selection_cancel_pressed.png
│ │ ├── selection_cancel_rest.png
│ │ ├── selection_confirm_grouphover.png
│ │ ├── selection_confirm_hover.png
│ │ ├── selection_confirm_pressed.png
│ │ ├── selection_confirm_rest.png
│ │ ├── selection_grouphover.png
│ │ ├── selection_hover.png
│ │ ├── selection_pressed.png
│ │ ├── selection_rest.png
│ │ ├── zoomin_grouphover.png
│ │ ├── zoomin_hover.png
│ │ ├── zoomin_pressed.png
│ │ ├── zoomin_rest.png
│ │ ├── zoomout_grouphover.png
│ │ ├── zoomout_hover.png
│ │ ├── zoomout_pressed.png
│ │ └── zoomout_rest.png
│ ├── marked.min.js
│ ├── openseadragon-guides.js
│ ├── openseadragon-guides.js.map
│ ├── openseadragon.js
│ ├── openseadragon.js.map
│ ├── openseadragon.min.js
│ ├── openseadragon.min.js.map
│ └── textExtensions.js
├── index-dev.html
├── index-opt.html
└── million.cex
└── scala
└── citeappscalajs
├── CitableImageModel.scala
├── CiteBinaryImageController.scala
├── CiteBinaryImageModel.scala
├── CiteBinaryImageView.scala
├── CiteMain.scala
├── CiteMainController.scala
├── CiteMainModel.scala
├── CiteMainView.scala
├── CommentaryModel.scala
├── DSEModel.scala
├── DataModelController.scala
├── DataModelModel.scala
├── DataModelView.scala
├── ExtendedTextPropertyView.scala
├── ImageRoiModel.scala
├── NGController.scala
├── NGModel.scala
├── NGView.scala
├── O2Controller.scala
├── O2Model.scala
├── O2View.scala
├── ObjectController.scala
├── ObjectModel.scala
├── ObjectView.scala
├── QueryObjectController.scala
├── QueryObjectModel.scala
├── QueryObjectView.scala
├── RelationsController.scala
├── RelationsModel.scala
└── RelationsView.scala
/.gitignore:
--------------------------------------------------------------------------------
1 | ### SBT template
2 | # Simple Build Tool
3 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
4 |
5 | target/
6 | lib_managed/
7 | src_managed/
8 | project/boot/
9 | .history
10 | .cache
11 | local.sbt
12 |
13 | *.DS_Store
14 |
15 | # sbteclipse plugin
16 | .target
17 |
18 | # TeXlipse plugin
19 | .texlipse
20 | ### Vim template
21 | [._]*.s[a-w][a-z]
22 | [._]s[a-w][a-z]
23 | *.un~
24 | Session.vim
25 | .netrwhist
26 | *~
27 | ### Scala template
28 | *.class
29 | *.log
30 |
31 | # sbt specific
32 | .cache
33 | .history
34 | .lib/
35 | dist/*
36 | target/
37 | lib_managed/
38 | src_managed/
39 | project/boot/
40 | project/plugins/project/
41 |
42 |
43 | *.iml
44 |
45 | ## Directory-based project format:
46 | .idea/
47 | # if you remove the above rule, at least ignore the following:
48 |
49 | # User-specific stuff:
50 | # .idea/workspace.xml
51 | # .idea/tasks.xml
52 | # .idea/dictionaries
53 |
54 | # Sensitive or high-churn files:
55 | # .idea/dataSources.ids
56 | # .idea/dataSources.xml
57 | # .idea/sqlDataSources.xml
58 | # .idea/dynamic.xml
59 | # .idea/uiDesigner.xml
60 |
61 | # Gradle:
62 | # .idea/gradle.xml
63 | # .idea/libraries
64 |
65 | # Mongo Explorer plugin:
66 | # .idea/mongoSettings.xml
67 |
68 | ## File-based project format:
69 | *.ipr
70 | *.iws
71 |
72 | ## Plugin-specific files:
73 |
74 | # IntelliJ
75 | /out/
76 |
77 | # mpeltonen/sbt-idea plugin
78 | .idea_modules/
79 |
80 | # JIRA plugin
81 | atlassian-ide-plugin.xml
82 |
83 | # Crashlytics plugin (for Android Studio and IntelliJ)
84 | com_crashlytics_export_strings.xml
85 | crashlytics.properties
86 | crashlytics-build.properties
87 | .cache-main
88 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |            
4 |
5 | # CITE Application
6 |
7 | A single-page browser application for exploring citable resources, written in [Scala.js](http://www.scala-js.org/).
8 |
9 | ## Current version: 1.16.0
10 |
11 | See [release notes](releases.md).
12 |
13 | ## License
14 |
15 | [GPL 3.0](https://opensource.org/licenses/gpl-3.0.html)
16 |
17 | CITE Application, by default, downloads a sample corpus of texts. Licensing and attribution for those texts is available in the [downloads directory](downloads).
18 |
19 | ## Using
20 |
21 | CITE Application is a single web page you can open in a browser. Precompiled versions are available in the [downloads directory](downloads), and named `cite-VERSION.html`.
22 |
23 | **N.b.** In the `downloads` directory there is a `js` directory that CiteApp uses for providing zooming views of binary images, using [OpenSeadragon](https://openseadragon.github.io).
24 |
25 | **Images not working?** You probably need to deal with browser restrictions. See the [Wiki page on this topic](https://github.com/cite-architecture/CITE-App/wiki/Local-File-and-Cross-Domain-Restrictions).
26 |
27 | ## Building
28 |
29 | CITE Application is targetted for Scala 2.12.You can use normal `sbt` using normal tasks for [ScalaJS projects](https://www.scala-js.org/doc/project/building.html) such as `sbt fastOptJS` or `sbt fullOptJS`.
30 |
31 | If `sbt fastOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-dev.html` in your browser.
32 |
33 | If `sbt fullOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-opt.html` in your browser.
34 |
35 | In addition, the project defines a custom `spa` task that builds a single-page application named `cite-VERSION.html` (where `VERSION` is the current version defined in `build.sbt`), in the `downloads` directory.
36 |
37 | If `sbt fastOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-dev.html` in your browser.
38 |
39 | If `sbt fullOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-opt.html` in your browser.
40 |
41 | ## Images for CiteApp
42 |
43 | Documentation for configuring collections of images for CiteApp is underway at .
44 |
45 | The `downloads/image_archive` directory contains a one-image sample setup showing how to implement URN-aware DeepZoom images.
46 |
47 | ## Python SimpleServer
48 |
49 | Running CiteApp locally, and attempting to access images, can run afoul of the Cross-Origin-Restrictions (CORS). It may be possible to tell your browser to ignore that security precaution. Or, a safer alternative, is to serve CiteApp locally. If Python is installed, navigate to the directory that contains `cite-VERSION.html`, and execute:
50 |
51 | `python -m SimpleHTTPServer`
52 |
53 | ## Credits
54 |
55 | CITEApplication, © 2017, 2018, 2019: Neel Smith and Christopher Blackwell. Available for use, modification, and distribution under the terms of the [GPL 3.0](https://opensource.org/licenses/gpl-3.0.html) license. Based on the [CITE and CTS protocols](http://cite-architecture.github.io), by Neel Smith and Christopher Blackwell.
56 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | enablePlugins(ScalaJSPlugin, BuildInfoPlugin)
2 |
3 | name := "citeapp"
4 |
5 | version := "1.16.0"
6 |
7 | scalaVersion := "2.12.8"
8 |
9 | resolvers += Resolver.jcenterRepo
10 | resolvers += Resolver.bintrayRepo("neelsmith", "maven")
11 | resolvers += sbt.Resolver.bintrayRepo("denigma", "denigma-releases")
12 |
13 | libraryDependencies ++= Seq(
14 | "org.scala-js" %% "scalajs-stubs" % scalaJSVersion % "provided",
15 | "org.scala-js" %%% "scalajs-dom" % "0.9.7",
16 | "io.monix" %%% "monix" % "2.3.3",
17 | "edu.holycross.shot.cite" %%% "xcite" % "4.2.0",
18 | "edu.holycross.shot" %%% "ohco2" % "10.18.2",
19 | "edu.holycross.shot" %%% "scm" % "7.2.0",
20 | "edu.holycross.shot" %%% "citeobj" % "7.4.0",
21 | "edu.holycross.shot" %%% "citerelations" % "2.6.0",
22 | "edu.holycross.shot" %%% "citebinaryimage" % "3.1.1",
23 | "edu.holycross.shot" %%% "dse" % "7.0.0",
24 | "com.github.karasiq" %%% "scalajs-marked" % "1.0.2",
25 | "com.thoughtworks.binding" %%% "dom" % "11.9.0+3-cadac35f"
26 | )
27 |
28 | addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
29 |
30 | //scalacOptions += "-P:scalajs:suppressExportDeprecations"
31 | //scalacOptions += "-P:scalajs:suppressMissingJSGlobalDeprecations"
32 | scalacOptions += "-unchecked"
33 | scalacOptions += "-deprecation"
34 |
35 | lazy val spa = taskKey[Unit]("Assemble single-page app from html templates and generated CSS and JS output")
36 |
37 | import scala.io.Source
38 | import java.io.PrintWriter
39 | spa := {
40 |
41 | // val defaultLibraryUrl = "https://raw.githubusercontent.com/cite-architecture/citedx/master/libraries/millionplus.cex"
42 | val defaultLibraryUrl = "https://raw.githubusercontent.com/Eumaeus/fuCiteDX/master/CEX_Tutorial/6_DataModel_DSE.cex"
43 | //val defaultLibraryUrl = "https://raw.githubusercontent.com/Eumaeus/fuCiteDX/master/fu-spring2018.cex"
44 | val serverMode = false
45 | val defaultLibraryDelimiter = "#"
46 | val defaultImagePath = "" // Path prefixed to the named directories for local images
47 |
48 | val compileFirst = (fullOptJS in Compile).value
49 |
50 | val junk = "//# sourceMappingURL=citeapp-opt.js.map"
51 | val js = Source.fromFile("target/scala-2.12/citeapp-opt.js").getLines.mkString("\n").replaceAll(junk,"")
52 |
53 | val css = Source.fromFile("target/scala-2.12/classes/application.css").getLines.mkString("\n")
54 |
55 | val template1 = "src/main/resources/cite-TEMPLATE1.html"
56 | val template1Text = Source.fromFile(template1).getLines.mkString("\n").replaceAll("ACTUALVERSION", version.value).replaceAll("ACTUALCSS",css)
57 |
58 |
59 | val urlPlaceholder = "DEFAULTLIBRARYURL"
60 | val delimiterPlaceholder = "DEFAULTLIBRARYDELIMITER"
61 | val imagePathPlaceholder = "DEFAULTIMAGEPATH"
62 | val serverModePlaceholder = "SERVERMODE"
63 |
64 | val template2Text = Source.fromFile("src/main/resources/cite-TEMPLATE2.html").getLines.mkString("\n").replaceAll(urlPlaceholder,defaultLibraryUrl).replaceAll(delimiterPlaceholder,defaultLibraryDelimiter).replaceAll(imagePathPlaceholder,defaultImagePath).replaceAll(serverModePlaceholder,serverMode.toString)
65 | val newFile = "downloads/cite-" + version.value + ".html"
66 | new PrintWriter(newFile) { write(template1Text + js + template2Text); close }
67 | println("Runnable single-page app is in " + newFile)
68 | }
69 |
70 | buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion)
71 | buildInfoPackage := "citeapp"
72 |
--------------------------------------------------------------------------------
/downloads/LICENSE.md:
--------------------------------------------------------------------------------
1 | # Licensing on Works
2 |
3 | ## Below is detailed licensing for the works included in the file `million.cex`.
4 |
5 | ## Quran
6 |
7 | The text of the Quran is version 1.0.2 from , distributed under the terms of a Creative Commons Attribution 3.0 License. To quote their terms of use:
8 |
9 | Permission is granted to copy and distribute verbatim copies
10 | of this text, but CHANGING IT IS NOT ALLOWED.
11 |
12 | This copyright notice shall be included in all verbatim copies
13 | of the text, and shall be reproduced appropriately in all files
14 | derived from or containing substantial portion of this text.
15 |
16 | ## Herodotus (English and Greek)
17 |
18 | The texts of Herodotus are from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License.
19 |
20 | ## Hafez
21 |
22 | The poetry of Hafez is from the Open Persian Project of Leipzig University, , Gregory Crane, Saeed Majidi, and Maryam Foradi, edd. Distributed under the terms of a Creative Commons 3.0 Attribution License.
23 |
24 | ## Plutarch (Greek)
25 |
26 | The Greek text of Plutarch is from the edition of Ziegler, published on Archive.org and released into the Public Domain. Preparation of this digital edition was funded by a grant from the Andrew W. Mellon Foundation.
27 |
28 | ## Plutarch (English)
29 |
30 | The English text of Plutarch is from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License.
31 |
32 | ## Latin Texts
33 |
34 | The Latin Texts are from Holy Cross Free Latin and Greek editions, distributed under the terms of the Creative Commons 3 Attribution-Share-Alike License, derived from Tesserae project edition (http://tesserae.caset.buffalo.edu/sources.php) derived from Perseus project edition (http://www.perseus.tufts.edu/hopper/collection?collection=Perseus%3Acollection%3AGreco-Roman)
35 |
36 | ## Licensing on Latin texts from CroALa
37 |
38 | All Latin texts from CroALa, the Croatiae auctores Latini bibliotheca electronica, Neven Jovanović, editor, are reproduced here in derivative versions, according to the terms of the Creative Commons Attribution 4.0 International License
39 |
40 | ## Licensing on Homer Multitext texts
41 |
42 | All texts from the Homer Multitext, Casey Dué and Mary Ebbott, edd., , are redistributed according to the terms of the Creative Commons Attribution, Non-Commercial 4.0 License .
43 |
--------------------------------------------------------------------------------
/downloads/README.md:
--------------------------------------------------------------------------------
1 | # CITEApp Download
2 |
3 | This directory includes compiled, optimized versions of the CITEApp, including all necessary CSS and javascript in a single `.html` file.
4 |
5 | ## Running
6 |
7 | - Double-click on `cite-VERSION.html` to open it in a browser.
8 | - If there is an active internet connection, the app will automatically fetch a digital library in `.cex` form.
9 |
10 | ## Running (Offline)
11 |
12 | - Prepare a `.cex` file to load, or get sample `.cex` libraries from [here](https://github.com/Eumaeus/cts-demo-corpus/tree/master/CEX-Files).
13 | - Double-click on `cite-VERSION.html` to open it in a browser.
14 | - Use the `Choose File` button at the to select and open a `.cex` file.
15 |
16 | ## Reference
17 |
18 | This app is based on the [CITE Architecture](http://cite-architecture.github.io), a protocol for identification and retrieval of data via machine-actional canonical citations in URN format.
19 |
20 | CITE/CTS is ©2002–2017 Neel Smith and Christopher Blackwell. This implementation of the CITE data models was written by Neel Smith and Christopher Blackwell using Scala, Scala-JS, and Binding.scala. Licensed under the GPL 3.0. Sourcecode on GitHub.
21 |
--------------------------------------------------------------------------------
/downloads/citeApp-js/Control.FullScreen.css:
--------------------------------------------------------------------------------
1 | .fullscreen-icon { background-image: url(images/icon-fullscreen.png); }
2 | .leaflet-retina .fullscreen-icon { background-image: url(images/icon-fullscreen-2x.png); background-size: 26px 26px; }
3 | /* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */
4 | .leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
5 | .leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
6 | .leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
7 | .leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
8 | .leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; }
9 |
--------------------------------------------------------------------------------
/downloads/citeApp-js/Control.FullScreen.js:
--------------------------------------------------------------------------------
1 | (function () {
2 |
3 | L.Control.FullScreen = L.Control.extend({
4 | options: {
5 | position: 'topleft',
6 | title: 'Full Screen',
7 | titleCancel: 'Exit Full Screen',
8 | forceSeparateButton: false,
9 | forcePseudoFullscreen: false,
10 | fullscreenElement: false
11 | },
12 |
13 | onAdd: function (map) {
14 | var className = 'leaflet-control-zoom-fullscreen', container, content = '';
15 |
16 | if (map.zoomControl && !this.options.forceSeparateButton) {
17 | container = map.zoomControl._container;
18 | } else {
19 | container = L.DomUtil.create('div', 'leaflet-bar');
20 | }
21 |
22 | if (this.options.content) {
23 | content = this.options.content;
24 | } else {
25 | className += ' fullscreen-icon';
26 | }
27 |
28 | this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);
29 |
30 | this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this);
31 |
32 | return container;
33 | },
34 |
35 | _createButton: function (title, className, content, container, fn, context) {
36 | this.link = L.DomUtil.create('a', className, container);
37 | this.link.href = '#';
38 | this.link.title = title;
39 | this.link.innerHTML = content;
40 |
41 | L.DomEvent
42 | .addListener(this.link, 'click', L.DomEvent.stopPropagation)
43 | .addListener(this.link, 'click', L.DomEvent.preventDefault)
44 | .addListener(this.link, 'click', fn, context);
45 |
46 | L.DomEvent
47 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
48 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
49 | .addListener(container, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context);
50 |
51 | L.DomEvent
52 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
53 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
54 | .addListener(document, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context);
55 |
56 | return this.link;
57 | },
58 |
59 | toggleFullScreen: function () {
60 | var map = this._map;
61 | map._exitFired = false;
62 | if (map._isFullscreen) {
63 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
64 | fullScreenApi.cancelFullScreen();
65 | } else {
66 | L.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
67 | }
68 | map.fire('exitFullscreen');
69 | map._exitFired = true;
70 | map._isFullscreen = false;
71 | }
72 | else {
73 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
74 | fullScreenApi.requestFullScreen(this.options.fullscreenElement ? this.options.fullscreenElement : map._container);
75 | } else {
76 | L.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
77 | }
78 | map.fire('enterFullscreen');
79 | map._isFullscreen = true;
80 | }
81 | },
82 |
83 | _toggleTitle: function () {
84 | this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
85 | },
86 |
87 | _handleFullscreenChange: function () {
88 | var map = this._map;
89 | map.invalidateSize();
90 | if (!fullScreenApi.isFullScreen() && !map._exitFired) {
91 | map.fire('exitFullscreen');
92 | map._exitFired = true;
93 | map._isFullscreen = false;
94 | }
95 | }
96 | });
97 |
98 | L.Map.addInitHook(function () {
99 | if (this.options.fullscreenControl) {
100 | this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions);
101 | this.addControl(this.fullscreenControl);
102 | }
103 | });
104 |
105 | L.control.fullscreen = function (options) {
106 | return new L.Control.FullScreen(options);
107 | };
108 |
109 | /*
110 | Native FullScreen JavaScript API
111 | -------------
112 | Assumes Mozilla naming conventions instead of W3C for now
113 |
114 | source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/
115 |
116 | */
117 |
118 | var
119 | fullScreenApi = {
120 | supportsFullScreen: false,
121 | isFullScreen: function () { return false; },
122 | requestFullScreen: function () {},
123 | cancelFullScreen: function () {},
124 | fullScreenEventName: '',
125 | prefix: ''
126 | },
127 | browserPrefixes = 'webkit moz o ms khtml'.split(' ');
128 |
129 | // check for native support
130 | if (typeof document.exitFullscreen !== 'undefined') {
131 | fullScreenApi.supportsFullScreen = true;
132 | } else {
133 | // check for fullscreen support by vendor prefix
134 | for (var i = 0, il = browserPrefixes.length; i < il; i++) {
135 | fullScreenApi.prefix = browserPrefixes[i];
136 | if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') {
137 | fullScreenApi.supportsFullScreen = true;
138 | break;
139 | }
140 | }
141 | if (typeof document['msExitFullscreen'] !== 'undefined') {
142 | fullScreenApi.prefix = 'ms';
143 | fullScreenApi.supportsFullScreen = true;
144 | }
145 | }
146 |
147 | // update methods to do something useful
148 | if (fullScreenApi.supportsFullScreen) {
149 | if (fullScreenApi.prefix === 'ms') {
150 | fullScreenApi.fullScreenEventName = 'MSFullscreenChange';
151 | } else {
152 | fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
153 | }
154 | fullScreenApi.isFullScreen = function () {
155 | switch (this.prefix) {
156 | case '':
157 | return document.fullscreen;
158 | case 'webkit':
159 | return document.webkitIsFullScreen;
160 | case 'ms':
161 | return document.msFullscreenElement;
162 | default:
163 | return document[this.prefix + 'FullScreen'];
164 | }
165 | };
166 | fullScreenApi.requestFullScreen = function (el) {
167 | switch (this.prefix) {
168 | case '':
169 | return el.requestFullscreen();
170 | case 'ms':
171 | return el.msRequestFullscreen();
172 | default:
173 | return el[this.prefix + 'RequestFullScreen']();
174 | }
175 | };
176 | fullScreenApi.cancelFullScreen = function () {
177 | switch (this.prefix) {
178 | case '':
179 | return document.exitFullscreen();
180 | case 'ms':
181 | return document.msExitFullscreen();
182 | default:
183 | return document[this.prefix + 'CancelFullScreen']();
184 | }
185 | };
186 | }
187 |
188 | // jQuery plugin
189 | if (typeof jQuery !== 'undefined') {
190 | jQuery.fn.requestFullScreen = function () {
191 | return this.each(function () {
192 | var el = jQuery(this);
193 | if (fullScreenApi.supportsFullScreen) {
194 | fullScreenApi.requestFullScreen(el);
195 | }
196 | });
197 | };
198 | }
199 |
200 | // export api
201 | window.fullScreenApi = fullScreenApi;
202 | })();
203 |
--------------------------------------------------------------------------------
/downloads/citeApp-js/citeImage.js:
--------------------------------------------------------------------------------
1 | // Variables to hold the current image URN and an array of ROIs
2 |
3 |
4 | var viewer = null
5 | var roiArray =[]
6 |
7 | /*
8 | classes:
9 |
10 | image_mappedUrn
11 | image_mappedROI
12 | image_roiGroup_1
13 | image_roi_selected
14 |
15 | */
16 |
17 | /*
18 | function imageInNewWindow(c) {
19 | console.log("Got here… opening " )
20 | var w = c.width;
21 | console.log(w);
22 | var h = c.height;
23 | console.log(h);
24 | var u = c.toDataURL();
25 | window.open(u, "Image", "width=200, height=200");
26 | }
27 | */
28 |
29 | function idForMappedUrn(i) {
30 | var s = "image_mappedUrn_" + (i)
31 | return s
32 | }
33 |
34 | function idForMappedROI(i) {
35 | var s = "image_mappedROI_" + (i)
36 | return s
37 | }
38 |
39 | function roiToUrnId(id) {
40 | var s = id.replace("image_mappedROI_","image_mappedUrn_")
41 | return s
42 | }
43 |
44 |
45 | function clearJsRoiArray(r) {
46 | roiArray = []
47 | }
48 |
49 | function addToJsRoiArray(i,r,u,g){
50 | tempMap = {index: i, roi: r, mappedUrn: u, group: g}
51 | roiArray.push(tempMap)
52 | }
53 |
54 | function clearSelectedROIs(){
55 | for (n = 0; n < (roiArray.length - 1); n++){
56 | var roiId = idForMappedROI(n+1)
57 | var urnId = idForMappedUrn(n+1)
58 | var thisROI = document.getElementById(roiId)
59 | var thisURN = document.getElementById(urnId)
60 | thisROI.classList.remove("image_roi_selected")
61 | thisURN.classList.remove("image_roi_selected")
62 | }
63 | }
64 |
65 | function updateImageJS(collection, imageObject, path ){
66 | //var collDirectory = collection.replace(new RegExp(':', 'g'), '_');
67 | //var imagePath = "../../../image_archive/" + collDirectory + "/" + imageObject + ".dzi"
68 | initOpenSeadragon(path)
69 | }
70 |
71 | /**
72 | * Normalizes the index of the ROI to a number within the given amount of
73 | * colors. E.g. If there were only two colors, an index of 4 would return group
74 | * number 0 => (index % colorLength)
75 | * @param {int} i index number
76 | * @return {int} normalized group number
77 | */
78 | function getGroup(i){
79 | var colorArray = ["#f23568", "#6d38ff", "#38ffd7", "#fff238", "#661641", "#275fb3", "#24a669", "#a67b24", "#ff38a2", "#194973", "#35f268", "#7f441c", "#801c79", "#2a8ebf", "#216616", "#d97330", "#da32e6", "#196d73", "#bdff38", "#bf3e2a", "#3d1973", "#30cdd9", "#858c1f", "#661616" ];
80 | var limit = colorArray.length
81 | var rv = i % limit;
82 | return rv;
83 | }
84 |
85 | function initOpenSeadragon(imagePath) {
86 | //console.log(imagePath)
87 |
88 | if (viewer != null){
89 | viewer.destroy();
90 | viewer = null
91 | }
92 |
93 | viewer = OpenSeadragon({
94 | id: 'image_zoomContainer',
95 | prefixUrl: 'citeApp-js/images/',
96 | crossOriginPolicy: "Anonymous",
97 | ajaxWithCredentials: false,
98 | defaultZoomLevel: 1,
99 | tileSources: imagePath,
100 | //tileSources: 'http://www.homermultitext.org/iipsrv?DeepZoom=/project/homer/pyramidal/deepzoom/hmt/vaimg/2017a/VA024RN_0025.tif.dzi',
101 | minZoomImageRatio: 0.25, // of viewer size
102 | immediateRender: true
103 | });
104 |
105 | viewer.guides({
106 | allowRotation: false, // Make it possible to rotate the guidelines (by double clicking them)
107 | horizontalGuideButton: null, // Element for horizontal guideline button
108 | verticalGuideButton: null, // Element for vertical guideline button
109 | prefixUrl: "citeApp-js/images/", // Images folder
110 | removeOnClose: false, // Remove guidelines when viewer closes
111 | useSessionStorage: false, // Save guidelines in sessionStorage
112 | navImages: {
113 | guideHorizontal: {
114 | REST: 'guidehorizontal_rest.png',
115 | GROUP: 'guidehorizontal_grouphover.png',
116 | HOVER: 'guidehorizontal_hover.png',
117 | DOWN: 'guidehorizontal_pressed.png'
118 | },
119 | guideVertical: {
120 | REST: 'guidevertical_rest.png',
121 | GROUP: 'guidevertical_grouphover.png',
122 | HOVER: 'guidevertical_hover.png',
123 | DOWN: 'guidevertical_pressed.png'
124 | }
125 | }
126 | });
127 |
128 |
129 | // Add overlays
130 | setTimeout(function(){
131 | if (viewer.world.getItemAt(0)){
132 | //console.log("defined");
133 | } else {
134 | //console.log("undefined");
135 | }
136 | var baseTimer = 0;
137 | while( !(viewer.world.getItemAt(0))){
138 | baseTimer = baseTimer + 1;
139 | }
140 | //console.log(baseTimer);
141 | var normH = viewer.world.getItemAt(0).getBounds().height;
142 | var normW = viewer.world.getItemAt(0).getBounds().width;
143 | if (roiArray.length > 0){
144 | for (ol = 0; ol < roiArray.length; ol++){
145 | var roi = roiArray[ol].roi
146 | var rl = +roi.split(",")[0]
147 | var rt = +roi.split(",")[1]
148 | var rw = +roi.split(",")[2]
149 | var rh = +roi.split(",")[3]
150 | var tl = rl * normW
151 | var tt = rt * normH
152 | var tw = rw * normW
153 | var th = rh * normH
154 | var osdRect = new OpenSeadragon.Rect(tl,tt,tw,th)
155 | var elt = document.createElement("a")
156 | elt.id = idForMappedROI(roiArray[ol].index)
157 | elt.className = "image_mappedROI" + " image_roiGroup_" + roiArray[ol].group + " " + idForMappedUrn(roiArray[ol].index)
158 | elt.dataset.urn = roiArray[ol].mappedUrn
159 |
160 | viewer.addOverlay(elt,osdRect)
161 | }
162 | }
163 |
164 | // Go through and attach events to each overlay
165 | for (n = 0; n < roiArray.length; n++){
166 | var captureN = n // because N keeps moving
167 | var thisId = idForMappedROI(roiArray[n].index)
168 | var thisElement = document.getElementById(thisId)
169 | thisElement.addEventListener("click", function(e) {
170 | clearSelectedROIs()
171 | var roiId = e.target.id
172 | var targetId = roiToUrnId(roiId)
173 | var targetSpan = document.getElementById(targetId)
174 | targetSpan.classList.add("image_roi_selected")
175 | e.target.classList.add("image_roi_selected")
176 | }, false);
177 | }
178 | },6000);
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/161728.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/161728.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/button_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/button_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/button_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/button_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/fullpage_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/fullpage_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/fullpage_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/fullpage_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidehorizontal_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidehorizontal_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidehorizontal_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidehorizontal_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidevertical_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidevertical_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidevertical_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/guidevertical_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/home_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/home_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/home_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/home_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/icon-fullscreen-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/icon-fullscreen-2x.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/icon-fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/icon-fullscreen.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/img_254851.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/img_254851.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/next_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/next_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/next_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/next_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/previous_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/previous_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/previous_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/previous_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateleft_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateleft_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateleft_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateright_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateright_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/rotateright_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_cancel_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_cancel_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_cancel_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_cancel_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_confirm_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_confirm_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_confirm_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_confirm_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/selection_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomin_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomin_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomin_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomin_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomout_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_grouphover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomout_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_hover.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomout_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_pressed.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/images/zoomout_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_rest.png
--------------------------------------------------------------------------------
/downloads/citeApp-js/openseadragon-guides.js:
--------------------------------------------------------------------------------
1 | !function(e){function t(n){if(i[n])return i[n].exports;var s=i[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,t),s.l=!0,s.exports}var i={};return t.m=e,t.c=i,t.i=function(e){return e},t.d=function(e,t,i){Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=3)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.$=OpenSeadragon,t.DIRECTION_HORIZONTAL=Symbol("horizontal"),t.DIRECTION_VERTICAL=Symbol("vertical")},function(e,t,i){"use strict";function n(e,t,i,n,s){var d=n===a.DIRECTION_HORIZONTAL?"horizontal":"vertical",l=o(),u=l.find(function(t){return t.id===e});u?(u.x=t,u.y=i,u.rotation=s):l.push({id:e,x:t,y:i,direction:d,rotation:s}),r(l)}function s(e){var t=o();r(t.filter(function(t){return t.id!==e}))}function o(){var e=window.sessionStorage.getItem(l);return e?JSON.parse(e):[]}function r(e){window.sessionStorage.setItem(l,JSON.stringify(e))}Object.defineProperty(t,"__esModule",{value:!0});var a=i(0),d=!1,l="openseadragon-guides";t.default={addGuide:n,deleteGuide:s,getGuides:o,useStorage:d}},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){var i=document.createElement("div");switch(i.id="osd-guide-"+t,i.classList.add("osd-guide"),e){case d.DIRECTION_HORIZONTAL:i.classList.add("osd-guide-horizontal");break;case d.DIRECTION_VERTICAL:i.classList.add("osd-guide-vertical");break;default:throw new Error("Invalid guide direction")}return i}function r(){var e=document.createElement("div");return e.classList.add("osd-guide-line"),e}Object.defineProperty(t,"__esModule",{value:!0}),t.Guide=void 0;var a=function(){function e(e,t){for(var i=0;i","").replace("
","")
6 | document.getElementById(elementId).innerHTML = parsedMarkdown;
7 | },1000);
8 | }
9 |
10 | function initiateLeafletWithLatLong(lat, long, elementId) {
11 | setTimeout(function(){
12 | var latitude = parseFloat(lat);
13 | var longitude = parseFloat(long);
14 | var mymap = L.map(elementId).setView([latitude, longitude], 13);
15 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
16 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
17 | maxZoom: 18,
18 | id: 'mapbox.satellite',
19 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ'
20 | }).addTo(mymap);
21 | var marker = L.marker([latitude, longitude]).addTo(mymap);
22 | },1000);
23 | }
24 |
25 | function initiateLeafletWithGeoJson(geojson, elementId) {
26 | setTimeout(function(){
27 | var myFeature = JSON.parse(geojson);
28 | var mymap = L.map(elementId).setView([0, 0], 20);
29 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
30 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
31 | maxZoom: 18,
32 | id: 'mapbox.satellite',
33 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ'
34 | }).addTo(mymap);
35 | var gjFeature = L.geoJSON(myFeature)
36 | gjFeature.addTo(mymap);
37 | mymap.fitBounds(gjFeature.getBounds());
38 | mymap.zoomOut(3);
39 |
40 | // create a fullscreen button and add it to the map
41 | L.control.fullscreen({
42 | position: 'topleft', // change the position of the button can be topleft, topright, bottomright or bottomleft, defaut topleft
43 | title: 'Show me the fullscreen !', // change the title of the button, default Full Screen
44 | titleCancel: 'Exit fullscreen mode', // change the title of the button when fullscreen is on, default Exit Full Screen
45 | content: null, // change the content of the button, can be HTML, default null
46 | forceSeparateButton: true, // force seperate button to detach from zoom buttons, default false
47 | forcePseudoFullscreen: true, // force use of pseudo full screen even if full screen API is available, default false
48 | fullscreenElement: false // Dom element to render in full screen, false by default, fallback to map._container
49 | }).addTo(mymap);
50 |
51 | // events are fired when entering or exiting fullscreen.
52 | mymap.on('enterFullscreen', function(){
53 | console.log('entered fullscreen');
54 | });
55 |
56 | mymap.on('exitFullscreen', function(){
57 | console.log('exited fullscreen');
58 | });
59 |
60 | },1000);
61 |
62 |
63 | }
64 |
65 | // mapbox token pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.dzi:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.jpg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/0/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/0/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/1/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/1/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_3.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_4.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_3.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_4.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_3.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_4.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_3.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_4.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_2.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_3.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_4.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/2/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/2/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/3/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/3/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/4/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/4/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/5/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/5/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/6/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/6/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/7/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/7/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/8/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/8/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_1.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_0.jpeg
--------------------------------------------------------------------------------
/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_1.jpeg
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.3.2
2 |
--------------------------------------------------------------------------------
/project/build.sbt:
--------------------------------------------------------------------------------
1 | //addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.15")
2 | //addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.20")
3 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.29")
4 | //addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.4.0")
5 |
--------------------------------------------------------------------------------
/project/buildinfo.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0")
--------------------------------------------------------------------------------
/releases.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | **1.16.0**: Handling of the Commentary Data Model will no longer try to be clever. It will literally use the CiteRelations present in the data, and only those.
4 |
5 | **1.15.0**: Updated DSE Library dependency, and re-wrote code to take advantage of it.
6 |
7 | **1.14.0**: Implemented Leaflet functionality, for geo-spatial data, and Marked.js, for markdown string properties. Now using discoverable data models for extended string property types.
8 |
9 | **1.13.3**: Using OHCO2 10.12.3, for improved performance.
10 |
11 | **1.13.2**: Updated CITE libraries.
12 |
13 | **1.13.1**: Improved handling of commenting for notional URNs.
14 |
15 | **1.13.0**: Implementing ExtendedStringPropertyTypes: markdown, geojson, Pleiades-URI, lat/long, tei-xml.
16 |
17 | **1.12.0**: Commentaries now point two ways, and are more clearly identified.
18 |
19 | **1.11.0**: Implemented Alt-click on Text and Object links to open a new instance of the browser, with the selected URN displayed.
20 |
21 | **1.10.0**: Adding link to look up any object, or Cite2Urn propert-value in Relations.
22 |
23 | **1.9.8**: Accurately reporting the presence of a given text in the repository.
24 |
25 | **1.9.7**: Sped up text retrieval when there are thousands of commentary relations.
26 |
27 | **1.9.6**: Replaced indicator for DSE records attached to a text passage.
28 |
29 | **1.9.5**: Fixed bug in NGram URN reporting; sped it up.
30 |
31 | **1.9.4**: Added "server mode" option, which removes the "local/remote" switch for images (using only "remote").
32 |
33 | **1.9.3**: Resolved all deprecation warnings from Binding.scala; improved display of text-nodes.
34 |
35 | **1.9.2**: Search history menu for relations tab.
36 |
37 | **1.9.1**: Using CiteRelations 2.0.4.
38 |
39 | **1.9.0**: Relations tab.
40 |
41 | **1.8.1**: Replace list of cited works with dropdown menu, for O2 view and NGram view.
42 |
43 | **1.8.0**: Implemented CiteRelations and the Commentary Datamodel for texts.
44 |
45 | **1.7.3**: Using scala-js-dom 0.9.5.
46 |
47 | **1.7.2**: Fixed a terrible bug where exemplar text nodes would show out of order.
48 | Accepting CtsUrn or Cite2Urn request-parameters for auto-loading (and sharing views).
49 |
50 | **1.7.1**: Even more rigorous checking for `Option[T]` throughout. Fixed a loophole where bad Cite2Urn values cased a `.get` operation on a `None` value when doing DSE records. Improved CSS for object views.
51 |
52 | **1.7.0**: Rebuilt text-display code following more sound binding principles, giving more flexibility to expand text presentation with datamodels. Better integration of text-view with DSE models. More rigorous checking for `Option[T]` throughout.
53 |
54 | **1.6.1**: Update OHCO2 library to 10.7.0, xCite library to 3.3.0; links to rull-rez image-downloads when viewing remote images.
55 |
56 | **1.6.0**: Fully implemented CiteBinaryImageModel and DSEModel.
57 |
58 | **1.5.4**: Added DSE Mappings to Text View. Fixed Issue #128: .
59 |
60 | **1.5.3**: Fixed Issue #133: .
61 |
62 | **1.5.2**: Fixed Issue #131: .
63 |
64 | **1.5.1**: Fixed Issue #132: .
65 |
66 | **1.5.0**: Implemented the DSE datamodel for data mapped to images.
67 |
68 | **1.4.4**: Increased selection menu for NGram size up to 15. Now showing property labels (not property URNs) in object-view.
69 |
70 | **1.4.3**: Added a working history menu for object browsing and querying.
71 |
72 | **1.4.2**: Significant refactoring of text display. Improved display of citations for Exemplars.
73 |
74 | **1.4.1**: Fixed bug where collection-level URNs in object property values would cause browsing to fail silently.
75 |
76 | **1.4.0**: Added Objects Tab for viewing and querying CITE Collections. Added Images tab, taking advantage of the `CiteBinaryImage` datamodel in CEX, to show binary image data.
77 |
78 | **1.3.10**: Updated dependencies.
79 |
80 | **1.3.9**: Fixed bug that prevented previous-search menu from activating on the "Explore Texts" tab.
81 |
82 | **1.3.8**: Improved UI for NGram threshold. Fixed bug where NGram URNs would get returned for every exemplar of an edition, and they should not have been.
83 |
84 | **1.3.7**: Improved UI for Exploring. Using OHCO2 Library 10.4.2, which fixes bugs in labelling works in Catalogs, and in delivering first-node URNs for corpora.
85 |
86 | **1.3.6**: Fixed bug that prevented NGrams from showing up. Also fixed a bug where URNs for NGrams were not being labelled correctly.
87 |
88 | **1.3.5**: Fixed bug that caused erroneous information in the "Works in this Corpus" sidebar. Added sorting of works in listing so all versions and exemplars are together (as opposed to appearing in whatever order their `#!ctsdata` appears in the CEX).
89 |
90 | **1.3.4**: Fixed bug that prevented searching for strings in a single work as opposed to the whole corpus.
91 |
92 | **1.3.3**: Moved a few blocking UI actions to use `Future[T]` to improve perceived responsiveness.
93 |
94 | **1.3.2**: Using updated version of the `ohco2` and `scm` libraries. Improvements to prev and next, and to NGram searching.
95 |
96 | **1.3.1**: Using updated version of the `ohco2` and `scm` libraries. Adjustments to take advantage of citation- and corpus-algebra.
97 |
98 | **1.3.0**: Using updated version of `.cex`. Added support for CITE Collections and Image Extensions.
99 |
100 | - Collections, Images, and Texts are integrated.
101 | - Refactoring toward a future microservice-based app.
102 | - Querying on CITE Properties with the latest version of the `citeobj` library.
103 |
104 | **1.2.1**: Improved import of `.cex` files, using the Scala SCM library and enforcing validity. Numerous bug-fixes in searching texts, finding ngrams, and displaying results. New functionality:
105 |
106 | - A UI way to see multiple versions of a passage of text.
107 | - New, more sensible navigation when viewing multiple versions of a text.
108 | - Links to online help
109 | - A left-to-right text that quotes a right-to-left language will display as generally expected.
110 |
111 | **1.1.0**: Import of repositories in `.cex` format, combining text-data and catalog-data. New functionality:
112 |
113 | - String- and Token-searching
114 | - Search history
115 | - Improved UI
116 | - Various internal refactorings and improvements
117 |
118 | **1.0**: initial release. Import of corpora in 2-column, `.tsv` format. Text browsing and querying for NGrams.
119 |
--------------------------------------------------------------------------------
/scripts/InsecureChrome.lnk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/scripts/InsecureChrome.lnk
--------------------------------------------------------------------------------
/scripts/dz2.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Making Deep Zoom Files."
3 | echo "Usage:"
4 | echo "1. Navigate to a directory of images."
5 | echo "2. 'mkdir ../new_image_archive'"
6 | echo "3. './dz2.sh *.jpg'"
7 | PYRAMID_DIR=../new_image_archive/
8 | SRC_EXTENSION=jpg
9 | # Script doing the work:
10 | VIPS=`which vips`
11 | MV=`which mv`
12 | for f in $*
13 | do
14 | echo "------------------"
15 | baseName=$(echo $f | sed -e "s/.$SRC_EXTENSION//")
16 | newF=${PYRAMID_DIR}/${baseName}
17 | echo "copying " $f " to " $PYRAMID_DIR " ..."
18 | cp $f $PYRAMID_DIR
19 | echo "converting " $f " to " $newF " ..."
20 | echo
21 | $VIPS dzsave $f $newF
22 | done;
23 |
--------------------------------------------------------------------------------
/scripts/macOS_insecure_chrome.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | open -a Google\ Chrome --args --disable-web-security --user-data-dir=""
4 |
--------------------------------------------------------------------------------
/scripts/make_ptiff_3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "works"
3 | PYRAMID_DIR=../tiff
4 |
5 | #
6 | # SRC_EXTENSION is the dot-extension on the SOURCE files: if you're
7 | # converting .tif files, change this value to "tif" for example
8 | SRC_EXTENSION=jpg
9 |
10 | echo $PYRAMID_DIR
11 |
12 | # Script doing the work:
13 | VIPS=`which vips`
14 | echo $VIPS
15 | MV=`which mv`
16 | echo $MV
17 | for f in $*
18 | do
19 | echo "------------------"
20 | baseName=$(echo $f | sed -e "s/.$SRC_EXTENSION//")
21 | newF=${PYRAMID_DIR}/${baseName}
22 | echo "converting " $f " to " $newF " ..."
23 | echo
24 | $VIPS dzsave $f $newF
25 | done;
26 |
27 |
--------------------------------------------------------------------------------
/src/main/resources/LICENSE.txt:
--------------------------------------------------------------------------------
1 | # Licensing on Works
2 |
3 | Below is detailed licensing for the works included in the file `million.cex`.
4 |
5 | ## Quran
6 |
7 | The text of the Quran is version 1.0.2 from , distributed under the terms of a Creative Commons Attribution 3.0 License.
8 | To quote their terms of use:
9 |
10 | Permission is granted to copy and distribute verbatim copies
11 | of this text, but CHANGING IT IS NOT ALLOWED.
12 |
13 | This copyright notice shall be included in all verbatim copies
14 | of the text, and shall be reproduced appropriately in all files
15 | derived from or containing substantial portion of this text.
16 |
17 | ## Herodotus (English and Greek)
18 |
19 | The texts of Herodotus are from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License.
20 |
21 | ## Hafez
22 |
23 | The poetry of Hafez is from the Open Persian Project of Leipzig University, , Gregory Crane, Saeed Majidi, and Maryam Foradi, edd. Distributed under the terms of a Creative Commons 3.0 Attribution License.
24 |
25 | ## Plutarch (Greek)
26 |
27 | The Greek text of Plutarch is from the edition of Ziegler, published on Archive.org and released into the Public Domain. Preparation of this digital edition was funded by a grant from the Andrew W. Mellon Foundation.
28 |
29 | ## Plutarch (English)
30 |
31 | The English text of Plutarch is from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License.
32 |
33 | ## Latin Texts
34 |
35 | The Latin Texts are from Holy Cross Free Latin and Greek editions, distributed under the terms of the Creative Commons 3 Attribution-Share-Alike License, derived from Tesserae project edition (http://tesserae.caset.buffalo.edu/sources.php) derived from Perseus project edition (http://www.perseus.tufts.edu/hopper/collection?collection=Perseus%3Acollection%3AGreco-Roman)
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/resources/cite-TEMPLATE1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cite Environment: version ACTUALVERSION
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
3 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/Control.FullScreen.css:
--------------------------------------------------------------------------------
1 | .fullscreen-icon { background-image: url(images/icon-fullscreen.png); }
2 | .leaflet-retina .fullscreen-icon { background-image: url(images/icon-fullscreen-2x.png); background-size: 26px 26px; }
3 | /* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */
4 | .leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
5 | .leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
6 | .leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
7 | .leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
8 | .leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; }
9 |
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/Control.FullScreen.js:
--------------------------------------------------------------------------------
1 | (function () {
2 |
3 | L.Control.FullScreen = L.Control.extend({
4 | options: {
5 | position: 'topleft',
6 | title: 'Full Screen',
7 | titleCancel: 'Exit Full Screen',
8 | forceSeparateButton: false,
9 | forcePseudoFullscreen: false,
10 | fullscreenElement: false
11 | },
12 |
13 | onAdd: function (map) {
14 | var className = 'leaflet-control-zoom-fullscreen', container, content = '';
15 |
16 | if (map.zoomControl && !this.options.forceSeparateButton) {
17 | container = map.zoomControl._container;
18 | } else {
19 | container = L.DomUtil.create('div', 'leaflet-bar');
20 | }
21 |
22 | if (this.options.content) {
23 | content = this.options.content;
24 | } else {
25 | className += ' fullscreen-icon';
26 | }
27 |
28 | this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);
29 |
30 | this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this);
31 |
32 | return container;
33 | },
34 |
35 | _createButton: function (title, className, content, container, fn, context) {
36 | this.link = L.DomUtil.create('a', className, container);
37 | this.link.href = '#';
38 | this.link.title = title;
39 | this.link.innerHTML = content;
40 |
41 | L.DomEvent
42 | .addListener(this.link, 'click', L.DomEvent.stopPropagation)
43 | .addListener(this.link, 'click', L.DomEvent.preventDefault)
44 | .addListener(this.link, 'click', fn, context);
45 |
46 | L.DomEvent
47 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
48 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
49 | .addListener(container, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context);
50 |
51 | L.DomEvent
52 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation)
53 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault)
54 | .addListener(document, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context);
55 |
56 | return this.link;
57 | },
58 |
59 | toggleFullScreen: function () {
60 | var map = this._map;
61 | map._exitFired = false;
62 | if (map._isFullscreen) {
63 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
64 | fullScreenApi.cancelFullScreen();
65 | } else {
66 | L.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
67 | }
68 | map.fire('exitFullscreen');
69 | map._exitFired = true;
70 | map._isFullscreen = false;
71 | }
72 | else {
73 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) {
74 | fullScreenApi.requestFullScreen(this.options.fullscreenElement ? this.options.fullscreenElement : map._container);
75 | } else {
76 | L.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
77 | }
78 | map.fire('enterFullscreen');
79 | map._isFullscreen = true;
80 | }
81 | },
82 |
83 | _toggleTitle: function () {
84 | this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
85 | },
86 |
87 | _handleFullscreenChange: function () {
88 | var map = this._map;
89 | map.invalidateSize();
90 | if (!fullScreenApi.isFullScreen() && !map._exitFired) {
91 | map.fire('exitFullscreen');
92 | map._exitFired = true;
93 | map._isFullscreen = false;
94 | }
95 | }
96 | });
97 |
98 | L.Map.addInitHook(function () {
99 | if (this.options.fullscreenControl) {
100 | this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions);
101 | this.addControl(this.fullscreenControl);
102 | }
103 | });
104 |
105 | L.control.fullscreen = function (options) {
106 | return new L.Control.FullScreen(options);
107 | };
108 |
109 | /*
110 | Native FullScreen JavaScript API
111 | -------------
112 | Assumes Mozilla naming conventions instead of W3C for now
113 |
114 | source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/
115 |
116 | */
117 |
118 | var
119 | fullScreenApi = {
120 | supportsFullScreen: false,
121 | isFullScreen: function () { return false; },
122 | requestFullScreen: function () {},
123 | cancelFullScreen: function () {},
124 | fullScreenEventName: '',
125 | prefix: ''
126 | },
127 | browserPrefixes = 'webkit moz o ms khtml'.split(' ');
128 |
129 | // check for native support
130 | if (typeof document.exitFullscreen !== 'undefined') {
131 | fullScreenApi.supportsFullScreen = true;
132 | } else {
133 | // check for fullscreen support by vendor prefix
134 | for (var i = 0, il = browserPrefixes.length; i < il; i++) {
135 | fullScreenApi.prefix = browserPrefixes[i];
136 | if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') {
137 | fullScreenApi.supportsFullScreen = true;
138 | break;
139 | }
140 | }
141 | if (typeof document['msExitFullscreen'] !== 'undefined') {
142 | fullScreenApi.prefix = 'ms';
143 | fullScreenApi.supportsFullScreen = true;
144 | }
145 | }
146 |
147 | // update methods to do something useful
148 | if (fullScreenApi.supportsFullScreen) {
149 | if (fullScreenApi.prefix === 'ms') {
150 | fullScreenApi.fullScreenEventName = 'MSFullscreenChange';
151 | } else {
152 | fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
153 | }
154 | fullScreenApi.isFullScreen = function () {
155 | switch (this.prefix) {
156 | case '':
157 | return document.fullscreen;
158 | case 'webkit':
159 | return document.webkitIsFullScreen;
160 | case 'ms':
161 | return document.msFullscreenElement;
162 | default:
163 | return document[this.prefix + 'FullScreen'];
164 | }
165 | };
166 | fullScreenApi.requestFullScreen = function (el) {
167 | switch (this.prefix) {
168 | case '':
169 | return el.requestFullscreen();
170 | case 'ms':
171 | return el.msRequestFullscreen();
172 | default:
173 | return el[this.prefix + 'RequestFullScreen']();
174 | }
175 | };
176 | fullScreenApi.cancelFullScreen = function () {
177 | switch (this.prefix) {
178 | case '':
179 | return document.exitFullscreen();
180 | case 'ms':
181 | return document.msExitFullscreen();
182 | default:
183 | return document[this.prefix + 'CancelFullScreen']();
184 | }
185 | };
186 | }
187 |
188 | // jQuery plugin
189 | if (typeof jQuery !== 'undefined') {
190 | jQuery.fn.requestFullScreen = function () {
191 | return this.each(function () {
192 | var el = jQuery(this);
193 | if (fullScreenApi.supportsFullScreen) {
194 | fullScreenApi.requestFullScreen(el);
195 | }
196 | });
197 | };
198 | }
199 |
200 | // export api
201 | window.fullScreenApi = fullScreenApi;
202 | })();
203 |
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/citeImage.js:
--------------------------------------------------------------------------------
1 | // Variables to hold the current image URN and an array of ROIs
2 |
3 |
4 | var viewer = null
5 | var roiArray =[]
6 |
7 | /*
8 | classes:
9 |
10 | image_mappedUrn
11 | image_mappedROI
12 | image_roiGroup_1
13 | image_roi_selected
14 |
15 | */
16 |
17 | /*
18 | function imageInNewWindow(c) {
19 | console.log("Got here… opening " )
20 | var w = c.width;
21 | console.log(w);
22 | var h = c.height;
23 | console.log(h);
24 | var u = c.toDataURL();
25 | window.open(u, "Image", "width=200, height=200");
26 | }
27 | */
28 |
29 | function idForMappedUrn(i) {
30 | var s = "image_mappedUrn_" + (i)
31 | return s
32 | }
33 |
34 | function idForMappedROI(i) {
35 | var s = "image_mappedROI_" + (i)
36 | return s
37 | }
38 |
39 | function roiToUrnId(id) {
40 | var s = id.replace("image_mappedROI_","image_mappedUrn_")
41 | return s
42 | }
43 |
44 |
45 | function clearJsRoiArray(r) {
46 | roiArray = []
47 | }
48 |
49 | function addToJsRoiArray(i,r,u,g){
50 | tempMap = {index: i, roi: r, mappedUrn: u, group: g}
51 | roiArray.push(tempMap)
52 | }
53 |
54 | function clearSelectedROIs(){
55 | for (n = 0; n < (roiArray.length - 1); n++){
56 | var roiId = idForMappedROI(n+1)
57 | var urnId = idForMappedUrn(n+1)
58 | var thisROI = document.getElementById(roiId)
59 | var thisURN = document.getElementById(urnId)
60 | thisROI.classList.remove("image_roi_selected")
61 | thisURN.classList.remove("image_roi_selected")
62 | }
63 | }
64 |
65 | function updateImageJS(collection, imageObject, path ){
66 | //var collDirectory = collection.replace(new RegExp(':', 'g'), '_');
67 | //var imagePath = "../../../image_archive/" + collDirectory + "/" + imageObject + ".dzi"
68 | initOpenSeadragon(path)
69 | }
70 |
71 | /**
72 | * Normalizes the index of the ROI to a number within the given amount of
73 | * colors. E.g. If there were only two colors, an index of 4 would return group
74 | * number 0 => (index % colorLength)
75 | * @param {int} i index number
76 | * @return {int} normalized group number
77 | */
78 | function getGroup(i){
79 | var colorArray = ["#f23568", "#6d38ff", "#38ffd7", "#fff238", "#661641", "#275fb3", "#24a669", "#a67b24", "#ff38a2", "#194973", "#35f268", "#7f441c", "#801c79", "#2a8ebf", "#216616", "#d97330", "#da32e6", "#196d73", "#bdff38", "#bf3e2a", "#3d1973", "#30cdd9", "#858c1f", "#661616" ];
80 | var limit = colorArray.length
81 | var rv = i % limit;
82 | return rv;
83 | }
84 |
85 | function initOpenSeadragon(imagePath) {
86 | //console.log(imagePath)
87 |
88 | if (viewer != null){
89 | viewer.destroy();
90 | viewer = null
91 | }
92 |
93 | viewer = OpenSeadragon({
94 | id: 'image_zoomContainer',
95 | prefixUrl: 'citeApp-js/images/',
96 | crossOriginPolicy: "Anonymous",
97 | ajaxWithCredentials: false,
98 | defaultZoomLevel: 1,
99 | tileSources: imagePath,
100 | //tileSources: 'http://www.homermultitext.org/iipsrv?DeepZoom=/project/homer/pyramidal/deepzoom/hmt/vaimg/2017a/VA024RN_0025.tif.dzi',
101 | minZoomImageRatio: 0.25, // of viewer size
102 | immediateRender: true
103 | });
104 |
105 | viewer.guides({
106 | allowRotation: false, // Make it possible to rotate the guidelines (by double clicking them)
107 | horizontalGuideButton: null, // Element for horizontal guideline button
108 | verticalGuideButton: null, // Element for vertical guideline button
109 | prefixUrl: "citeApp-js/images/", // Images folder
110 | removeOnClose: false, // Remove guidelines when viewer closes
111 | useSessionStorage: false, // Save guidelines in sessionStorage
112 | navImages: {
113 | guideHorizontal: {
114 | REST: 'guidehorizontal_rest.png',
115 | GROUP: 'guidehorizontal_grouphover.png',
116 | HOVER: 'guidehorizontal_hover.png',
117 | DOWN: 'guidehorizontal_pressed.png'
118 | },
119 | guideVertical: {
120 | REST: 'guidevertical_rest.png',
121 | GROUP: 'guidevertical_grouphover.png',
122 | HOVER: 'guidevertical_hover.png',
123 | DOWN: 'guidevertical_pressed.png'
124 | }
125 | }
126 | });
127 |
128 |
129 | // Add overlays
130 | setTimeout(function(){
131 | if (viewer.world.getItemAt(0)){
132 | //console.log("defined");
133 | } else {
134 | //console.log("undefined");
135 | }
136 | var baseTimer = 0;
137 | while( !(viewer.world.getItemAt(0))){
138 | baseTimer = baseTimer + 1;
139 | }
140 | //console.log(baseTimer);
141 | var normH = viewer.world.getItemAt(0).getBounds().height;
142 | var normW = viewer.world.getItemAt(0).getBounds().width;
143 | if (roiArray.length > 0){
144 | for (ol = 0; ol < roiArray.length; ol++){
145 | var roi = roiArray[ol].roi
146 | var rl = +roi.split(",")[0]
147 | var rt = +roi.split(",")[1]
148 | var rw = +roi.split(",")[2]
149 | var rh = +roi.split(",")[3]
150 | var tl = rl * normW
151 | var tt = rt * normH
152 | var tw = rw * normW
153 | var th = rh * normH
154 | var osdRect = new OpenSeadragon.Rect(tl,tt,tw,th)
155 | var elt = document.createElement("a")
156 | elt.id = idForMappedROI(roiArray[ol].index)
157 | elt.className = "image_mappedROI" + " image_roiGroup_" + roiArray[ol].group + " " + idForMappedUrn(roiArray[ol].index)
158 | elt.dataset.urn = roiArray[ol].mappedUrn
159 |
160 | viewer.addOverlay(elt,osdRect)
161 | }
162 | }
163 |
164 | // Go through and attach events to each overlay
165 | for (n = 0; n < roiArray.length; n++){
166 | var captureN = n // because N keeps moving
167 | var thisId = idForMappedROI(roiArray[n].index)
168 | var thisElement = document.getElementById(thisId)
169 | thisElement.addEventListener("click", function(e) {
170 | clearSelectedROIs()
171 | var roiId = e.target.id
172 | var targetId = roiToUrnId(roiId)
173 | var targetSpan = document.getElementById(targetId)
174 | targetSpan.classList.add("image_roi_selected")
175 | e.target.classList.add("image_roi_selected")
176 | }, false);
177 | }
178 | },6000);
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/161728.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/161728.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/button_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/button_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/button_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/button_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/fullpage_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/fullpage_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/fullpage_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/fullpage_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidehorizontal_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidehorizontal_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidehorizontal_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidehorizontal_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidevertical_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidevertical_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidevertical_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/guidevertical_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/home_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/home_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/home_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/home_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/icon-fullscreen-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/icon-fullscreen-2x.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/icon-fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/icon-fullscreen.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/img_254851.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/img_254851.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/next_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/next_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/next_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/next_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/previous_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/previous_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/previous_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/previous_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateleft_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateleft_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateleft_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateleft_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateright_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateright_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateright_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/rotateright_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_cancel_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_cancel_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_cancel_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_cancel_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_confirm_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_confirm_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_confirm_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_confirm_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/selection_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomin_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomin_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomin_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomin_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomout_grouphover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_grouphover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomout_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_hover.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomout_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_pressed.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/images/zoomout_rest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_rest.png
--------------------------------------------------------------------------------
/src/main/resources/citeApp-js/textExtensions.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function initiateMarked(markdownString, elementId) {
4 | setTimeout(function(){
5 | var parsedMarkdown = marked(markdownString).replace("","").replace("
","")
6 | document.getElementById(elementId).innerHTML = parsedMarkdown;
7 | },1000);
8 | }
9 |
10 | function initiateLeafletWithLatLong(lat, long, elementId) {
11 | setTimeout(function(){
12 | var latitude = parseFloat(lat);
13 | var longitude = parseFloat(long);
14 | var mymap = L.map(elementId).setView([latitude, longitude], 13);
15 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
16 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
17 | maxZoom: 18,
18 | id: 'mapbox.satellite',
19 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ'
20 | }).addTo(mymap);
21 | var marker = L.marker([latitude, longitude]).addTo(mymap);
22 | },1000);
23 | }
24 |
25 | function initiateLeafletWithGeoJson(geojson, elementId) {
26 | setTimeout(function(){
27 | var myFeature = JSON.parse(geojson);
28 | var mymap = L.map(elementId).setView([0, 0], 20);
29 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
30 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
31 | maxZoom: 18,
32 | id: 'mapbox.satellite',
33 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ'
34 | }).addTo(mymap);
35 | var gjFeature = L.geoJSON(myFeature)
36 | gjFeature.addTo(mymap);
37 | mymap.fitBounds(gjFeature.getBounds());
38 | mymap.zoomOut(3);
39 |
40 | // create a fullscreen button and add it to the map
41 | L.control.fullscreen({
42 | position: 'topleft', // change the position of the button can be topleft, topright, bottomright or bottomleft, defaut topleft
43 | title: 'Show me the fullscreen !', // change the title of the button, default Full Screen
44 | titleCancel: 'Exit fullscreen mode', // change the title of the button when fullscreen is on, default Exit Full Screen
45 | content: null, // change the content of the button, can be HTML, default null
46 | forceSeparateButton: true, // force seperate button to detach from zoom buttons, default false
47 | forcePseudoFullscreen: true, // force use of pseudo full screen even if full screen API is available, default false
48 | fullscreenElement: false // Dom element to render in full screen, false by default, fallback to map._container
49 | }).addTo(mymap);
50 |
51 | // events are fired when entering or exiting fullscreen.
52 | mymap.on('enterFullscreen', function(){
53 | console.log('entered fullscreen');
54 | });
55 |
56 | mymap.on('exitFullscreen', function(){
57 | console.log('exited fullscreen');
58 | });
59 |
60 | },1000);
61 |
62 |
63 | }
64 |
65 | // mapbox token pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ
--------------------------------------------------------------------------------
/src/main/resources/index-dev.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cite Environment (Development 1.15.0)
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/main/resources/index-opt.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Cite Environment v.1.15.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CitableImageModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import scala.scalajs.js.Dynamic.{ global => g }
8 | import js.annotation._
9 | import collection.mutable
10 | import collection.mutable._
11 | import org.scalajs.dom._
12 | import org.scalajs.dom.ext._
13 | import org.scalajs.dom.raw._
14 | import edu.holycross.shot.cite._
15 | import edu.holycross.shot.ohco2._
16 | import edu.holycross.shot.citeobj._
17 |
18 | import scala.scalajs.js.annotation.JSExport
19 | import js.annotation._
20 |
21 | /*
22 | Defines a model for dealing with objects that implement the
23 | CiteBinaryImage datamodel.
24 | */
25 |
26 | @JSExportTopLevel("CitableImageModel")
27 | object CitableImageModel {
28 |
29 | case class ImageObject(val urn:Cite2Urn, val caption:String, val rights:String) {
30 | override def toString = s"${urn} - ${caption}. ${rights}"
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CiteBinaryImageModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import scala.scalajs.js.Dynamic.{ global => g }
8 | import js.annotation._
9 | import collection.mutable
10 | import collection.mutable._
11 | import org.scalajs.dom._
12 | import org.scalajs.dom.ext._
13 | import org.scalajs.dom.raw._
14 | import edu.holycross.shot.cite._
15 | import edu.holycross.shot.ohco2._
16 | import edu.holycross.shot.citeobj._
17 | import edu.holycross.shot.scm._
18 | import edu.holycross.shot.citebinaryimage._
19 |
20 | import scala.scalajs.js.annotation.JSExport
21 | import js.annotation._
22 |
23 | /*
24 | Defines a model for dealing with objects that implement the
25 | CiteBinaryImage datamodel.
26 | */
27 |
28 | @JSExportTopLevel("CiteBinaryImageModel")
29 | object CiteBinaryImageModel {
30 |
31 | // URNs for implemented Image models
32 | val binaryImageModelUrn:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:binaryimg")
33 | val protocolPropertyName:String = "protocol"
34 | val iiifApiProtocolString:String = "iiifApi"
35 | val localDZProtocolString:String = "localDeepZoom"
36 | val iipDZProtocolString:String = "iipDeepZoom"
37 | val jpgProtocolString:String = "JPG"
38 |
39 |
40 | // this is changed by the user using the local/remote switch
41 | val imgUseLocal = Var[Boolean](false)
42 |
43 | // this is set at app init
44 | val imgArchivePath = Var[String]("")
45 |
46 |
47 | // To save everyone time, is *any* collection in the current CEX
48 | // supported for local viewing?
49 | val hasLocalOption = Var[Boolean](false)
50 | // To save everyone time, is *any* collection in the current CEX
51 | // supported for remote viewing?
52 | val hasRemoteOption = Var[Boolean](false)
53 |
54 |
55 | // any binary image implemented?
56 | val hasBinaryImages = Var[Boolean](false)
57 | val binaryImageCollections = Vars.empty[Cite2Urn]
58 |
59 | // which protocols are implemented in this CEX?
60 | /*
61 | val hasIiifApi = Var[Boolean](false)
62 | val hasLocalDeepZoom = Var[Boolean](false)
63 | val hasJPG = Var[Boolean](false)
64 | val hasIipDZ = Var[Boolean](false)
65 | */
66 |
67 | // urn is what the user requested
68 | val urn = Var[Option[Cite2Urn]](None)
69 |
70 | /* If a user requests a single URN with an ROI, preview that. But if
71 | we're doing some fancy data model stuff, we might want to show
72 | the whole image in the preview. So we separate the current URN from
73 | the current Preview Urn */
74 | val previewUrn = Var[Option[Cite2Urn]](None)
75 |
76 | // An ImageROI object associates an roi with a urn;
77 | // our image may have none, one, or many
78 | val imageRoiTuple = Vars.empty[(Int,ImageRoiModel.Roi)]
79 | // This splits imageRoiTuple up into groups
80 | val imageRoiGroups = Var[Option[Map[String,Int]]](None)
81 | // And for convenience, and making Binding happen, another view of the roiGroups…
82 | val imageRoiGroupSeq = Vars.empty[(String,Int)]
83 |
84 | val currentContextUrn = Var[Option[Urn]](None)
85 |
86 |
87 | // User Interface stuff
88 | val userMessage = Var("")
89 | val userAlert = Var("default")
90 | val userMessageVisibility = Var("app_hidden")
91 | // for displaying and hiding user messages
92 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null
93 | val thumbnailMaxWidth:Int = 400
94 |
95 | // Current info on image displayed
96 | val displayUrn = Var[Option[Cite2Urn]](None)
97 | // Do we use this?
98 | val versionsForCurrentUrn = Var(1)
99 |
100 | def clearROIs:Unit = {
101 | imageRoiTuple.value.clear
102 | imageRoiGroups.value = None
103 | imageRoiGroupSeq.value.clear
104 | }
105 |
106 | def loadROIs(rois:Vector[ImageRoiModel.Roi]):Unit = {
107 | clearROIs
108 | for ( (roi,i) <- rois.zipWithIndex){
109 | val t:(Int,ImageRoiModel.Roi) = (i, roi)
110 | CiteBinaryImageModel.imageRoiTuple.value += t
111 | }
112 | imageRoiGroups.value = CiteBinaryImageController.groupsForROIs(rois)
113 | imageRoiGroups.value match {
114 | case Some(irg) => {
115 | irg.toVector.foreach( g => {
116 | imageRoiGroupSeq.value += g
117 | })
118 | }
119 | case None => imageRoiGroupSeq.value.clear
120 | }
121 |
122 | }
123 |
124 |
125 | def addToROIs(roi:ImageRoiModel.Roi):Unit = {
126 | val i = imageRoiTuple.value.size
127 | val t:(Int,ImageRoiModel.Roi) = (i, roi)
128 | CiteBinaryImageModel.imageRoiTuple.value += t
129 | val roiPreVec = CiteBinaryImageModel.imageRoiTuple.value.map(_._2).toVector
130 | imageRoiGroups.value = None // Clear it out
131 | imageRoiGroups.value = CiteBinaryImageController.groupsForROIs(roiPreVec)
132 | }
133 |
134 | def imageRoisToOptionVector:Option[Vector[ImageRoiModel.Roi]] = {
135 | imageRoiTuple.value.size match {
136 | case s if (s == 1) => None
137 | case _ => {
138 | val roiVec:Vector[ImageRoiModel.Roi] = imageRoiTuple.value.map( r => r._2).toVector
139 | Some(roiVec)
140 | }
141 | }
142 | }
143 |
144 | /* This is how to pass data to the global JS scope */
145 | /*
146 | js.Dynamic.global.currentImageUrn = "urn:cts"
147 | js.Dynamic.global.roiArray = Array("one","two","three")
148 | */
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CiteMain.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 | import com.thoughtworks.binding.{Binding, dom}
3 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
4 | import com.thoughtworks.binding.Binding.{Var, Vars}
5 | import com.thoughtworks.binding.dom
6 | import org.scalajs.dom.document
7 | import org.scalajs.dom.raw.Event
8 | import org.scalajs.dom.ext.Ajax
9 | import scala.concurrent
10 | .ExecutionContext
11 | .Implicits
12 | .global
13 |
14 | import scala.scalajs.js
15 | import scala.scalajs.js._
16 | import js.annotation._
17 | import scala.scalajs.js.annotation.JSExport
18 |
19 | @JSExportTopLevel("CiteMain")
20 | class CiteMain(remoteUrl:String, localImagePath:String, serverMode:String) {
21 |
22 | @JSExport
23 | def main(): Unit = {
24 | CiteMainController.main(remoteUrl: String, localImagePath:String, serverMode:String)
25 | }
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CiteMainModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 | import com.thoughtworks.binding.{Binding, dom}
3 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
4 | import com.thoughtworks.binding.Binding.{Var, Vars}
5 | import com.thoughtworks.binding.dom
6 | import org.scalajs.dom.document
7 | import org.scalajs.dom.raw.Event
8 | import org.scalajs.dom.ext.Ajax
9 | import scala.concurrent
10 | .ExecutionContext
11 | .Implicits
12 | .global
13 |
14 | import scala.scalajs.js
15 | import scala.scalajs.js._
16 | import edu.holycross.shot.cite._
17 | import js.annotation._
18 | import edu.holycross.shot.scm._
19 |
20 |
21 | @JSExportTopLevel("CiteMainModel")
22 | object CiteMainModel {
23 |
24 | val userMessage = Var("Main loaded.")
25 | val userAlert = Var("default")
26 | val userMessageVisibility = Var("app_hidden")
27 |
28 | val requestParameterUrn = Var[Option[Urn]](None)
29 |
30 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null
31 |
32 | val currentLibraryMetadataString = Var("No library loaded.")
33 |
34 | // These are terrible and need to be replaced with real data model stuff
35 | val textProtocol:String = "TextProtocol"
36 | val objectProtocol:String = "ObjectProtocol"
37 | val localImageProtocol:String = "LocalImageProtocol"
38 |
39 | val cexMainDelimiter:String = "#"
40 | val cexSecondaryDelimiter:String = ","
41 |
42 |
43 | val showTexts = Var(true)
44 | val showNg = Var(true)
45 | val showCollections = Var(true)
46 | val showImages = Var(true)
47 | val mainLibrary = Var[Option[CiteLibrary]](None)
48 | val showRelations = Var(true)
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CiteMainView.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import org.scalajs.dom._
8 | import org.scalajs.dom.ext._
9 | import scala.scalajs.js.Dynamic.{ global => g }
10 | import org.scalajs.dom.raw._
11 | import org.scalajs.dom.document
12 | import org.scalajs.dom.raw.Event
13 | import org.scalajs.dom.ext.Ajax
14 | import edu.holycross.shot.cite._
15 | import edu.holycross.shot.ohco2._
16 | import edu.holycross.shot.citeobj._
17 | import scala.scalajs.js.annotation.JSExport
18 | import js.annotation._
19 |
20 |
21 | @JSExportTopLevel("CiteMainView")
22 | object CiteMainView {
23 |
24 | val textView = O2View.o2div
25 | val ngramView = NGView.nGdiv
26 | val objectView = ObjectView.objectDiv
27 | val imageView = CiteBinaryImageView.imageDiv
28 | val relationsView = RelationsView.relationsDiv
29 | val serverMode = Var(false)
30 |
31 |
32 | def changeTab(tab:String):Unit = {
33 | tab match {
34 | case "text" => js.Dynamic.global.document.getElementById("tab-1").checked = true
35 | case "object" => js.Dynamic.global.document.getElementById("tab-3").checked = true
36 | case "image" => js.Dynamic.global.document.getElementById("tab-4").checked = true
37 | case "relations" => js.Dynamic.global.document.getElementById("tab-5").checked = true
38 | }
39 | }
40 |
41 | // *** Apropos Microservice ***
42 | // We will want a switch here
43 | @dom
44 | def filePicker = {
45 |
46 |
47 | CiteMainController.loadLocalLibrary( event )}
51 | >
52 | { imageLocalRemoteSwitch.bind }
53 |
54 | }
55 |
56 | // *** Apropos Microservice ***
57 | @dom
58 | def imageLocalRemoteSwitch = {
59 | {
62 | CiteBinaryImageModel.hasBinaryImages.bind match {
63 | case true => "app_visible"
64 | case _ => "app_hidden"
65 | }
66 | }
67 | case _ => "app_hidden"
68 | }
69 | }>
70 | Image Source:
71 |
"app_hidden"
74 | case false => "app_visible"
75 | }
76 | }>
77 | "app_visible"
80 | case _ => "app_hidden"
81 | }
82 | }>Using Local Images
83 | "app_visible"
86 | case _ => "app_hidden"
87 | }
88 | }>Using Remote Images
89 |
90 |
"onoffswitch app_visible"
93 | case false => "onoffswitch app_hidden"
94 | }
95 | }>
96 | "onoffswitch-checkbox app_visible"
100 | case false => "onoffswitch-checkbox app_hidden"
101 | }
102 | } id="citeMain_localImageSwitch" checked={CiteBinaryImageModel.imgUseLocal.bind}
103 | onchange={ event: Event => CiteBinaryImageController.setPreferredImageSource}
104 | />
105 |
109 |
110 |
111 | }
112 |
113 |
114 | @dom
115 | def mainMessageDiv = {
116 |
117 |
{ CiteMainModel.userMessage.bind }
118 |
119 | }
120 |
121 | @dom
122 | def mainDiv = {
123 |
124 |
125 |
128 | { filePicker.bind }
129 | CITE Environment
130 |
131 | [ Online Help ]
132 |
133 |
134 |
135 |
136 | { mainMessageDiv.bind }
137 |
138 |
139 |
"app_visible app_tab"
143 | case _ => "app_hidden app_tab"
144 | }
145 | }>
146 |
147 |
148 |
149 | { textView.bind }
150 |
151 |
152 |
153 |
"app_visible app_tab"
157 | case _ => "app_hidden app_tab"
158 | }
159 | }>
160 |
161 |
162 |
163 | { ngramView.bind }
164 |
165 |
166 |
167 |
"app_visible app_tab"
171 | case _ => "app_hidden app_tab"
172 | }
173 | }>
174 |
175 |
176 |
177 | { objectView.bind }
178 |
179 |
180 |
181 |
"app_visible app_tab"
185 | case _ => "app_hidden app_tab"
186 | }
187 | }>
188 |
189 |
190 |
191 | { imageView.bind }
192 |
193 |
194 |
195 |
"app_visible app_tab"
199 | case _ => "app_hidden app_tab"
200 | }
201 | }>
202 |
203 |
204 |
205 | { relationsView.bind }
206 |
207 |
208 |
209 |
210 |
211 |
212 |
215 |
216 | }
217 |
218 |
219 | @dom
220 | def footer = {
221 |
222 | { CiteMainModel.currentLibraryMetadataString.bind }
223 |
224 |
225 | CITE/CTS is ©2002–2018 Neel Smith and Christopher Blackwell. This implementation of the CITE data models was written by Neel Smith and Christopher Blackwell using Scala, Scala-JS, and Binding.scala. Licensed under the GPL 3.0. Sourcecode on GitHub. Copyright and licensing information for the default library is available here. Report bugs by filing issues on GitHub.
226 |
227 | }
228 |
229 | }
230 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/CommentaryModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.citerelation._
20 | import edu.holycross.shot.scm._
21 |
22 | import monix.execution.Scheduler.Implicits.global
23 | import monix.eval._
24 |
25 | import scala.scalajs.js.annotation.JSExport
26 |
27 | @JSExportTopLevel("CommentaryModel")
28 | object CommentaryModel {
29 |
30 | val commentaryVerb:Cite2Urn = Cite2Urn("urn:cite2:cite:verbs.v1:commentsOn")
31 | val commentaryModel:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:commentarymodel")
32 | // commentsOn not used yet…
33 | val commentsOn = Var[Boolean](true)
34 |
35 | case class CiteComment(comment:Urn, text:Urn)
36 |
37 | val commentList = Vars.empty[CiteComment]
38 | val currentCommentsAll = Vars.empty[CiteComment]
39 | val currentCommentsDistinctComments = Vars.empty[CiteComment]
40 |
41 | def ctsHasCommentary(urn:CtsUrn):Vars[Urn] = {
42 | DataModelController.hasCommentaryModel match {
43 | case false => Vars.empty[Urn]
44 | case _ => {
45 | val relevantComments:Vector[CiteComment] = currentCommentsAll.value.filter(_.text.asInstanceOf[CtsUrn] == urn).toVector
46 | val v = Vars.empty[Urn]
47 | for (c <- relevantComments) {
48 | v.value += c.comment
49 | }
50 | v
51 | }
52 | }
53 | }
54 |
55 | def clearAllComments:Unit = {
56 | commentList.value.clear
57 | currentCommentsAll.value.clear
58 | currentCommentsDistinctComments.value.clear
59 | }
60 |
61 | def clearPassageComments:Unit = {
62 | currentCommentsAll.value.clear
63 | currentCommentsDistinctComments.value.clear
64 | }
65 |
66 | def updateCurrentListOfComments(corp:Corpus):Unit = {
67 | clearPassageComments
68 | //val corpUrns:Vector[CtsUrn] = corp.urns
69 | commentList.value.size match {
70 | case s if (s > 0) => {
71 | val twiddledComments:Vector[CiteComment] = {
72 | commentList.value.filter( c => {
73 | val textMatch:Boolean = {
74 | c.text match {
75 | case CtsUrn(_) => {
76 | //((corp ~~ c.text.asInstanceOf[CtsUrn]).size > 0)
77 | //(corp.nodes.filter(_.urn == c.text.asInstanceOf[CtsUrn]).size > 0)
78 | val curn:CtsUrn = c.text.asInstanceOf[CtsUrn]
79 | /*
80 | val curn:CtsUrn = {
81 | if (tempUrn.isRange){
82 | CtsUrn(s"${tempUrn.dropPassage}${tempUrn.rangeBegin}")
83 | } else {
84 | tempUrn
85 | }
86 | }
87 | */
88 | (corp.nodes.view.filter(_.urn <= curn).size > 0)
89 |
90 |
91 | }
92 | case _ => false
93 | }
94 | }
95 | val commentMatch:Boolean = {
96 | c.comment match {
97 | case CtsUrn(_) => {
98 | //((corp ~~ c.text.asInstanceOf[CtsUrn]).size > 0)
99 | //(corp.nodes.filter(_.urn == c.text.asInstanceOf[CtsUrn]).size > 0)
100 | val curn:CtsUrn = c.comment.asInstanceOf[CtsUrn]
101 | /*
102 | val curn:CtsUrn = {
103 | if (tempUrn.isRange){
104 | CtsUrn(s"${tempUrn.dropPassage}${tempUrn.rangeBegin}")
105 | } else {
106 | tempUrn
107 | }
108 | }
109 | */
110 | (corp.nodes.view.filter(_.urn == curn).size > 0)
111 | }
112 | case _ => false
113 | }
114 | }
115 | (textMatch || commentMatch)
116 | }).toVector
117 | }
118 | // If any of the twiddledComments were ranges, let's expand those…
119 | val rangeComments:Vector[CiteComment] = {
120 | twiddledComments.filter( c => {
121 | c.text.asInstanceOf[CtsUrn].isRange
122 | }).toVector
123 | }
124 |
125 |
126 |
127 |
128 | val expandedRangeComments:Vector[CiteComment] = {
129 | (
130 | for (rc <- rangeComments) yield {
131 | val urns:Vector[CtsUrn] = (corp ~~ rc.text.asInstanceOf[CtsUrn]).urns
132 | urns.map( u => { CiteComment(rc.comment,u)})
133 | }
134 | ).flatten
135 | }
136 | // And then we need to ditch the range comments from the original
137 | val nonRangeComments:Vector[CiteComment] = {
138 | twiddledComments.filter( c => {
139 | c.text.asInstanceOf[CtsUrn].isRange == false
140 | }).toVector
141 | }
142 |
143 | // And we concatenate those, and eliminate dups
144 | val finalCurrentComments:Vector[CiteComment] = {
145 | (nonRangeComments ++ expandedRangeComments).distinct.toVector
146 | }
147 |
148 |
149 | // If any comment is a Cite2Urn at the notional level, get it…
150 | val notionalCollComments:Vector[CiteComment] = {
151 | finalCurrentComments.filter( c => {
152 | c.comment match {
153 | case Cite2Urn(_) => {
154 | val u:Cite2Urn = c.comment.asInstanceOf[Cite2Urn]
155 | u.versionOption match {
156 | case Some(v) => false
157 | case None => true
158 | }
159 | }
160 | case _ => false
161 | }
162 | }).distinct
163 | }
164 |
165 | // …now let's see if we can find some versions for that…
166 | val versionedNotionalCommentUrns:Vector[CiteComment] = {
167 | ObjectModel.collRep.value match {
168 | case Some(cr) => {
169 | // for each notionalCollComment, find all real urns
170 | notionalCollComments.map(ncc => {
171 | val realUrns:Vector[Cite2Urn] = cr.citableObjects.view.filter(_.urn ~~ ncc.comment).map(_.urn).toVector
172 | val newComments:Vector[CiteComment] = realUrns.map(ru => {
173 | CiteComment(ru,ncc.text)
174 | })
175 | newComments
176 | }).flatten
177 | }
178 | case None => Vector()
179 | }
180 | }
181 |
182 | val reallyFinalCurrentComments:Vector[CiteComment] = finalCurrentComments ++ versionedNotionalCommentUrns
183 |
184 | //g.console.log(s"really final = ${reallyFinalCurrentComments}")
185 |
186 | // And we concatenate while removing unversioned comments
187 | for (c <- reallyFinalCurrentComments){
188 | c.comment match {
189 | case CtsUrn(_) => currentCommentsAll.value += c
190 | case Cite2Urn(_) => {
191 | if (c.comment.asInstanceOf[Cite2Urn].versionOption != None) currentCommentsAll.value += c
192 | }
193 | case _ => // do nothing
194 | }
195 | }
196 |
197 | // And let's get a version that just has unique comments, for the sidebar
198 | val uniquedComments:Vector[CiteComment] = reallyFinalCurrentComments.filter(cc => {
199 | cc.comment match {
200 | case CtsUrn(_) => true
201 | case Cite2Urn(_) => {
202 | cc.comment.asInstanceOf[Cite2Urn].versionOption != None
203 | }
204 | case _ => false
205 |
206 | }
207 | }).groupBy(_.comment).map(_._2.head).toVector
208 | // And why not group by work/collection, while we're at it… the list isn't going to be long
209 | val map1:Vector[Tuple2[String,CiteComment]] = uniquedComments.map(c => {
210 | val mapString:String = {
211 | c.comment match {
212 | case CtsUrn(_) => c.comment.asInstanceOf[CtsUrn].dropPassage.toString
213 | case _ => c.comment.asInstanceOf[Cite2Urn].dropSelector.toString
214 | }
215 | }
216 | Tuple2(mapString,c)
217 | })
218 | val map2:Vector[(String,Vector[Tuple2[String,CiteComment]])] = map1.groupBy(_._1).toVector
219 | val map3:Vector[Tuple2[String,CiteComment]] = map2.map(_._2).flatten
220 | val map4:Vector[CiteComment] = map3.map(_._2)
221 |
222 | for (c <- map4){
223 | currentCommentsDistinctComments.value += c
224 | }
225 |
226 | }
227 | case _ => //do nothing
228 | }
229 | }
230 |
231 | def loadAllComments:Unit = {
232 | commentList.value.clear
233 | if (DataModelController.hasCommentaryModel) {
234 | val tempComments:Option[CiteRelationSet] = {
235 | RelationsModel.citeRelations.value match {
236 | case Some(cr) => {
237 | val cv:CiteRelationSet = cr.verb(commentaryVerb)
238 | cv.size match {
239 | case s if (s > 0) => Some(cv)
240 | case _ => None
241 | }
242 | }
243 | case None => None
244 | }
245 | }
246 | if (tempComments != None) {
247 | for (c <- tempComments.get.relations ){
248 | commentList.value += CiteComment(comment = c.urn1, text = c.urn2)
249 | }
250 | }
251 | }
252 | }
253 |
254 |
255 | }
256 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/DataModelController.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.scm._
20 |
21 | import monix.execution.Scheduler.Implicits.global
22 | import monix.eval._
23 |
24 | import scala.scalajs.js.annotation.JSExport
25 |
26 | @JSExportTopLevel("DataModelController")
27 | object DataModelController {
28 |
29 | // Clear Data Models
30 | def clearDataModels:Unit = {
31 | DataModelModel.dataModels.value = None
32 | CiteBinaryImageModel.hasBinaryImages.value = false
33 | CiteBinaryImageModel.hasRemoteOption.value = false
34 | CiteBinaryImageModel.hasLocalOption.value = false
35 | }
36 |
37 | // Probably should be in CiteObj library?
38 | // Given a collection URN and a property name, construct a property URN
39 | def propertyUrnFromPropertyName(urn:Cite2Urn, propName:String):Cite2Urn = {
40 | val returnUrn:Cite2Urn = {
41 | urn.propertyOption match {
42 | case Some(po) => urn // just return it!
43 | case None => {
44 | val collUrn:Cite2Urn = urn.dropSelector
45 | val collUrnString:String = collUrn.toString.dropRight(1) // remove colon
46 | urn.objectComponentOption match {
47 | case Some(oc) => {
48 | Cite2Urn(s"${collUrnString}.${propName}:${oc}")
49 | }
50 | case None => {
51 | Cite2Urn(s"${collUrnString}.${propName}:")
52 | }
53 | }
54 | }
55 | }
56 | }
57 | returnUrn
58 | }
59 |
60 | // Checks to see if a text is present in the currently loaded library
61 | // Will match with ~~ similarity
62 | // *** ALERT *** for testing, I'm turning all of these into work-level URNs.
63 | def hasText(u:CtsUrn):Boolean = {
64 | O2Model.textRepo.value match {
65 | case Some(tr) => {
66 | tr.catalog.texts.filter(_.urn ~~ u.dropPassage).size match {
67 | case 0 => false
68 | case _ => true
69 | }
70 | }
71 | case None => {
72 | false
73 | }
74 | }
75 | }
76 |
77 | def hasObject(u:Cite2Urn):Boolean = {
78 | val urn:Cite2Urn = {
79 | val tempU:Cite2Urn = u.dropExtensions
80 | tempU.isRange match {
81 | case true => tempU.rangeBeginUrn
82 | case _ => tempU
83 | }
84 | }
85 | ObjectModel.collRep.value match {
86 | case Some(cr) => {
87 | cr.citableObjects.filter(_.urn == urn.dropExtensions).size match {
88 | case 1 => true
89 | case _ => false
90 | }
91 | }
92 | case None => {
93 | false
94 | }
95 | }
96 | }
97 |
98 | /* Check to see if the Citable Image datamodel is:
99 | 1. supported by this app
100 | 2. present in this library
101 | 3. implemented by the collection represented by `u`
102 | */
103 | def isCitableImage(u:Cite2Urn):Boolean ={
104 | val collUrn:Cite2Urn = u.dropSelector
105 | val citableImageModelUrn:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:imagemodel")
106 |
107 | DataModelModel.dataModels.value match {
108 | case None => false
109 | case Some(dms) => {
110 | val implementations:Vector[DataModel] = dms.filter(_.model == citableImageModelUrn).filter(_.collection == collUrn)
111 | implementations.size match {
112 | case 0 => false
113 | case _ => true
114 | }
115 | }
116 | }
117 | }
118 |
119 | /*
120 | Given a Cite2Urn, see if it identifies a property that is of type 'text' and is
121 | extended by a published protocol
122 | */
123 | // Returns None, or the type of extension
124 | def textPropertyIsExtended(propUrn:Cite2Urn):Option[String] = {
125 | try {
126 | val extensionModel:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:extensions_text")
127 | if ( DataModelModel.implementedDataModels.contains(extensionModel) ) {
128 | propUrn.propertyOption match {
129 | case Some(po) => {
130 | CiteMainModel.mainLibrary.value match {
131 | case Some(dms) => {
132 | val extendedPropColls:Vector[Cite2Urn] = dms.collectionsForModel(extensionModel)
133 | /* for each in extendedPropColls
134 | filter collection for @propertyurn
135 | */
136 | val implementingObjects:Vector[CiteObject] = {
137 | // get all objects in collection of extensions
138 | val allExtendedObjs:Vector[CiteObject] = extendedPropColls.view.map(c => ObjectModel.collRep.value.get.citableObjects.filter(_.urn ~~ c)).toVector.flatten
139 | val matchingObjs:Vector[CiteObject] = allExtendedObjs.filter( ob => {
140 | val thisPropUrn:Cite2Urn = propertyUrnFromPropertyName(ob.urn, "propertyurn")
141 | val propVal = {
142 | ob.propertyValue(thisPropUrn).asInstanceOf[Cite2Urn].objectOption match {
143 | case Some(oo) => {
144 | ob.propertyValue(thisPropUrn) == propUrn
145 | }
146 | case None => {
147 | ob.propertyValue(thisPropUrn) == propUrn.dropSelector
148 | }
149 | }
150 | }
151 | propVal
152 | })
153 | matchingObjs
154 | }
155 | implementingObjects.size match {
156 | case n if (n > 0) => {
157 | // if there is more than one, there is bad data, but we'll just return the first one.
158 | val thisObj:CiteObject = implementingObjects(0)
159 | val thisPropUrn:Cite2Urn = propertyUrnFromPropertyName(thisObj.urn, "extendedtype")
160 | val extType:String = thisObj.propertyValue(thisPropUrn).asInstanceOf[String]
161 | Some(extType)
162 | }
163 | case _ => None
164 | }
165 | }
166 | case None => None
167 | }
168 | }
169 | case None => None
170 | }
171 | } else {
172 | None
173 | }
174 | } catch {
175 | case e:Exception => Some("")
176 | }
177 | }
178 |
179 | /* Check to see if the Commentary datamodel is present */
180 | def hasCommentaryModel:Boolean = {
181 | val commUrn:Cite2Urn = CommentaryModel.commentaryModel
182 | DataModelModel.dataModels.value match {
183 | case None => false
184 | case Some(dms) => {
185 | val implementations:Vector[DataModel] = dms.filter(_.model == commUrn).toVector
186 | implementations.size match {
187 | case 0 => false
188 | case _ => true
189 | }
190 | }
191 | }
192 | }
193 |
194 |
195 | /*
196 | Methods for switching tabs and loading text and objects
197 | */
198 |
199 | def retrieveUrn(u:Urn):Unit = {
200 | u match {
201 | case CtsUrn(_) => retrieveTextPassage(None, u.asInstanceOf[CtsUrn])
202 | case Cite2Urn(_) => retrieveObject(None, u.asInstanceOf[Cite2Urn])
203 | case _ => CiteMainController.updateUserMessage(s"Could not resolve ${u} to either CtsUrn or Cite2Urn",2)
204 |
205 | }
206 | }
207 |
208 | def retrieveTextPassage(contextUrn:Option[Cite2Urn] = None, urn:CtsUrn):Unit = {
209 | O2Controller.changeUrn(urn)
210 | CiteMainView.changeTab("text")
211 | }
212 |
213 | def retrieveObject(contextUrn:Option[Cite2Urn] = None, urn:Cite2Urn):Unit = {
214 | val tempUrn:Cite2Urn = urn.dropExtensions
215 | ObjectController.changeUrn(tempUrn)
216 | ObjectController.changeObject
217 | CiteMainView.changeTab("object")
218 | }
219 |
220 |
221 | def viewImage(
222 | contextUrn:Option[Cite2Urn],
223 | implementingObject:CiteObject,
224 | urn:Cite2Urn,
225 | roiObj:ImageRoiModel.Roi
226 | ):Unit = {
227 | viewImage(contextUrn, implementingObject, urn, Some(Vector(roiObj)))
228 | }
229 |
230 |
231 | def viewImage(
232 | contextUrn:Option[Cite2Urn],
233 | implementingObject:CiteObject,
234 | urn:Cite2Urn,
235 | roiObj:Option[Vector[ImageRoiModel.Roi]]
236 | ):Unit = {
237 | CiteBinaryImageController.changeUrn(contextUrn, urn, roiObj)
238 | CiteMainView.changeTab("image")
239 | }
240 |
241 |
242 | }
243 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/DataModelModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.scm._
20 |
21 | import monix.execution.Scheduler.Implicits.global
22 | import monix.eval._
23 |
24 | import scala.scalajs.js.annotation.JSExport
25 |
26 | @JSExportTopLevel("DataModelModel")
27 | object DataModelModel {
28 |
29 | var implementedDataModels:Vector[Cite2Urn] = Vector(
30 | // Defines a basic citable image model
31 | Cite2Urn("urn:cite2:cite:datamodels.v1:imagemodel"),
32 | // Defines an image that can be delivered as binary image data
33 | Cite2Urn("urn:cite2:cite:datamodels.v1:binaryimg"),
34 | // Defines a "codex model" of ordered text-bearing surfaces
35 | //Cite2Urn("urn:cite2:cite:datamodels.v1:tbsmodel"),
36 | // Defines a "documented scholarly editions" model of surface + image + text
37 | Cite2Urn("urn:cite2:cite:datamodels.v1:dsemodel"),
38 | // Defines a CITE Collection property of type `text` more precisely
39 | Cite2Urn("urn:cite2:cite:datamodels.v1:extensions_text")
40 | )
41 |
42 | val dataModels = Var[Option[Vector[DataModel]]](None)
43 |
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/ExtendedTextPropertyView.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.scm._
20 |
21 | import monix.execution.Scheduler.Implicits.global
22 | import monix.eval._
23 | import com.karasiq.highlightjs.HighlightJS
24 | import com.karasiq.markedjs.{Marked, MarkedOptions, MarkedRenderer}
25 | import scala.scalajs.js.annotation.JSExport
26 |
27 | @JSExportTopLevel("ExtendedTextPropertyView")
28 | object ExtendedTextPropertyView {
29 |
30 | // Returns None, or the type of extension
31 | def textPropertyIsExtended(propUrn:Cite2Urn):Option[String] = {
32 | None
33 | }
34 |
35 | /*
36 | @dom
37 | def xxxxxxxextendedTextLinks(contextUrn:Option[Cite2Urn], p:ObjectModel.BoundCiteProperty) = {
38 | String Type:
{
39 | val extendedOption:Option[String] = DataModelController.textPropertyIsExtended(p.urn.value)
40 | extendedOption match {
41 | case Some("markdown") => {
42 | initiateMarked(s"${p.propertyValue.bind}", s"propertyField_${p.urn.bind}")
43 | }
44 | case _ => {
45 | g.console.log(s"No extension.")
46 | }
47 | }
48 | }
49 |
50 | { s"${p.propertyValue.bind.toString}" }
51 |
52 | }
53 | */
54 |
55 | @dom
56 | def extendedTextLinks(contextUrn:Option[Cite2Urn], p:ObjectModel.BoundCiteProperty) = {
57 | val extendedOption:Option[String] = DataModelController.textPropertyIsExtended(p.urn.value)
58 | extendedOption match {
59 | case Some("markdown") => {
60 | markdownTextContent(p).bind
61 | }
62 | case Some("teixml") => {
63 | teiTextContent(p).bind
64 | }
65 | case Some("pleiadesuri") => {
66 | pleiadesTextContent(p).bind
67 | }
68 | case Some("latlong") => {
69 | latLongTextContent(p).bind
70 | }
71 | case Some("geojson") => {
72 | geojsonTextContent(p).bind
73 | }
74 | case _ => {
75 | plainTextContent(p).bind
76 | }
77 | }
78 | }
79 |
80 | @dom
81 | def geojsonTextContent(p:ObjectModel.BoundCiteProperty) = {
82 | val geojson:String = p.propertyValue.bind.trim
83 | g.console.log(geojson)
84 | val elId:String = s"propertyField_${p.urn.bind}"
85 | initiateLeafletWithGeoJson(geojson, elId)
86 | { s"Leaflet.js map will be drawn here: ${p.propertyValue.bind.toString}" }
87 | }
88 |
89 | @dom
90 | def latLongTextContent(p:ObjectModel.BoundCiteProperty) = {
91 | val lat:String = p.propertyValue.bind.split(",")(0).trim
92 | val long:String = p.propertyValue.bind.split(",")(1).trim
93 | val elId:String = s"propertyField_${p.urn.bind}"
94 | initiateLeafletWithLatLong(lat, long, elId)
95 | { s"Leaflet.js map will be drawn here: ${p.propertyValue.bind.toString}" }
96 | }
97 |
98 | @dom
99 | def plainTextContent(p:ObjectModel.BoundCiteProperty) = {
100 | { s"${p.propertyValue.bind.toString}" }
101 | }
102 |
103 | @dom
104 | def markdownTextContent(p:ObjectModel.BoundCiteProperty) = {
105 | initiateMarked(s"${p.propertyValue.bind}", s"propertyField_${p.urn.bind}")
106 |
107 | { s"${p.propertyValue.bind.toString}" }
108 |
109 | }
110 |
111 | @dom
112 | def teiTextContent(p:ObjectModel.BoundCiteProperty) = {
113 | val thisSpan = document.createElement("span").asInstanceOf[HTMLSpanElement]
114 | thisSpan.innerHTML = p.propertyValue.bind
115 | thisSpan
116 | }
117 |
118 | @dom
119 | def pleiadesTextContent(p:ObjectModel.BoundCiteProperty) = {
120 |
121 | { "Pleiades place resource: "}
122 |
123 | { p.propertyValue.bind }
124 |
125 |
126 | }
127 |
128 |
129 | def getMarkdownProperyAndId(p:ObjectModel.BoundCiteProperty):Map[String,String] = {
130 | val propertyName:String = ""
131 | Map("id" -> "some id", "content" -> "some content.")
132 | }
133 |
134 | /* Methods for connecting out to Javascript */
135 | @JSGlobal("initiateMarked")
136 | @js.native
137 | object initiateMarked extends js.Any {
138 | def apply(markdownString:String, elementId:String): js.Dynamic = js.native
139 | }
140 |
141 | @JSGlobal("initiateLeafletWithLatLong")
142 | @js.native
143 | object initiateLeafletWithLatLong extends js.Any {
144 | def apply(lat:String, long:String, elementId:String): js.Dynamic = js.native
145 | }
146 |
147 | @JSGlobal("initiateLeafletWithGeoJson")
148 | @js.native
149 | object initiateLeafletWithGeoJson extends js.Any {
150 | def apply(geojson:String, elementId:String): js.Dynamic = js.native
151 | }
152 | }
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/ImageRoiModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import scala.scalajs.js.Dynamic.{ global => g }
8 | import js.annotation._
9 | import collection.mutable
10 | import collection.mutable._
11 | import org.scalajs.dom._
12 | import org.scalajs.dom.ext._
13 | import org.scalajs.dom.raw._
14 | import edu.holycross.shot.cite._
15 | import edu.holycross.shot.ohco2._
16 | import edu.holycross.shot.citeobj._
17 |
18 | import scala.scalajs.js.annotation.JSExport
19 | import js.annotation._
20 |
21 | /*
22 | Defines a model for Image ROIs, defined rectangles on citable images, associated with
23 | Cite and CTS Urns.
24 | */
25 |
26 | @JSExportTopLevel("ImageRoiModel")
27 | object ImageRoiModel {
28 |
29 | case class ImageRoi(imageUrn:Cite2Urn, rois:Vars[Roi]) {
30 | override def toString = s"Image: ${imageUrn}. ${rois}"
31 | }
32 |
33 | case class Roi(val l:Float, t:Float, w:Float, h:Float, dataUrn:Option[Urn] = None, contextUrn:Option[Cite2Urn] = None ) {
34 | override def toString = s"left:${l}, top:${t}, width:${w}, height:${h} => ${dataUrn}"
35 | def toSubrefString:String = {
36 | s"${l},${t},${w},${h}"
37 | }
38 | }
39 |
40 | def roiFromUrn(u:Cite2Urn, data:Option[Urn] = None, context:Option[Cite2Urn] = None):Option[Roi] = {
41 | // in this case, there will be only one Roi object in the ImageRoi
42 | try {
43 | u.objectExtensionOption match {
44 | case Some(oe) => {
45 | val parts = oe.split(",")
46 | if (parts.size != 4) throw new Exception(s"${oe} did not contain four, comma-separated values.")
47 | val l:Float = parts(0).toFloat
48 | val t:Float = parts(1).toFloat
49 | val w:Float = parts(2).toFloat
50 | val h:Float = parts(3).toFloat
51 | if ( (l <0) | ( l > 1) ) throw new Exception(s"${l} must be > 0 and < 1.")
52 | if ( (t <0) | ( t > 1) ) throw new Exception(s"${t} must be > 0 and < 1.")
53 | if ( (w <0) | ( w > 1) ) throw new Exception(s"${w} must be > 0 and < 1.")
54 | if ( (h <0) | ( h > 1) ) throw new Exception(s"${h} must be > 0 and < 1.")
55 | // Got here and we're good
56 | val roi:Roi = Roi(l,t,w,h,data, context)
57 | Some(roi)
58 | }
59 | case None => None
60 | }
61 | } catch {
62 | case e:Exception => throw new Exception(s"Unable to make ROI from ${u}. ${e}")
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/NGModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import org.scalajs.dom._
8 | import org.scalajs.dom.ext._
9 | import org.scalajs.dom.raw._
10 | import edu.holycross.shot.cite._
11 | import edu.holycross.shot.ohco2._
12 | import edu.holycross.shot.citeobj._
13 | import scala.scalajs.js.Dynamic.{ global => g }
14 |
15 | import scala.scalajs.js.annotation.JSExport
16 | import js.annotation._
17 |
18 | @JSExportTopLevel("NGModel")
19 | object NGModel {
20 |
21 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null
22 |
23 | var corpusOrUrn = Var[Option[CtsUrn]](None)
24 |
25 | val urn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage"))
26 |
27 | val shortWorkLabel = Var("default")
28 |
29 | val citedWorks = Vars.empty[CtsUrn]
30 |
31 | val userMessage = Var("")
32 | val userAlert = Var("default")
33 | val userMessageVisibility = Var("app_hidden")
34 |
35 | /* For recording queries */
36 |
37 | class CtsQuery( urn:Option[CtsUrn]) {
38 | override def toString:String = {
39 | val s:String = s"Generic query on ${urn}."
40 | s
41 | }
42 | }
43 |
44 | case class NGramQuery(n:Integer, t:Integer, fs: String, ip: Boolean, urn:Option[CtsUrn] ) extends CtsQuery(urn){
45 | // this.getClass.getName will yield 'citeapp.NGModel$NGramQuery'
46 | override def toString:String = {
47 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"}
48 | val s = s"""NGram Query: n=${n}; threshold = ${t}; ignore-punctuation=${ip}; filtered by "${fs}"; scope=${ scope }."""
49 | s
50 | }
51 |
52 | }
53 |
54 | case class StringSearch(fs: String, urn:Option[CtsUrn] ) extends CtsQuery(urn) {
55 | override def toString:String = {
56 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"}
57 | val s = s"""String Search: "${fs}"; scope=${ scope }."""
58 | s
59 | }
60 |
61 | }
62 |
63 |
64 | case class TokenSearch(tt: Vector[String], p:Integer, urn:Option[CtsUrn]) extends CtsQuery(urn){
65 | override def toString:String = {
66 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"}
67 | val s = s"""Token Search: "${tt.mkString(", ")}"; proximity=${p}; scope=${ scope }."""
68 | s
69 | }
70 | }
71 |
72 | val pastQueries = Vars.empty[CtsQuery]
73 |
74 | /* for holding search results */
75 | case class SearchResult(urn: Var[CtsUrn], kwic: Var[String])
76 | val citationResults = Vars.empty[SearchResult]
77 |
78 | /* Values for NGrams */
79 | val nGramThreshold = Var(3)
80 |
81 | val nGramResults = Vars.empty[StringCount]
82 |
83 | val nGramQueryReport = Var("")
84 | val otherQueryReport = Var("")
85 |
86 | /* Values for Search */
87 | val tokenSearchProximity = Var(20)
88 |
89 | /* Some methods for working the model */
90 |
91 | @dom
92 | def updateShortWorkLabel = {
93 | if ( O2Model.textRepo.value == None){
94 | NGModel.shortWorkLabel.value = "- no selected text -"
95 | } else {
96 | val longS:String = O2Model.textRepo.value.get.catalog.label(NGModel.urn.value)
97 | if (longS.size > 50){
98 | val shortS:String = longS.take(24) + " … " + longS.takeRight(23)
99 | NGModel.shortWorkLabel.value = shortS
100 | } else {
101 | NGModel.shortWorkLabel.value = longS
102 | }
103 | }
104 | }
105 |
106 | @dom
107 | def updateCitedWorks = {
108 | NGModel.citedWorks.value.clear
109 | NGController.clearResults
110 | NGController.clearInputs
111 | // N.b. The textRepository remains with the Ohco2 Model.
112 | for ( cw <- O2Model.textRepo.value.get.corpus.citedWorks){
113 | NGModel.citedWorks.value += cw
114 | }
115 | }
116 |
117 |
118 | /* NGram Searching */
119 |
120 | def getNGram(filterString: String, n: Int, occ: Int, ignorePunc: Boolean ): StringHistogram = {
121 | getNGram(O2Model.textRepo.value.get.corpus, filterString, n, occ, ignorePunc)
122 | }
123 |
124 | def getNGram(ngUrn: CtsUrn, filterString: String, n: Int, occ: Int, ignorePunc: Boolean): StringHistogram = {
125 | val newCorpus: Corpus = O2Model.textRepo.value.get.corpus ~~ ngUrn
126 | getNGram(newCorpus, filterString, n, occ, ignorePunc)
127 | }
128 |
129 | def getNGram(ngCorpus:Corpus, filterString: String, n: Int, occ: Int, ignorePunc: Boolean ): StringHistogram = {
130 |
131 | val hist:StringHistogram = {
132 | if( filterString == ""){
133 | ngCorpus.ngramHisto(n, occ, ignorePunc)
134 | } else {
135 | ngCorpus.ngramHisto(filterString, n, occ , ignorePunc)
136 | }
137 | }
138 | hist
139 | }
140 |
141 | def getUrnsForNGram(s: String, ignorePunc: Boolean ): Vector[CtsUrn] ={
142 | val vurn = O2Model.textRepo.value.get.corpus.urnsForNGram(s, 1, ignorePunc)
143 | vurn
144 | }
145 |
146 | def getUrnsForNGram(ngUrn: CtsUrn, s: String, ignorePunc: Boolean ): Vector[CtsUrn] ={
147 | val newCorpus: Corpus = O2Model.textRepo.value.get.corpus >= ngUrn
148 | val vurn = newCorpus.urnsForNGram(s, 1, ignorePunc)
149 | vurn
150 | }
151 |
152 | def getUrnsForNGram(ngCorpus: Corpus, s: String, ignorePunc: Boolean ): Vector[CtsUrn] = {
153 | val vurn = ngCorpus.urnsForNGram(s, 1, ignorePunc)
154 | vurn
155 | }
156 |
157 | /* String and Token Finding */
158 | def findString(urn:CtsUrn, s:String):Corpus = {
159 | val tempCorpus = O2Model.textRepo.value.get.corpus >= urn
160 | val foundCorpus = tempCorpus.find(s)
161 | foundCorpus
162 | }
163 |
164 | def findString(s:String):Corpus = {
165 | val foundCorpus = O2Model.textRepo.value.get.corpus.find(s)
166 | foundCorpus
167 | }
168 |
169 |
170 |
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/O2Controller.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import org.scalajs.dom._
8 | import org.scalajs.dom.ext._
9 | import org.scalajs.dom.raw._
10 | import edu.holycross.shot.cite._
11 | import edu.holycross.shot.ohco2._
12 | import edu.holycross.shot.citeobj._
13 | import scala.concurrent._
14 | import scala.scalajs.js.Dynamic.{ global => g }
15 | //import ExecutionContext.Implicits.global
16 | import monix.execution.Scheduler.Implicits.global
17 | import monix.eval._
18 |
19 | import scala.scalajs.js.annotation.JSExport
20 | import js.annotation._
21 |
22 | @JSExportTopLevel("O2Controller")
23 | object O2Controller {
24 |
25 |
26 | val validUrnInField = Var(false)
27 |
28 |
29 | /* A lot of work gets done here */
30 | def changePassage: Unit = {
31 | val timeStart = new js.Date().getTime()
32 | val newUrn: CtsUrn = O2Model.urn.value
33 | O2Model.updateUrnHistory(newUrn)
34 | val task1 = Task{
35 | O2Model.versionsForCurrentUrn.value = O2Model.versionsForUrn(newUrn)
36 | O2Model.displayPassage(newUrn)
37 | val timeEnd = new js.Date().getTime()
38 | O2Controller.updateUserMessage(s"Fetched ${O2Model.currentNumberOfCitableNodes.value} citation objects in ${(timeEnd - timeStart)/1000} seconds.",0)
39 | }
40 | val future1 = task1.runAsync
41 | val task2 = Task{ O2Model.getPrevNextUrn(O2Model.urn.value) }
42 | val future2 = task2.runAsync
43 | }
44 |
45 |
46 | def updateUserMessage(msg: String, alert: Int): Unit = {
47 | O2Model.userMessageVisibility.value = "app_visible"
48 | O2Model.userMessage.value = msg
49 | alert match {
50 | case 0 => O2Model.userAlert.value = "default"
51 | case 1 => O2Model.userAlert.value = "wait"
52 | case 2 => O2Model.userAlert.value = "warn"
53 | }
54 | js.timers.clearTimeout(O2Model.msgTimer)
55 | O2Model.msgTimer = js.timers.setTimeout(6000){ O2Model.userMessageVisibility.value = "app_hidden" }
56 | }
57 |
58 |
59 | def validateUrn(urnString: String): Unit = {
60 | try{
61 | val newUrn: CtsUrn = CtsUrn(urnString)
62 | validUrnInField.value = true
63 | } catch {
64 | case e: Exception => {
65 | validUrnInField.value = false
66 | }
67 | }
68 | }
69 |
70 | def getNext:Unit = {
71 | if (O2Model.currentNext.value != None){
72 | changeUrn(O2Model.currentNext.value.get)
73 | }
74 | }
75 |
76 | def getPrev:Unit = {
77 | if (O2Model.currentPrev.value != None){
78 | changeUrn(O2Model.currentPrev.value.get)
79 | }
80 | }
81 |
82 | def changeUrn(urnString: String): Unit = {
83 | changeUrn(CtsUrn(urnString))
84 | }
85 |
86 |
87 | def changeUrn(urn: CtsUrn): Unit = {
88 | try {
89 | O2Model.urn.value = urn
90 | O2Model.displayUrn.value = urn
91 | validUrnInField.value = true
92 | O2Controller.updateUserMessage("Retrieving passage…",1)
93 | val task = Task{ O2Controller.changePassage }
94 | val future = task.runAsync
95 | /*
96 | js.timers.setTimeout(200){
97 | Future{
98 | O2Controller.changePassage
99 | }
100 | }
101 | */
102 |
103 | } catch {
104 | case e: Exception => {
105 | validUrnInField.value = false
106 | updateUserMessage("Invalid URN. Current URN not changed.",2)
107 | }
108 | }
109 | }
110 |
111 |
112 | def insertFirstNodeUrn(urn: CtsUrn): Unit = {
113 | val firstUrn = O2Model.textRepo.value.get.corpus.firstNode(urn).urn
114 | js.Dynamic.global.document.getElementById("o2_urnInput").value = firstUrn.toString
115 | validUrnInField.value = true
116 | }
117 |
118 |
119 | @dom
120 | def preloadUrn = {
121 | O2Model.urn.value = O2Model.textRepo.value.get.corpus.firstNode(O2Model.textRepo.value.get.corpus.citedWorks(0)).urn
122 | O2Controller.validUrnInField.value = true
123 | }
124 |
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/O2Model.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import scala.scalajs.js.Dynamic.{ global => g }
8 | import scala.collection.mutable.LinkedHashMap
9 | import org.scalajs.dom._
10 | import org.scalajs.dom.ext._
11 | import org.scalajs.dom.raw._
12 | import edu.holycross.shot.cite._
13 | import edu.holycross.shot.ohco2._
14 | import edu.holycross.shot.citeobj._
15 | import scala.collection.immutable.SortedMap
16 |
17 | import scala.scalajs.js.annotation.JSExport
18 | import js.annotation._
19 |
20 | @JSExportTopLevel("O2Model")
21 | object O2Model {
22 |
23 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null
24 |
25 | case class VersionNodeBlock(versionUrn:Var[CtsUrn],nodes:Vars[CitableNode])
26 |
27 | case class BoundCorpus(versionUrn:Var[CtsUrn], versionLabel:Var[String], versionNodes:Vars[VersionNodeBlock] )
28 |
29 | val currentCorpus = Vars.empty[BoundCorpus]
30 |
31 | val currentNumberOfCitableNodes = Var(0)
32 | val currentListOfUrns = Vars.empty[CtsUrn]
33 | val isRtlPassage = Var(false)
34 |
35 | // for navigation
36 | val urnHistory = Vars.empty[(Int,CtsUrn,String)]
37 |
38 |
39 | // Add an entry to the citation-history
40 | def updateUrnHistory(u:CtsUrn):Unit = {
41 | try {
42 | if (textRepo.value != None) {
43 |
44 | val tempList:List[Tuple2[CtsUrn,String]] = urnHistory.value.toList.reverse.map(t => { Tuple2(t._2, t._3)})
45 | val newTempList:List[Tuple2[CtsUrn,String]] = tempList ++ List(Tuple2(u,textRepo.value.get.label(u)))
46 | val indexedTempList:List[Tuple3[Int,CtsUrn,String]] = newTempList.zipWithIndex.map( t => {
47 | Tuple3((t._2 + 1),t._1._1,t._1._2)
48 | })
49 | val reversedList = indexedTempList.reverse
50 | urnHistory.value.clear
51 | for (t <- reversedList) { urnHistory.value += t }
52 | }
53 | } catch{
54 | case e:Exception => O2Controller.updateUserMessage(s"Unable to make label for ${u}: ${e}",2)
55 | }
56 | }
57 |
58 |
59 | // urn is what the user requested
60 | val urn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage"))
61 | // displayUrn is what will be shown
62 | val displayUrn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage"))
63 | val versionsForCurrentUrn = Var(1)
64 |
65 | val userMessage = Var("")
66 | val userAlert = Var("default")
67 | val userMessageVisibility = Var("app_hidden")
68 |
69 | val textRepo = Var[Option[TextRepository]](None)
70 | val citedWorks = Vars.empty[CtsUrn]
71 |
72 | val currentNext = Var[Option[CtsUrn]](None)
73 | val currentPrev = Var[Option[CtsUrn]](None)
74 |
75 |
76 | /* Some methods for working the model */
77 | def versionsForUrn(urn:CtsUrn):Int = {
78 | var versions = 0
79 | if (O2Model.textRepo.value != None){
80 | val s = s"urn:cts:${urn.namespace}:${urn.textGroup}.${urn.work}:"
81 | val versionVector = O2Model.textRepo.value.get.catalog.entriesForUrn(CtsUrn(s))
82 | versions = versionVector.size
83 | }
84 | versions
85 | }
86 |
87 | def getPrevNextUrn(urn:CtsUrn):Unit = {
88 | O2Model.currentPrev.value = O2Model.textRepo.value.get.corpus.prevUrn(urn)
89 | O2Model.currentNext.value = O2Model.textRepo.value.get.corpus.nextUrn(urn)
90 | }
91 |
92 | def collapseToWorkUrn(urn:CtsUrn):CtsUrn = {
93 | val s = {
94 | s"urn:cts:${urn.namespace}:${urn.textGroup}.${urn.work}:${urn.passageComponent}"
95 | }
96 | val u = CtsUrn(s)
97 | u
98 | }
99 |
100 | def updateCurrentListOfUrns(c:Corpus):Unit = {
101 | O2Model.currentListOfUrns.value.clear
102 | for (n <- c.nodes){
103 | O2Model.currentListOfUrns.value += n.urn
104 | }
105 | }
106 |
107 |
108 | // case class BoundCorpus(versionUrn:Var[CtsUrn], versionLabel:Var[String], nodes:Vars[CitableNode] )
109 | // val currentCorpus = Vars.empty[BoundCorpus]
110 |
111 | def updateCurrentCorpus(c:Corpus, u:CtsUrn):Unit = {
112 | try {
113 | O2Model.currentCorpus.value.clear
114 | if (O2Model.textRepo.value != None) {
115 | // Since GroupBy doesn't preserve order, let's preserve our own order
116 | val versionLevelOrder:Vector[CtsUrn] = {
117 | c.urns.map(u => dropOneLevel(u)).distinct.toVector
118 | }
119 | // Get Corpus into a Vector of tuples: (version-level-urn, vector[CitableNode])
120 | val tempCorpusVector:Vector[(CtsUrn, Vector[CitableNode])] = c.nodes.groupBy(_.urn.dropPassage).toVector
121 | // in correct order to this point
122 | for (tc <- tempCorpusVector) {
123 | val versionLabel:String = O2Model.textRepo.value.get.catalog.label(tc._1)
124 | val passageString:String = {
125 | u.passageComponent
126 | }
127 | // in correct order to this point
128 | val boundVersionLabel = Var(versionLabel)
129 |
130 | val versionUrn:CtsUrn = CtsUrn(s"${tc._1}${passageString}")
131 | val boundVersionUrn = Var(versionUrn)
132 |
133 | // Group node urns according to nodeBlocks
134 | val nodeBlocks:Vector[(CtsUrn, Vector[CitableNode])] = {
135 | tc._1.exemplarOption match {
136 | case Some(eo) => {
137 | val block:Vector[(CtsUrn,Vector[CitableNode])] = {
138 | tc._2.groupBy(n => dropOneLevel(n.urn)).toVector
139 | }
140 | val block2 = tc._2.zipWithIndex.groupBy(n => dropOneLevel(n._1.urn))
141 | val lhm = LinkedHashMap(block2.toSeq sortBy (_._2.head._2): _*)
142 | val block3 = lhm mapValues (_ map (_._1))
143 | val sortedBlock = block3.toVector
144 | sortedBlock
145 | }
146 | case None => {
147 | Vector( (tc._1,tc._2) )
148 | }
149 | }
150 | }
151 | // Get this nodeBlock into a versionNodeBlock
152 | val tempNodeBlockVec = Vars.empty[VersionNodeBlock]
153 | for (b <- nodeBlocks){
154 | val tempBlockUrn = Var(b._1)
155 | val tempNodesVec = Vars.empty[CitableNode]
156 | for (n <- b._2) tempNodesVec.value += n
157 | tempNodeBlockVec.value += VersionNodeBlock(tempBlockUrn, tempNodesVec)
158 | }
159 |
160 | /*
161 | val tempNodesBindingVector = Vars.empty[CitableNode]
162 | for (n <- tc._2) {
163 | tempNodesBindingVector.value += n
164 | }
165 | */
166 | O2Model.currentCorpus.value += BoundCorpus(boundVersionUrn, boundVersionLabel, tempNodeBlockVec)
167 | }
168 | }
169 |
170 | } catch {
171 | case e:Exception => {
172 | O2Controller.updateUserMessage(s"O2Model Exception in 'updateCurrentCorpus': ${e}",2)
173 | }
174 | }
175 | }
176 |
177 | def dropOneLevel(u:CtsUrn):CtsUrn = {
178 | try {
179 | val passage:String = u.passageComponent
180 | val plainUrn:String = u.dropPassage.toString
181 | val newPassage:String = passage.split('.').dropRight(1).mkString(".")
182 | val droppedUrn:CtsUrn = CtsUrn(s"${plainUrn}${newPassage}")
183 | droppedUrn
184 | } catch {
185 | case e:Exception => {
186 | O2Controller.updateUserMessage(s"Error dropping one level from ${u}: ${e}",2)
187 | throw new Exception(s"${e}")
188 | }
189 | }
190 | }
191 |
192 |
193 | def displayNewPassage(urn:CtsUrn):Unit = {
194 | O2Model.displayPassage(urn)
195 | }
196 |
197 | @dom
198 | def clearPassage:Unit = {
199 | //O2Model.xmlPassage.innerHTML = ""
200 | O2Model.versionsForCurrentUrn.value = 0
201 | O2Model.currentListOfUrns.value.clear
202 | DSEModel.currentListOfDseUrns.value.clear
203 | O2Model.currentCorpus.value.clear
204 | }
205 |
206 | def passageLevel(u:CtsUrn):Int = {
207 | try {
208 | val urn = u.dropSubref
209 | if (urn.isRange) throw new Exception(s"Cannot report passage level for ${urn} becfause it is a range.")
210 | urn.passageComponent.size match {
211 | case n if (n > 0) => {
212 | urn.passageComponent.split('.').size
213 | }
214 | case _ => throw new Exception(s"Cannot report passage level for ${urn} because it does not have a passage component.")
215 | }
216 | } catch {
217 | case e:Exception => throw new Exception(s"${e}")
218 | }
219 | }
220 |
221 | def valueForLevel(u:CtsUrn,level:Int):String = {
222 | try {
223 | val urn = u.dropSubref
224 | val pl:Int = passageLevel(urn)
225 | if (pl < level) throw new Exception(s"${u} has a ${pl}-deep citation level, which is less than ${level}.")
226 | urn.passageComponent.size match {
227 | case n if (n > 0) => {
228 | urn.passageComponent.split('.')(level-1)
229 | }
230 | case _ => throw new Exception(s"Cannot report passage level for ${u} because it does not have a passage component.")
231 | }
232 | } catch {
233 | case e:Exception => throw new Exception(s"${e}")
234 | }
235 | }
236 |
237 | @dom
238 | def displayPassage(newUrn: CtsUrn):Unit = {
239 | val tempCorpus: Corpus = O2Model.textRepo.value.get.corpus >= newUrn
240 | O2Model.updateCurrentListOfUrns(tempCorpus)
241 | DSEModel.updateCurrentListOfDseUrns(tempCorpus)
242 | CommentaryModel.updateCurrentListOfComments(tempCorpus)
243 | O2Model.updateCurrentCorpus(tempCorpus, newUrn)
244 | O2Model.currentNumberOfCitableNodes.value = tempCorpus.size
245 | }
246 |
247 |
248 |
249 | def checkForRTL(s:String):Boolean = {
250 | val sStart = s.take(10)
251 | val arabicBlock = "[\u0600-\u06FF]".r
252 | val hebrewBlock = "[\u0591-\u05F4]".r
253 | var isRtl:Boolean = ((arabicBlock findAllIn sStart).nonEmpty || (hebrewBlock findAllIn sStart).nonEmpty)
254 | isRtl
255 | }
256 |
257 |
258 |
259 | @dom
260 | def updateCitedWorks = {
261 | O2Model.citedWorks.value.clear
262 | for ( cw <- O2Model.textRepo.value.get.corpus.citedWorks){
263 | O2Model.citedWorks.value += cw
264 | }
265 | }
266 |
267 |
268 | }
269 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/QueryObjectModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import scala.scalajs.js.Dynamic.{ global => g }
8 | import js.annotation._
9 | import collection.mutable
10 | import collection.mutable._
11 | import org.scalajs.dom._
12 | import org.scalajs.dom.ext._
13 | import org.scalajs.dom.raw._
14 | import edu.holycross.shot.cite._
15 | import edu.holycross.shot.ohco2._
16 | import edu.holycross.shot.citeobj._
17 |
18 | import scala.scalajs.js.annotation.JSExport
19 | import js.annotation._
20 |
21 | @JSExportTopLevel("QueryObjectModel")
22 | object QueryObjectModel {
23 |
24 | val pastQueries = Vars.empty[CiteCollectionQuery]
25 | val currentQuery = Var[Option[CiteCollectionQuery]](None)
26 | val isValidSearch = Var(false)
27 |
28 | val currentQueryCollection = Var[Option[Cite2Urn]](None)
29 | val currentQueryCollectionProps = Vars.empty[CitePropertyDef]
30 | val queryProperty = Var[Option[CitePropertyDef]](None)
31 | val selectedPropertyType = Var[Option[CitePropertyType]](Some(StringType))
32 | val currentControlledVocabulary = Vars.empty[String]
33 | val currentControlledVocabItem = Var[Option[String]](None)
34 | val currentSearchString = Var[Option[String]](None)
35 | val currentRegexState = Var(false)
36 | val currentCaseSensitiveState = Var(false)
37 |
38 | val currentNumericQuery1 = Var[Option[BigDecimal]](None)
39 | val currentNumericQuery2 = Var[Option[BigDecimal]](None)
40 | val currentNumericOperator = Var("eq")
41 |
42 | val currentBooleanVal = Var(true)
43 |
44 | val currentCtsUrnQuery = Var[Option[CtsUrn]](None)
45 | val currentCite2UrnQuery = Var[Option[Cite2Urn]](None)
46 |
47 | def clearAll = {
48 | currentQuery.value = None
49 | isValidSearch.value = false
50 | currentQueryCollectionProps.value.clear
51 | queryProperty.value = None
52 | selectedPropertyType.value = Some(StringType)
53 | currentControlledVocabulary.value.clear
54 | currentControlledVocabItem.value = None
55 | currentSearchString.value = None
56 | currentRegexState.value = false
57 | currentCaseSensitiveState.value = false
58 | currentNumericQuery1.value = None
59 | currentNumericQuery2.value = None
60 | currentBooleanVal.value = true
61 | currentCtsUrnQuery.value = None
62 | currentCite2UrnQuery.value = None
63 | }
64 |
65 | case class CiteCollectionQuery(
66 | val qCollection: Option[Cite2Urn],
67 | val qProperty: Option[CitePropertyDef] = None ,
68 | val qPropertyType: Option[CitePropertyType],
69 | val qControlledVocabItem: Option[String] = None,
70 | val qSearchString: Option[String] = None,
71 | val qRegex:Option[Boolean] = None,
72 | val qCaseSensitive: Option[Boolean] = None,
73 | val qNum1: Option[BigDecimal] = None,
74 | val qNum2: Option[BigDecimal] = None,
75 | val qNumOperator: Option[String] = None,
76 | val qBoolVal: Option[Boolean] = None,
77 | val qCtsUrn: Option[CtsUrn] = None,
78 | val qCite2Urn: Option[Cite2Urn] = None
79 | ) {
80 |
81 | var numResults:Int = 0
82 |
83 | override def toString:String = {
84 | var qds:String = ""
85 | qCollection match {
86 | case Some(x) => qds += s"${x.toString} :"
87 | case None => qds += s"All collections. "
88 | }
89 | qProperty match {
90 | case Some(x) => qds += s"Property: ${x.label}. "
91 | case _ => qds += s"All properties. "
92 | }
93 | qPropertyType match {
94 | case Some(x) => qds += s"${x}. "
95 | case _ => qds += s"No property type. "
96 | }
97 | qSearchString match {
98 | case Some(x) => {
99 | qds += s"Search for “${x}”. "
100 | qCaseSensitive match {
101 | case Some(true) => qds += s"Case sensitive. "
102 | case _ => qds += ""
103 | }
104 | qRegex match {
105 | case Some(true) => qds += s"With Regex. "
106 | case _ => qds += ""
107 | }
108 | }
109 | case _ => qds += ""
110 | }
111 | qControlledVocabItem match {
112 | case Some(x) => qds += s"Search for Controlled Vocabulary Item “${x}”. "
113 | case _ => qds += ""
114 | }
115 | qBoolVal match {
116 | case Some(x) => qds += s"Search for Boolean value [${x}]. "
117 | case _ => qds += ""
118 | }
119 | qCtsUrn match {
120 | case Some(x) => qds += s"Search for Cts Urn ${x}. "
121 | case _ => qds += ""
122 | }
123 | qCite2Urn match {
124 | case Some(x) => qds += s"Search for Cite2 Urn ${x}. "
125 | case _ => qds += ""
126 | }
127 | qNumOperator match {
128 | case Some(x) => {
129 | x match {
130 | case "inRange" => qds += s"Search for value in range ${qNum1.get}–${qNum2.get}. "
131 | case "eq" => qds += s"Search for value = ${qNum1.get}. "
132 | case "gt" => qds += s"Search for value > ${qNum1.get}. "
133 | case "lt" => qds += s"Search for value < ${qNum1.get}. "
134 | case "gteq" => qds += s"Search for value >= ${qNum1.get}. "
135 | case "lteq" => qds += s"Search for value <= ${qNum1.get}. "
136 | }
137 | }
138 | case _ => qds += ""
139 | }
140 | qds += s" (${numResults} Objects)"
141 | qds
142 | }
143 | }
144 |
145 |
146 | def validateNumericEntry(thisEvent: Event):Unit = {
147 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement]
148 | val testText = thisTarget.value.toString
149 | var previousEntry:Option[BigDecimal] = None
150 | thisTarget.id match {
151 | case "queryObject_numeric1" => previousEntry = currentNumericQuery1.value
152 | case "queryObject_numeric2" => previousEntry = currentNumericQuery2.value
153 | case _ => previousEntry = None
154 | }
155 | try{
156 | val mo:BigDecimal = testText.toDouble
157 | thisTarget.id match {
158 | case "queryObject_numeric1" => currentNumericQuery1.value = Some(mo)
159 | case "queryObject_numeric2" => currentNumericQuery2.value = Some(mo)
160 | }
161 | } catch {
162 | case e: Exception => {
163 | val badMo: String = testText
164 | thisTarget.value = ""
165 | ObjectController.updateUserMessage(s""" "${badMo}" is not a numeric value.""", 2)
166 | }
167 | }
168 | }
169 |
170 | def validateCtsUrnEntry(thisEvent: Event):Unit = {
171 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement]
172 | val testText = thisTarget.value.toString
173 | try{
174 | val testCts:CtsUrn = CtsUrn(testText)
175 | currentCtsUrnQuery.value = Some(testCts)
176 | } catch {
177 | case e: Exception => {
178 | val badMo: String = testText
179 | thisTarget.value = ""
180 | ObjectController.updateUserMessage(s"${badMo} is not a valid CTS URN.", 2)
181 | }
182 | }
183 | }
184 |
185 | def validateCite2UrnEntry(thisEvent: Event):Unit = {
186 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement]
187 | val testText = thisTarget.value.toString
188 | try{
189 | val testCite2:Cite2Urn = Cite2Urn(testText)
190 | currentCite2UrnQuery.value = Some(testCite2)
191 | } catch {
192 | case e: Exception => {
193 | val badMo: String = testText
194 | thisTarget.value = ""
195 | ObjectController.updateUserMessage(s"${badMo} is not a valid CITE2 URN.", 2)
196 | }
197 | }
198 | }
199 |
200 | /* Based on whether we're set up to query all properties or a single one,
201 | load controlled vocabulary into a binding Vars */
202 | @dom
203 | def loadControlledVocabulary = {
204 | QueryObjectModel.currentQueryCollection.value match {
205 | case None => loadControlledVocablAll
206 | case _ => loadControlledVocablOne
207 | }
208 | }
209 |
210 | @dom
211 | def loadControlledVocablAll = {
212 | QueryObjectModel.currentControlledVocabulary.value.clear
213 | var vList = new ListBuffer[String]
214 | for (c <- ObjectModel.collections.value ){
215 | for (p <- c.propertyDefs){
216 | for (v <- p.vocabularyList)
217 | vList += v
218 | }
219 | }
220 | val vSet = vList.toSet
221 | for (vs <- vSet ){
222 | QueryObjectModel.currentControlledVocabulary.value += vs
223 | }
224 | if (vSet.size > 0){
225 | QueryObjectModel.currentControlledVocabItem.value = Some(vSet.head)
226 | }
227 |
228 |
229 | }
230 |
231 | @dom
232 | def loadControlledVocablOne = {
233 | QueryObjectModel.queryProperty.bind match {
234 | case None => {
235 | QueryObjectModel.currentControlledVocabulary.value.clear
236 | for (p <- QueryObjectModel.currentQueryCollectionProps.value){
237 | if (p.propertyType == ControlledVocabType){
238 | for (v <- p.vocabularyList){
239 | QueryObjectModel.currentControlledVocabulary.value += v
240 | }
241 | }
242 | }
243 | if (QueryObjectModel.currentControlledVocabulary.value.size > 0){
244 | QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.value.head)
245 | }
246 | }
247 | case _ => {
248 | QueryObjectModel.currentControlledVocabulary.value.clear
249 | for (v <- QueryObjectModel.queryProperty.value.get.vocabularyList){
250 | QueryObjectModel.currentControlledVocabulary.value += v
251 | }
252 | QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.value.head)
253 | }
254 | }
255 | //QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.get.head)
256 | }
257 |
258 |
259 |
260 | }
261 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/RelationsController.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.citerelation._
20 | import edu.holycross.shot.scm._
21 |
22 | import monix.execution.Scheduler.Implicits.global
23 | import monix.eval._
24 |
25 | import scala.scalajs.js.annotation.JSExport
26 |
27 | @JSExportTopLevel("RelationsController")
28 | object RelationsController {
29 |
30 |
31 | val validUrnInField = Var(false)
32 |
33 | def updateUserMessage(msg: String, alert: Int): Unit = {
34 | NGModel.userMessageVisibility.value = "app_visible"
35 | NGModel.userMessage.value = msg
36 | alert match {
37 | case 0 => RelationsModel.userAlert.value = "default"
38 | case 1 => RelationsModel.userAlert.value = "wait"
39 | case 2 => RelationsModel.userAlert.value = "warn"
40 | }
41 | js.timers.clearTimeout(RelationsModel.msgTimer)
42 | RelationsModel.msgTimer = js.timers.setTimeout(6000){ RelationsModel.userMessageVisibility.value = "app_hidden" }
43 | }
44 |
45 | def validateUrn(urnString: String): Unit = {
46 | try{
47 | urnString.take(8) match {
48 | case "urn:cts:" => {
49 | val newUrn:CtsUrn = CtsUrn(urnString)
50 | validUrnInField.value = true
51 | }
52 | case _ => {
53 | urnString.take(10) match {
54 | case "urn:cite2:" => {
55 | val newUrn:Cite2Urn = Cite2Urn(urnString)
56 | validUrnInField.value = true
57 | }
58 | }
59 | }
60 | }
61 | } catch {
62 | case e: Exception => {
63 | validUrnInField.value = false
64 | }
65 | }
66 | }
67 |
68 | def changeUrn(urnString:String):Unit = {
69 | val u:Option[Urn] = {
70 | urnString.take(8) match {
71 | case "urn:cts:" => {
72 | val newUrn:CtsUrn = CtsUrn(urnString)
73 | Some(newUrn)
74 | }
75 | case _ => {
76 | urnString.take(10) match {
77 | case "urn:cite2:" => {
78 | val newUrn:Cite2Urn = Cite2Urn(urnString)
79 | Some(newUrn)
80 | }
81 | case _ => { None }
82 | }
83 | }
84 | }
85 | }
86 | RelationsModel.urn.value = u
87 | findRelations
88 | }
89 |
90 | def changeUrn(urn:Urn):Unit = {
91 | RelationsModel.urn.value = Some(urn)
92 | findRelations
93 | }
94 |
95 | def findRelations(hi:RelationsModel.HistoryItem):Unit = {
96 | RelationsModel.urn.value = Some(hi.search)
97 | RelationsModel.filterVerb.value = hi.filter
98 | RelationsController.findRelations
99 | }
100 |
101 | def findRelations:Unit = {
102 | if ((RelationsModel.urn.value != None) && (RelationsModel.citeRelations.value != None)) {
103 |
104 | val foundRelations:CiteRelationSet = {
105 | RelationsModel.filterVerb.value match {
106 | case Some(fv) => {
107 | val historyItem:RelationsModel.HistoryItem = RelationsModel.HistoryItem(RelationsModel.urn.value.get, Some(fv))
108 | RelationsModel.updateHistory(historyItem)
109 | RelationsModel.citeRelations.value.get.verb(fv) ~~ RelationsModel.urn.value.get
110 | }
111 | case _ => {
112 | val historyItem:RelationsModel.HistoryItem = RelationsModel.HistoryItem(RelationsModel.urn.value.get, None )
113 | RelationsModel.updateHistory(historyItem)
114 | RelationsModel.citeRelations.value.get ~~ RelationsModel.urn.value.get
115 | }
116 | }
117 |
118 | }
119 | //g.console.log(s"found: ${foundRelations.size} out of ${RelationsModel.citeRelations.value.get.size} for ${RelationsModel.urn.value}")
120 | // Let's sort by subject URN
121 | val sortedRelations:Vector[CiteTriple] = foundRelations.relations.toVector.sortBy(_.urn1.toString)
122 | RelationsModel.foundRelations.value.clear
123 | for (r <- sortedRelations) {
124 | RelationsModel.foundRelations.value += r
125 | }
126 |
127 | }
128 | }
129 |
130 | def setFilterVerb(s:String):Unit = {
131 | try {
132 | val u:Option[Cite2Urn] = {
133 | s.take(10) match {
134 | case "urn:cite2:" => Some(Cite2Urn(s))
135 | case _ => None
136 | }
137 | }
138 | RelationsModel.filterVerb.value = u
139 | findRelations
140 | } catch {
141 | case e:Exception => {
142 | RelationsController.updateUserMessage(s"Relations-tab: Unaccountably, something went wrong with the value of the Filter by Relation popup. Could not turn ${s} into a URN: ${e}",2)
143 | }
144 | }
145 | }
146 |
147 | }
148 |
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/RelationsModel.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.citerelation._
20 | import edu.holycross.shot.scm._
21 |
22 | import monix.execution.Scheduler.Implicits.global
23 | import monix.eval._
24 |
25 | import scala.scalajs.js.annotation.JSExport
26 |
27 | @JSExportTopLevel("RelationsModel")
28 | object RelationsModel {
29 | val citeRelations = Var[Option[CiteRelationSet]](None)
30 | val foundRelations = Vars.empty[CiteTriple]
31 |
32 | val allVerbs = Vars.empty[(Cite2Urn,String)]
33 |
34 | val urn = Var[Option[Urn]](None)
35 | val inputBoxUrnStr = Var("")
36 | val filterVerb = Var[Option[Cite2Urn]](None)
37 | val userMessageVisibility = Var("app_hidden")
38 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null
39 | val userMessage = Var("")
40 | val userAlert = Var("default")
41 |
42 | case class HistoryItem(search:Urn, filter:Option[Cite2Urn]) {
43 | override def toString:String = {
44 | filter match {
45 | case Some(f) => s"${search} filtered by “${f.objectComponent}”."
46 | case None => s"${search}."
47 | }
48 | }
49 | }
50 | val searchHistory = Vars.empty[HistoryItem]
51 |
52 | def clearRelations:Unit = {
53 | urn.value = None
54 | filterVerb.value = None
55 | inputBoxUrnStr.value = ""
56 | foundRelations.value.clear
57 | }
58 |
59 | def updateHistory(hi:HistoryItem):Unit = {
60 | val oldHistory:Vector[HistoryItem] = {
61 | searchHistory.value.map(s => {
62 | s
63 | }).toVector
64 |
65 | }
66 | val newHistory:Vector[HistoryItem] = Vector(hi) ++ oldHistory
67 | searchHistory.value.clear
68 | for (i <- newHistory){
69 | searchHistory.value += i
70 | }
71 | }
72 |
73 | def getVerbLabel(u:Cite2Urn):String = {
74 | val label:String = ObjectModel.collRep.value match {
75 | case None => {
76 | val label:String = {
77 | u.objectOption match {
78 | case Some(o) => o
79 | case None => "< nothing specified >"
80 | }
81 | }
82 | label
83 | }
84 | case Some(cr) => {
85 | val label:String = {
86 | (cr ~~ u) match {
87 | case objVec if (objVec.size > 0) => {
88 | objVec(0).label
89 | }
90 | case _ => {
91 | u.objectOption match {
92 | case Some(o) => o
93 | case None => "< nothing specified >"
94 | }
95 | }
96 | }
97 | }
98 | label
99 | }
100 | }
101 | label
102 | }
103 |
104 |
105 | def loadAllVerbs:Unit = {
106 | citeRelations.value match {
107 | case None => allVerbs.value.clear
108 | case Some(crs) => {
109 | val verbs:Vector[Cite2Urn] = {
110 | crs.relations.map( _.relation ).toVector.distinct
111 | }
112 | val verbPairs:Vector[(Cite2Urn, String)] = {
113 | ObjectModel.collRep.value match {
114 | case None => {
115 | verbs.map( v => {
116 | val label:String = {
117 | v.objectOption match {
118 | case Some(o) => o
119 | case None => "< nothing specified >"
120 | }
121 | }
122 | (v, label)
123 | }).toVector
124 | }
125 | case Some(cr) => {
126 | verbs.map( v => {
127 | val label:String = {
128 | (cr ~~ v) match {
129 | case objVec if (objVec.size > 0) => {
130 | objVec(0).label
131 | }
132 | case _ => {
133 | v.objectOption match {
134 | case Some(o) => o
135 | case None => "< nothing specified >"
136 | }
137 | }
138 | }
139 | }
140 | (v, label)
141 | }).toVector
142 | }
143 | }
144 | }
145 | allVerbs.value.clear
146 | for (vp <- verbPairs) {
147 | allVerbs.value += vp
148 | }
149 | }
150 | }
151 | }
152 | }
--------------------------------------------------------------------------------
/src/main/scala/citeappscalajs/RelationsView.scala:
--------------------------------------------------------------------------------
1 | package citeapp
2 |
3 | import com.thoughtworks.binding.{Binding, dom}
4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars}
5 | import scala.scalajs.js
6 | import scala.scalajs.js._
7 | import js.annotation._
8 | import scala.concurrent._
9 | //import ExecutionContext.Implicits.global
10 | import collection.mutable
11 | import collection.mutable._
12 | import scala.scalajs.js.Dynamic.{ global => g }
13 | import org.scalajs.dom._
14 | import org.scalajs.dom.ext._
15 | import org.scalajs.dom.raw._
16 | import edu.holycross.shot.cite._
17 | import edu.holycross.shot.ohco2._
18 | import edu.holycross.shot.citeobj._
19 | import edu.holycross.shot.citerelation._
20 | import edu.holycross.shot.scm._
21 |
22 | import monix.execution.Scheduler.Implicits.global
23 | import monix.eval._
24 |
25 | import scala.scalajs.js.annotation.JSExport
26 |
27 | @JSExportTopLevel("RelationsView")
28 | object RelationsView {
29 |
30 | @dom
31 | def relationsMessageDiv = {
32 |
34 |
35 | {
36 | RelationsModel.userMessage.bind
37 | }
38 |
39 |
40 | }
41 | @dom
42 | def relationsDiv = {
43 |
44 | val urnValidatingKeyUpHandler = { event: KeyboardEvent =>
45 | (event.currentTarget, event.keyCode) match {
46 | case (input: html.Input, KeyCode.Enter) => {
47 | event.preventDefault()
48 | RelationsController.changeUrn(s"${input.value.toString}")
49 | //input.value = ""
50 | }
51 | case(input: html.Input, _) => RelationsController.validateUrn(s"${input.value.toString}")
52 | case _ =>
53 | }
54 | }
55 |
56 |
57 |
58 |
76 |
77 | { relationsMessageDiv.bind }
78 |
79 |
80 | {
81 | RelationsModel.urn.bind match {
82 | case Some(u) => s"${u}"
83 | case None => "[ no URN requested ]"
84 | }
85 | }
86 |
87 | { RelationsModel.filterVerb.bind match {
88 | case Some(u) => {
89 | { s" filtered by ${u}" }
90 | }
91 | case None => ""
92 | }
93 | }
94 | { s" (${RelationsModel.foundRelations.length.bind} relations.)" }
95 |
96 |
97 | { relationsSpace.bind }
98 |
99 |
100 | }
101 |
102 | @dom
103 | def relationsSpace = {
104 |
105 |
106 | { relationsListItems.bind }
107 |
108 |
109 | }
110 |
111 | @dom
112 | def relationsListItems = {
113 | for ( r <- RelationsModel.foundRelations ) yield {
114 |
115 |
116 | { relationsUrnDisplay(r.urn1).bind }
117 | { - { RelationsModel.getVerbLabel(r.relation) }
}
118 | { relationsUrnDisplay(r.urn2).bind }
119 |
120 |
121 | }
122 | }
123 |
124 | @dom
125 | def relationsUrnDisplay(u:Urn) = {
126 | u match {
127 | case CtsUrn(_) => {
128 | DataModelView.textLinkItem(None,u.asInstanceOf[CtsUrn]).bind
129 | }
130 | case Cite2Urn(_) => {
131 | DataModelView.objectLinkItem(None,u.asInstanceOf[Cite2Urn],true).bind
132 | }
133 | case _ =>
134 | }
135 | }
136 |
137 | @dom
138 | def findRelationsButton = {
139 |
177 | }
178 |
179 | @dom
180 | def verbFilterSelect = {
181 |
182 |
196 | }
197 |
198 | /* Previous Searches */
199 | @dom
200 | def previousQueryMenu = {
201 |
212 | }
213 |
214 | @dom
215 | def previousQueriesMenu = {
216 |
217 | { RelationsView.loadPreviousSearches.bind }
218 |
219 | }
220 |
221 | @dom
222 | def loadPreviousSearches = {
223 | for (q <- RelationsModel.searchHistory) yield {
224 |
225 | {
226 | RelationsController.findRelations(q)
227 | }
228 | }>{ q.toString }
229 | }
230 | }
231 |
232 | }
233 |
--------------------------------------------------------------------------------