diff --git a/openlayers/docs/fonts/OpenSans-Bold-webfont.eot b/openlayers/docs/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000..5d20d91 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Bold-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-Bold-webfont.svg b/openlayers/docs/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..3ed7be4 --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-Bold-webfont.woff b/openlayers/docs/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..1205787 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Bold-webfont.woff differ diff --git a/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.eot b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 0000000..1f639a1 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.svg b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 0000000..6a2607b --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.woff b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000..ed760c0 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/openlayers/docs/fonts/OpenSans-Italic-webfont.eot b/openlayers/docs/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 0000000..0c8a0ae Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Italic-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-Italic-webfont.svg b/openlayers/docs/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 0000000..e1075dc --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-Italic-webfont.woff b/openlayers/docs/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..ff652e6 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Italic-webfont.woff differ diff --git a/openlayers/docs/fonts/OpenSans-Light-webfont.eot b/openlayers/docs/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 0000000..1486840 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Light-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-Light-webfont.svg b/openlayers/docs/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..11a472c --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-Light-webfont.woff b/openlayers/docs/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..e786074 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Light-webfont.woff differ diff --git a/openlayers/docs/fonts/OpenSans-LightItalic-webfont.eot b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000..8f44592 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-LightItalic-webfont.svg b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..431d7e3 --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-LightItalic-webfont.woff b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000..43e8b9e Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/openlayers/docs/fonts/OpenSans-Regular-webfont.eot b/openlayers/docs/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000..6bbc3cf Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Regular-webfont.eot differ diff --git a/openlayers/docs/fonts/OpenSans-Regular-webfont.svg b/openlayers/docs/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 0000000..25a3952 --- /dev/null +++ b/openlayers/docs/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openlayers/docs/fonts/OpenSans-Regular-webfont.woff b/openlayers/docs/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..e231183 Binary files /dev/null and b/openlayers/docs/fonts/OpenSans-Regular-webfont.woff differ diff --git a/openlayers/docs/global.html b/openlayers/docs/global.html new file mode 100644 index 0000000..227f335 --- /dev/null +++ b/openlayers/docs/global.html @@ -0,0 +1,333 @@ + + + + + JSDoc: Global + + + + + + + + + +
+

Global

+ +
+
+

+
+ +
+
+
+
+ +

Members

+ +

+ (constant) map + :ol.Map +

+ +
Main map
+ +
Type:
+
    +
  • + ol.Map +
  • +
+ +
+
Source:
+
+ +
+
+ +

+ (constant) pinLayer + :ol.layer.VectorLayer +

+ +
Vector layer for pin vector source
+ +
Type:
+
    +
  • + ol.layer.VectorLayer +
  • +
+ +
+
Source:
+
+ +
+
+ +

+ (constant) pinSource + :ol.source.VectorSource +

+ +
Vector source for pins
+ +
Type:
+
    +
  • + ol.source.VectorSource +
  • +
+ +
+
Source:
+
+ +
+
+ + + +
Overlay element for pin popups
+ +
Type:
+
    +
  • + ol.Overlay +
  • +
+ +
+
Source:
+
+ +
+
+ +

Methods

+ +

+ disposePopover() +

+ +
+ Removes store information popup from screen +
+ +
+
Source:
+
+ +
+
+ +

+ map.oncick() +

+ +
+ Handles user clicks. If user clicks on a pixel that contains a pin, + display popup with store information +
+ +
+
Source:
+
+ +
+
+ +

+ window.passLocation(lon, lat) +

+ +
+ Centers location on user based on location information passed in + from expo-location +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
lon + number + User's longitude
lat + number + User's latitude
+ +
+
Source:
+
+ +
+
+ +

+ window.placePin() +

+ +
+ Begins store creation process if user clicks on "New" button +
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/index.html b/openlayers/docs/index.html new file mode 100644 index 0000000..52f36ce --- /dev/null +++ b/openlayers/docs/index.html @@ -0,0 +1,85 @@ + + + + + JSDoc: Home + + + + + + + + + +
+

Home

+ +

beerbuddy 1.0.0

+ +
+
+

OpenLayers + Vite

+

+ First stage of the app is the creation of an OpenLayers app that is + inlined into a single file by Vite. This is then an asset that can + be interacted with from within React Native. +

+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/main.js.html b/openlayers/docs/main.js.html new file mode 100644 index 0000000..caccac1 --- /dev/null +++ b/openlayers/docs/main.js.html @@ -0,0 +1,277 @@ + + + + + JSDoc: Source: main.js + + + + + + + + + +
+

Source: main.js

+ +
+
+
import "./style.css";
+
+import { Map, View, Overlay } from "ol";
+
+import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
+import { TileJSON, Vector as VectorSource } from "ol/source";
+import { useGeographic } from "ol/proj.js";
+import { defaults as defaultControls } from "ol/control.js";
+
+import { Popover } from "bootstrap";
+
+import searchBar from "./modules/searchBar.js";
+import fetchPins from "./modules/fetchPins.js";
+import ButtonControl from "./modules/newButton.js";
+import changeResolutionHandler from "./modules/changeResolutionHandler.js";
+import pointerMoveHandler from "./modules/pointerMoveHandler.js";
+import searchInputHander from "./modules/searchInputHandler.js";
+
+///
+
+const search = searchBar;
+
+let pinning = false;
+
+let popover;
+
+/** Vector source for pins
+ * @constant {ol.source.VectorSource} */
+const pinSource = new VectorSource();
+/** Vector layer for pin vector source
+ * @constant {ol.layer.VectorLayer} */
+const pinLayer = new VectorLayer({
+  source: pinSource,
+});
+
+useGeographic();
+
+fetchPins(pinSource);
+
+/** Main map
+ * @constant {ol.Map} */
+const map = new Map({
+  controls: defaultControls().extend([new ButtonControl()]),
+  target: document.getElementById("map"),
+  layers: [
+    new TileLayer({
+      source: new TileJSON({
+        url: `https://api.maptiler.com/maps/hybrid/tiles.json?key=${
+          import.meta.env.VITE_MAPTILER_KEY
+        }`,
+        tileSize: 512,
+        crossOrigin: "anonymous",
+      }),
+    }),
+  ],
+  view: new View({
+    center: [0, 0],
+    zoom: 2,
+    maxZoom: 20,
+  }),
+});
+
+/** Overlay element for pin popups
+ * @constant {ol.Overlay} */
+const popup = new Overlay({
+  element: document.getElementById("popup"),
+  positioning: "bottom-center",
+  stopEvent: false,
+});
+
+map.addOverlay(popup);
+
+map.addControl(search);
+
+const searchInput = search.getInputField();
+searchInput.onkeydown = (event) => {
+  searchInputHander(event, map);
+};
+
+/** Removes store information popup from screen
+ */
+const disposePopover = () => {
+  if (popover) {
+    popover.dispose();
+    popover = undefined;
+  }
+};
+
+/** Handles user clicks. If user clicks on a pixel that contains a pin, display popup with store information
+ * @param {Event} event - User click event
+ * @param {bootstrap.Popover} popover - Popover object from Bootstrap/Popper
+ * @param {ol.Overlay} popup - Overlay element for pin popups
+ * @param {ol.Map} map - OpenLayers map
+ */
+
+map.on("click", (event) => {
+  disposePopover();
+
+  const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => feature);
+  if (!feature) return;
+
+  popup.setPosition(event.coordinate);
+
+  const element = document.querySelector("#popup");
+
+  popover = new Popover(element, {
+    placement: "top",
+    html: true,
+    title: feature.get("store"),
+    content: function () {
+      const container = document.createElement("div");
+
+      const cheapestItem = document.createElement("div");
+      cheapestItem.textContent = `Cheapest Item: ${feature.get(
+        "cheapestItem"
+      )}`;
+      container.appendChild(cheapestItem);
+
+      const cheapestPerFloz = document.createElement("div");
+      cheapestPerFloz.textContent = `$ / oz.: ${feature.get("pricePerOz")}`;
+      container.appendChild(cheapestPerFloz);
+
+      const link = document.createElement("a");
+      link.href = "#";
+      link.onclick = function (event) {
+        event.preventDefault();
+        window.ReactNativeWebView?.postMessage(
+          `open@${feature.getGeometry().getCoordinates()}`
+        );
+      };
+      link.textContent = "More...";
+      container.appendChild(link);
+
+      return container;
+    },
+  });
+
+  popover.show();
+});
+
+map.on("pointermove", (event) => {
+  pointerMoveHandler(event, map);
+});
+
+map.on("movestart", disposePopover);
+
+map.getView().on("change:resolution", () => {
+  changeResolutionHandler(pinning, map, pinLayer);
+});
+
+/** Centers location on user based on location information passed in from expo-location
+ * @param {number} lon - User's longitude
+ * @param {number} lat - User's latitude
+ */
+window.passLocation = (lon, lat) => {
+  const view = new View({
+    center: [lon, lat],
+    zoom: 18,
+    maxZoom: 20,
+  });
+
+  map.setView(view);
+  map.getLayers().extend([pinLayer]);
+
+  // sets NEW listener to listen for zoom changes
+  view.on("change:resolution", () => {
+    view.getZoom() < 5
+      ? map.getLayers().removeAt(1)
+      : (() => {
+          if (map.getLayers().getLength() === 1) {
+            if (!pinning) map.getLayers().extend([pinLayer]);
+          }
+        })();
+  });
+};
+
+/** Begins store creation process if user clicks on "New" button
+ */
+window.placePin = () => {
+  button.removeEventListener("click", newButtonHandler, false);
+  pinning = true;
+  map.getLayers().removeAt(1);
+  // adds pin in center of view
+  document.getElementById("centerPin").style.display = "block";
+  // changes new button to OK button
+  button.textContent = "OK";
+  // OK button has event listener that on click
+  function OKButtonHandler() {
+    // removes listener on button in case someone wants to mash it
+    button.removeEventListener("click", OKButtonHandler, false);
+    // removes pin in center of view
+    document.getElementById("centerPin").style.display = "none";
+    // emits to RN
+    window.ReactNativeWebView?.postMessage(
+      `create@${map.getView().getCenter()}`
+    );
+  }
+  button.addEventListener("click", OKButtonHandler, false);
+};
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-changeResolutionHandler.html b/openlayers/docs/module-changeResolutionHandler.html new file mode 100644 index 0000000..936649f --- /dev/null +++ b/openlayers/docs/module-changeResolutionHandler.html @@ -0,0 +1,218 @@ + + + + + JSDoc: Module: changeResolutionHandler + + + + + + + + + +
+

Module: changeResolutionHandler

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Members

+ +

+ (inner, constant) CUTOFF + :number +

+ +
Maximum zoom level to show pins
+ +
Type:
+
    +
  • + number +
  • +
+ +
+
Default Value:
+
+
    +
  • 5
  • +
+
+ +
Source:
+
+ +
+
+ +

Methods

+ +

+ (inner) changeResolutionHandler(pinning, map, pinLayer) +

+ +
+ Adds or removes pin vector layer depending on zoom level +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pinning + boolean + + Boolean to toggle between new pin creation and viewing + existing pins. If this is true, existing pins are not visible. +
map + ol.Map + OpenLayers map to center
pinLayer + ol.layer.Vector + + OpenLayers vector layer for pins +
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-fetchPins.html b/openlayers/docs/module-fetchPins.html new file mode 100644 index 0000000..a33972a --- /dev/null +++ b/openlayers/docs/module-fetchPins.html @@ -0,0 +1,146 @@ + + + + + JSDoc: Module: fetchPins + + + + + + + + + +
+

Module: fetchPins

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Methods

+ +

+ (async, inner) fetchPins(pinSource) +

+ +
+ Fetches pin records from database and adds pin features to pin + vector source layer +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pinSource + ol.source.Vector + + The relevant vector source layer to add pin features to +
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-makePin.html b/openlayers/docs/module-makePin.html new file mode 100644 index 0000000..f8b4739 --- /dev/null +++ b/openlayers/docs/module-makePin.html @@ -0,0 +1,194 @@ + + + + + JSDoc: Module: makePin + + + + + + + + + +
+

Module: makePin

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Methods

+ +

+ (inner) makePin(lon, lat, storeName, cheapest, flozPrice) → {ol.Feature} +

+ +
Makes pin feature from arguments
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
lon + number + Longitude
lat + number + Latitude
storeName + string + Name of store
cheapest + string + Cheapest item in store
flozPrice + number + + Price per fluid ounce of cheapest item in store +
+ +
+
Source:
+
+ +
+
+ +
Returns:
+ +
- Created pin feature
+ +
+
Type
+
+ ol.Feature +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-newButton-ButtonControl.html b/openlayers/docs/module-newButton-ButtonControl.html new file mode 100644 index 0000000..0e70a5e --- /dev/null +++ b/openlayers/docs/module-newButton-ButtonControl.html @@ -0,0 +1,120 @@ + + + + + JSDoc: Class: ButtonControl + + + + + + + + + +
+

Class: ButtonControl

+ +
+
+

+ + newButton~ButtonControl() +

+ +
+ Extends OpenLayers default Control class to provide button for pin + creation process +
+
+ +
+
+

Constructor

+ +

+ new ButtonControl() +

+ +
+
Source:
+
+ +
+
+
+ +

Extends

+ +
    +
  • ol.control.Control
  • +
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-newButton.html b/openlayers/docs/module-newButton.html new file mode 100644 index 0000000..1933fcc --- /dev/null +++ b/openlayers/docs/module-newButton.html @@ -0,0 +1,101 @@ + + + + + JSDoc: Module: newButton + + + + + + + + + +
+

Module: newButton

+ +
+
+ + +
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-pointerMoveHandler.html b/openlayers/docs/module-pointerMoveHandler.html new file mode 100644 index 0000000..fbb8f88 --- /dev/null +++ b/openlayers/docs/module-pointerMoveHandler.html @@ -0,0 +1,161 @@ + + + + + JSDoc: Module: pointerMoveHandler + + + + + + + + + +
+

Module: pointerMoveHandler

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Methods

+ +

+ (inner) pointerMoveHandler(event, map) +

+ +
+ Changes cursor depending on if user is hovering over a pin +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + Event + Pointer move event
map + ol.Map + OpenLayers map
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-searchBar.html b/openlayers/docs/module-searchBar.html new file mode 100644 index 0000000..a648eb4 --- /dev/null +++ b/openlayers/docs/module-searchBar.html @@ -0,0 +1,123 @@ + + + + + JSDoc: Module: searchBar + + + + + + + + + +
+

Module: searchBar

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Members

+ +

+ (inner, constant) searchBar + :ol-ext.control.Search +

+ +
Search bar component
+ +
Type:
+
    +
  • + ol-ext.control.Search +
  • +
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-searchInputHander.html b/openlayers/docs/module-searchInputHander.html new file mode 100644 index 0000000..c24ece8 --- /dev/null +++ b/openlayers/docs/module-searchInputHander.html @@ -0,0 +1,163 @@ + + + + + JSDoc: Module: searchInputHander + + + + + + + + + +
+

Module: searchInputHander

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Methods

+ +

+ (inner) searchInputHander(event, map) +

+ +
+ Handles user pressing Enter key in search input field by sending + current coordinates and contents of field to React Native for + processing +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
event + Event + + Keydown event in search input field +
map + ol.Map + OpenLayers map
+ +
+
Source:
+
+ +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/module-toLatLon.html b/openlayers/docs/module-toLatLon.html new file mode 100644 index 0000000..2dcdf80 --- /dev/null +++ b/openlayers/docs/module-toLatLon.html @@ -0,0 +1,187 @@ + + + + + JSDoc: Module: toLatLon + + + + + + + + + +
+

Module: toLatLon

+ +
+
+ +
+
+
+
Source:
+
+ +
+
+
+ +

Methods

+ +

+ (inner) toLatLon(easting, northing, zone, zoneLetter) → {Array} +

+ +
+ Converts UTM coordinates in database store records to + latitude/longitude for use with the map +
+ +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
easting + number + UTM easting of store
northing + number + UTM northing of store
zone + string + UTM zone of store
zoneLetter + string + UTM zone letter of store
+ +
+
Source:
+
+ +
+
+ +
Returns:
+ +
+ - Array of coordinates as [latitude, longitude] +
+ +
+
Type
+
+ Array +
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_changeResolutionHandler.js.html b/openlayers/docs/modules_changeResolutionHandler.js.html new file mode 100644 index 0000000..d7d621d --- /dev/null +++ b/openlayers/docs/modules_changeResolutionHandler.js.html @@ -0,0 +1,104 @@ + + + + + JSDoc: Source: modules/changeResolutionHandler.js + + + + + + + + + +
+

Source: modules/changeResolutionHandler.js

+ +
+
+
/**
+ * @module changeResolutionHandler
+ */
+
+/** Maximum zoom level to show pins
+ * @constant {number}
+ * @default 5
+ */
+const CUTOFF = 5;
+
+/** Adds or removes pin vector layer depending on zoom level
+ * @param {boolean} pinning - Boolean to toggle between new pin creation and viewing existing pins. If this is true, existing pins are not visible.
+ * @param {ol.Map} map - OpenLayers map to center
+ * @param {ol.layer.Vector} pinLayer - OpenLayers vector layer for pins
+ */
+const changeResolutionHandler = (pinning, map, pinLayer) => {
+  map.getView().getZoom() < CUTOFF
+    ? map.getLayers().removeAt(1)
+    : (() => {
+        if (map.getLayers().getLength() === 1) {
+          if (!pinning) map.getLayers().extend([pinLayer]);
+        }
+      })();
+};
+
+export default changeResolutionHandler;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_fetchPins.js.html b/openlayers/docs/modules_fetchPins.js.html new file mode 100644 index 0000000..4d1e31e --- /dev/null +++ b/openlayers/docs/modules_fetchPins.js.html @@ -0,0 +1,116 @@ + + + + + JSDoc: Source: modules/fetchPins.js + + + + + + + + + +
+

Source: modules/fetchPins.js

+ +
+
+
import makePin from "./makePin.js";
+import toLatLon from "./toLatLon.js";
+
+/**
+ * @module fetchPins
+ */
+
+/** Fetches pin records from database and adds pin features to pin vector source layer
+ * @async
+ * @param {ol.source.Vector} pinSource - The relevant vector source layer to add pin features to
+ */
+const fetchPins = async (pinSource) => {
+  const res = await fetch(import.meta.env.VITE_BACKEND_URL);
+  const pinRecords = await res.json();
+
+  pinRecords.forEach((pinRecord) => {
+    const [latitude, longitude] = toLatLon(
+      pinRecord.easting,
+      pinRecord.northing,
+      pinRecord.zone,
+      pinRecord.zoneLetter
+    );
+
+    const pin = makePin(
+      longitude.toFixed(5),
+      latitude.toFixed(5),
+      pinRecord.name,
+      pinRecord.cheapestItem,
+      pinRecord.cheapestFloz
+    );
+
+    pinSource.addFeature(pin);
+  });
+};
+
+export default fetchPins;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_makePin.js.html b/openlayers/docs/modules_makePin.js.html new file mode 100644 index 0000000..855cd83 --- /dev/null +++ b/openlayers/docs/modules_makePin.js.html @@ -0,0 +1,126 @@ + + + + + JSDoc: Source: modules/makePin.js + + + + + + + + + +
+

Source: modules/makePin.js

+ +
+
+
// creates pins
+import { Feature } from "ol";
+import { Icon, Style } from "ol/style";
+import Point from "ol/geom/Point.js";
+
+/**
+ * @module makePin
+ */
+
+/** Makes pin feature from arguments
+ * @param {number} lon - Longitude
+ * @param {number} lat - Latitude
+ * @param {string} storeName - Name of store
+ * @param {string} cheapest - Cheapest item in store
+ * @param {number} flozPrice - Price per fluid ounce of cheapest item in store
+ * @returns {ol.Feature} - Created pin feature
+ */
+const makePin = (lon, lat, storeName, cheapest, flozPrice) => {
+  // define pin graphics (since this is all inline)
+  const pinSVG = `<svg width="32px" height="32px" viewBox="-0.12 -0.12 12.24 12.24" enable-background="new 0 0 12 12" id="Слой_1" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" stroke="#000000" stroke-width="0.12000000000000002"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M6,0C3.2385864,0,1,2.2385864,1,5s2.5,5,5,7c2.5-2,5-4.2385864,5-7S8.7614136,0,6,0z M6,7 C4.8954468,7,4,6.1045532,4,5s0.8954468-2,2-2s2,0.8954468,2,2S7.1045532,7,6,7z" fill="#ed333b"></path></g></svg>`;
+  const pinSVGBlob = new Blob([pinSVG], {
+    type: "image/svg+xml",
+  });
+  const pinImageURL = URL.createObjectURL(pinSVGBlob);
+
+  // define style for all pins
+  const pinStyle = new Style({
+    image: new Icon({
+      src: pinImageURL,
+      anchor: [0.5, 1],
+    }),
+  });
+
+  // create pin as feature
+  const pin = new Feature({
+    geometry: new Point([lon, lat]),
+    store: storeName,
+    cheapestItem: cheapest,
+    pricePerOz: flozPrice,
+  });
+
+  // set style for pin
+  pin.setStyle(pinStyle);
+
+  return pin;
+};
+
+export default makePin;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_newButton.js.html b/openlayers/docs/modules_newButton.js.html new file mode 100644 index 0000000..280c15d --- /dev/null +++ b/openlayers/docs/modules_newButton.js.html @@ -0,0 +1,113 @@ + + + + + JSDoc: Source: modules/newButton.js + + + + + + + + + +
+

Source: modules/newButton.js

+ +
+
+
import { Control } from "ol/control.js";
+
+/**
+ * @module newButton
+ */
+
+/** Extends OpenLayers default Control class to provide button for pin creation process
+ * @extends ol.control.Control
+ */
+class ButtonControl extends Control {
+  constructor(opt_options) {
+    const options = opt_options || {};
+
+    const button = document.createElement("button");
+    button.textContent = "New";
+    button.addEventListener("click", newButtonHandler, false);
+
+    function newButtonHandler() {
+      window.ReactNativeWebView?.postMessage("new pin start");
+    }
+
+    const element = document.createElement("div");
+    element.className = "new-button ol-unselectable ol-control";
+    element.appendChild(button);
+
+    super({
+      element: element,
+      target: options.target,
+    });
+  }
+}
+
+export default ButtonControl;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_pointerMoveHandler.js.html b/openlayers/docs/modules_pointerMoveHandler.js.html new file mode 100644 index 0000000..81c5215 --- /dev/null +++ b/openlayers/docs/modules_pointerMoveHandler.js.html @@ -0,0 +1,95 @@ + + + + + JSDoc: Source: modules/pointerMoveHandler.js + + + + + + + + + +
+

Source: modules/pointerMoveHandler.js

+ +
+
+
/**
+ * @module pointerMoveHandler
+ */
+
+/** Changes cursor depending on if user is hovering over a pin
+ * @param {Event} event - Pointer move event
+ * @param {ol.Map} map - OpenLayers map
+ */
+
+const pointerMoveHandler = (event, map) => {
+  const currentPixel = map.getEventPixel(event.originalEvent);
+  if (map.hasFeatureAtPixel(currentPixel)) {
+    map.getTarget().style.cursor = "pointer";
+  } else map.getTarget().style.cursor = "";
+};
+
+export default pointerMoveHandler;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_searchBar.js.html b/openlayers/docs/modules_searchBar.js.html new file mode 100644 index 0000000..ada4ee4 --- /dev/null +++ b/openlayers/docs/modules_searchBar.js.html @@ -0,0 +1,98 @@ + + + + + JSDoc: Source: modules/searchBar.js + + + + + + + + + +
+

Source: modules/searchBar.js

+ +
+
+
import Search from "ol-ext/control/Search.js";
+
+/**
+ * @module searchBar
+ */
+
+/** Search bar component
+ * @constant {ol-ext.control.Search}
+ */
+const searchBar = new Search({
+  // disable autocompletion
+  typing: -1,
+  placeholder: "Search for products...",
+  collapsed: "false",
+  className: "searchBar",
+});
+
+export default searchBar;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_searchInputHandler.js.html b/openlayers/docs/modules_searchInputHandler.js.html new file mode 100644 index 0000000..025410c --- /dev/null +++ b/openlayers/docs/modules_searchInputHandler.js.html @@ -0,0 +1,95 @@ + + + + + JSDoc: Source: modules/searchInputHandler.js + + + + + + + + + +
+

Source: modules/searchInputHandler.js

+ +
+
+
/**
+ * @module searchInputHander
+ */
+
+/** Handles user pressing Enter key in search input field by sending current coordinates and contents of field to React Native for processing
+ * @param {Event} event - Keydown event in search input field
+ * @param {ol.Map} map - OpenLayers map
+ */
+const searchInputHander = (event, map) => {
+  if (event.key === "Enter") {
+    const coords = map.getView().getCenter();
+    const query = event.target.value;
+    window.ReactNativeWebView?.postMessage(`search@${coords}:${query}`);
+  }
+};
+
+export default searchInputHander;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/modules_toLatLon.js.html b/openlayers/docs/modules_toLatLon.js.html new file mode 100644 index 0000000..6c12fbe --- /dev/null +++ b/openlayers/docs/modules_toLatLon.js.html @@ -0,0 +1,106 @@ + + + + + JSDoc: Source: modules/toLatLon.js + + + + + + + + + +
+

Source: modules/toLatLon.js

+ +
+
+
import utmObj from "utm-latlng";
+
+const utm = new utmObj();
+
+/**
+ * @module toLatLon
+ */
+
+/** Converts UTM coordinates in database store records to latitude/longitude for use with the map
+ * @param {number} easting - UTM easting of store
+ * @param {number} northing - UTM northing of store
+ * @param {string} zone - UTM zone of store
+ * @param {string} zoneLetter - UTM zone letter of store
+ * @returns {Array} - Array of coordinates as [latitude, longitude]
+ */
+const toLatLon = (easting, northing, zone, zoneLetter) => {
+  const convertedCoordinates = utm.convertUtmToLatLng(
+    easting,
+    northing,
+    zone,
+    zoneLetter
+  );
+  return [convertedCoordinates.lat, convertedCoordinates.lng];
+};
+
+export default toLatLon;
+
+
+
+
+ + + +
+ + + + + + + diff --git a/openlayers/docs/scripts/linenumber.js b/openlayers/docs/scripts/linenumber.js new file mode 100644 index 0000000..4354785 --- /dev/null +++ b/openlayers/docs/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(() => { + const source = document.getElementsByClassName('prettyprint source linenums'); + let i = 0; + let lineNumber = 0; + let lineId; + let lines; + let totalLines; + let anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = `line${lineNumber}`; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/openlayers/docs/scripts/prettify/Apache-License-2.0.txt b/openlayers/docs/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/openlayers/docs/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/openlayers/docs/scripts/prettify/lang-css.js b/openlayers/docs/scripts/prettify/lang-css.js new file mode 100644 index 0000000..041e1f5 --- /dev/null +++ b/openlayers/docs/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/openlayers/docs/scripts/prettify/prettify.js b/openlayers/docs/scripts/prettify/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/openlayers/docs/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.source +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.source code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/openlayers/docs/styles/prettify-jsdoc.css b/openlayers/docs/styles/prettify-jsdoc.css new file mode 100644 index 0000000..5a2526e --- /dev/null +++ b/openlayers/docs/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/openlayers/docs/styles/prettify-tomorrow.css b/openlayers/docs/styles/prettify-tomorrow.css new file mode 100644 index 0000000..b6f92a7 --- /dev/null +++ b/openlayers/docs/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/openlayers/main.js b/openlayers/main.js index eeeeef0..57eb897 100644 --- a/openlayers/main.js +++ b/openlayers/main.js @@ -5,98 +5,40 @@ import { Map, View, Overlay } from "ol"; import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer"; import { TileJSON, Vector as VectorSource } from "ol/source"; import { useGeographic } from "ol/proj.js"; -import { Control, defaults as defaultControls } from "ol/control.js"; - -import Search from "ol-ext/control/Search.js"; +import { defaults as defaultControls } from "ol/control.js"; import { Popover } from "bootstrap"; -import utmObj from "utm-latlng"; -import makePin from "./modules/makePin.js"; +import searchBar from "./modules/searchBar.js"; +import fetchPins from "./modules/fetchPins.js"; +import ButtonControl from "./modules/newButton.js"; +import changeResolutionHandler from "./modules/changeResolutionHandler.js"; +import pointerMoveHandler from "./modules/pointerMoveHandler.js"; +import searchInputHander from "./modules/searchInputHandler.js"; -// utm converter -const utm = new utmObj(); +/// -// specify to use real lon/lat coordinates -useGeographic(); +const search = searchBar; -// state bool for locking pin overlay while adding pin let pinning = false; -// create new VectorSource for pins + +let popover; + +/** Vector source for pins + * @constant {ol.source.VectorSource} */ const pinSource = new VectorSource(); -// create vector layer for rendering pins and popups +/** Vector layer for pin vector source + * @constant {ol.layer.VectorLayer} */ const pinLayer = new VectorLayer({ source: pinSource, }); -// pull data from flask -fetch(import.meta.env.VITE_BACKEND_URL) - .then((res) => res.json()) - .then((dbPins) => { - dbPins.forEach((dbPin) => { - // convert to lat/lon - const [lat, lon] = [ - utm.convertUtmToLatLng( - dbPin.easting, - dbPin.northing, - dbPin.zone, - dbPin.zoneLetter - ).lat, - utm.convertUtmToLatLng( - dbPin.easting, - dbPin.northing, - dbPin.zone, - dbPin.zoneLetter - ).lng, - ]; - // make pin feature - const pin = makePin( - lon.toFixed(5), - lat.toFixed(5), - dbPin.name, - dbPin.cheapestItem, - dbPin.cheapestFloz - ); - // add - pinSource.addFeature(pin); - }); - }); +useGeographic(); -// create button -// made in global scope so it can be modified -const button = document.createElement("button"); -button.textContent = "New"; -button.addEventListener("click", newButtonHandler, false); -function newButtonHandler() { - window.ReactNativeWebView?.postMessage("new pin start"); -} +fetchPins(pinSource); -// add button to control -class ButtonControl extends Control { - constructor(opt_options) { - const options = opt_options || {}; - - const element = document.createElement("div"); - element.className = "new-button ol-unselectable ol-control"; - element.appendChild(button); - - super({ - element: element, - target: options.target, - }); - } -} - -// create search bar -const search = new Search({ - // disable autocompletion - typing: -1, - placeholder: "Search for products...", - collapsed: "false", - className: "searchBar", -}); - -// create OSM map +/** Main map + * @constant {ol.Map} */ const map = new Map({ controls: defaultControls().extend([new ButtonControl()]), target: document.getElementById("map"), @@ -111,7 +53,6 @@ const map = new Map({ }), }), ], - // initially view at Null Point, 2x zoom view: new View({ center: [0, 0], zoom: 2, @@ -119,33 +60,25 @@ const map = new Map({ }), }); -// popup element to display when pin clicked -const element = document.getElementById("popup"); +/** Overlay element for pin popups + * @constant {ol.Overlay} */ const popup = new Overlay({ - element: element, + element: document.getElementById("popup"), positioning: "bottom-center", stopEvent: false, }); -// add popup overlay to map map.addOverlay(popup); -// add search map.addControl(search); -// get search input field const searchInput = search.getInputField(); searchInput.onkeydown = (event) => { - if (event.key === "Enter") { - // emits to RN - window.ReactNativeWebView?.postMessage( - `search@${map.getView().getCenter()}:${event.target.value}` - ); - } + searchInputHander(event, map); }; -// set state for popup visibility -let popover; +/** Removes store information popup from screen + */ const disposePopover = () => { if (popover) { popover.dispose(); @@ -153,29 +86,35 @@ const disposePopover = () => { } }; -// on click events +/** Handles user clicks. If user clicks on a pixel that contains a pin, display popup with store information */ + map.on("click", (event) => { - // get features at pixel - const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => feature); - // preemptively remove any previous popup overlays disposePopover(); - // if no pins at location, do nothing + + const feature = map.forEachFeatureAtPixel(event.pixel, (feature) => feature); if (!feature) return; - // set popup window position + popup.setPosition(event.coordinate); - // create popover at position + + const element = document.querySelector("#popup"); + popover = new Popover(element, { placement: "top", html: true, title: feature.get("store"), content: function () { - const holder = document.createElement("div"); - const one = document.createElement("div"); - one.textContent = `Cheapest Item: ${feature.get("cheapestItem")}`; - holder.appendChild(one); - const two = document.createElement("div"); - two.textContent = `$ / oz.: ${feature.get("pricePerOz")}`; - holder.appendChild(two); + const container = document.createElement("div"); + + const cheapestItem = document.createElement("div"); + cheapestItem.textContent = `Cheapest Item: ${feature.get( + "cheapestItem" + )}`; + container.appendChild(cheapestItem); + + const cheapestPerFloz = document.createElement("div"); + cheapestPerFloz.textContent = `$ / oz.: ${feature.get("pricePerOz")}`; + container.appendChild(cheapestPerFloz); + const link = document.createElement("a"); link.href = "#"; link.onclick = function (event) { @@ -185,40 +124,29 @@ map.on("click", (event) => { ); }; link.textContent = "More..."; - holder.appendChild(link); - return holder; + container.appendChild(link); + + return container; }, }); - // show popover + popover.show(); }); -// set pointer to cursor when hovering over pin map.on("pointermove", (event) => { - // if there is a pin at the pixel the user is hovering over - if (map.hasFeatureAtPixel(map.getEventPixel(event.originalEvent))) { - // set the cursor to pointer cursor - map.getTarget().style.cursor = "pointer"; - } - // otherwise make cursor normal again - else map.getTarget().style.cursor = ""; + pointerMoveHandler(event, map); }); -// close popup when map moved map.on("movestart", disposePopover); -// sets listener to listen for zoom changes map.getView().on("change:resolution", () => { - map.getView().getZoom() < 5 - ? map.getLayers().removeAt(1) - : (() => { - if (map.getLayers().getLength() === 1) { - if (!pinning) map.getLayers().extend([pinLayer]); - } - })(); + changeResolutionHandler(pinning, map, pinLayer); }); -// centers location on user based on location information passed in from expo-location +/** Centers location on user based on location information passed in from expo-location + * @param {number} lon - User's longitude + * @param {number} lat - User's latitude + */ window.passLocation = (lon, lat) => { const view = new View({ center: [lon, lat], @@ -241,24 +169,22 @@ window.passLocation = (lon, lat) => { }); }; -// place pin interaction +/** Begins store creation process if user clicks on "New" button */ window.placePin = () => { - // removes listener on button in case someone wants to mash it - button.removeEventListener("click", newButtonHandler, false); - // removes pin layer + const oldButton = document.querySelector(".new-button > button"); + const button = oldButton.cloneNode(true); + oldButton.parentNode.replaceChild(button, oldButton); pinning = true; + map.getLayers().removeAt(1); - // adds pin in center of view document.getElementById("centerPin").style.display = "block"; - // changes new button to OK button + button.textContent = "OK"; - // OK button has event listener that on click + function OKButtonHandler() { - // removes listener on button in case someone wants to mash it button.removeEventListener("click", OKButtonHandler, false); - // removes pin in center of view document.getElementById("centerPin").style.display = "none"; - // emits to RN + window.ReactNativeWebView?.postMessage( `create@${map.getView().getCenter()}` ); diff --git a/openlayers/modules/changeResolutionHandler.js b/openlayers/modules/changeResolutionHandler.js new file mode 100644 index 0000000..3c1695a --- /dev/null +++ b/openlayers/modules/changeResolutionHandler.js @@ -0,0 +1,26 @@ +/** + * @module changeResolutionHandler + */ + +/** Maximum zoom level to show pins + * @constant {number} + * @default 5 + */ +const CUTOFF = 5; + +/** Adds or removes pin vector layer depending on zoom level + * @param {boolean} pinning - Boolean to toggle between new pin creation and viewing existing pins. If this is true, existing pins are not visible. + * @param {ol.Map} map - OpenLayers map to center + * @param {ol.layer.Vector} pinLayer - OpenLayers vector layer for pins + */ +const changeResolutionHandler = (pinning, map, pinLayer) => { + map.getView().getZoom() < CUTOFF + ? map.getLayers().removeAt(1) + : (() => { + if (map.getLayers().getLength() === 1) { + if (!pinning) map.getLayers().extend([pinLayer]); + } + })(); +}; + +export default changeResolutionHandler; diff --git a/openlayers/modules/fetchPins.js b/openlayers/modules/fetchPins.js new file mode 100644 index 0000000..04f6822 --- /dev/null +++ b/openlayers/modules/fetchPins.js @@ -0,0 +1,36 @@ +import makePin from "./makePin.js"; +import toLatLon from "./toLatLon.js"; + +/** + * @module fetchPins + */ + +/** Fetches pin records from database and adds pin features to pin vector source layer + * @async + * @param {ol.source.Vector} pinSource - The relevant vector source layer to add pin features to + */ +const fetchPins = async (pinSource) => { + const res = await fetch(import.meta.env.VITE_BACKEND_URL); + const pinRecords = await res.json(); + + pinRecords.forEach((pinRecord) => { + const [latitude, longitude] = toLatLon( + pinRecord.easting, + pinRecord.northing, + pinRecord.zone, + pinRecord.zoneLetter + ); + + const pin = makePin( + longitude.toFixed(5), + latitude.toFixed(5), + pinRecord.name, + pinRecord.cheapestItem, + pinRecord.cheapestFloz + ); + + pinSource.addFeature(pin); + }); +}; + +export default fetchPins; diff --git a/openlayers/modules/makePin.js b/openlayers/modules/makePin.js index a9af663..b83bcd9 100644 --- a/openlayers/modules/makePin.js +++ b/openlayers/modules/makePin.js @@ -3,6 +3,18 @@ import { Feature } from "ol"; import { Icon, Style } from "ol/style"; import Point from "ol/geom/Point.js"; +/** + * @module makePin + */ + +/** Makes pin feature from arguments + * @param {number} lon - Longitude + * @param {number} lat - Latitude + * @param {string} storeName - Name of store + * @param {string} cheapest - Cheapest item in store + * @param {number} flozPrice - Price per fluid ounce of cheapest item in store + * @returns {ol.Feature} - Created pin feature + */ const makePin = (lon, lat, storeName, cheapest, flozPrice) => { // define pin graphics (since this is all inline) const pinSVG = ``; diff --git a/openlayers/modules/newButton.js b/openlayers/modules/newButton.js new file mode 100644 index 0000000..afa5086 --- /dev/null +++ b/openlayers/modules/newButton.js @@ -0,0 +1,33 @@ +import { Control } from "ol/control.js"; + +/** + * @module newButton + */ + +/** Extends OpenLayers default Control class to provide button for pin creation process + * @extends ol.control.Control + */ +class ButtonControl extends Control { + constructor(opt_options) { + const options = opt_options || {}; + + const button = document.createElement("button"); + button.textContent = "New"; + button.addEventListener("click", newButtonHandler, false); + + function newButtonHandler() { + window.ReactNativeWebView?.postMessage("new pin start"); + } + + const element = document.createElement("div"); + element.className = "new-button ol-unselectable ol-control"; + element.appendChild(button); + + super({ + element: element, + target: options.target, + }); + } +} + +export default ButtonControl; diff --git a/openlayers/modules/pointerMoveHandler.js b/openlayers/modules/pointerMoveHandler.js new file mode 100644 index 0000000..7490ce3 --- /dev/null +++ b/openlayers/modules/pointerMoveHandler.js @@ -0,0 +1,17 @@ +/** + * @module pointerMoveHandler + */ + +/** Changes cursor depending on if user is hovering over a pin + * @param {Event} event - Pointer move event + * @param {ol.Map} map - OpenLayers map + */ + +const pointerMoveHandler = (event, map) => { + const currentPixel = map.getEventPixel(event.originalEvent); + if (map.hasFeatureAtPixel(currentPixel)) { + map.getTarget().style.cursor = "pointer"; + } else map.getTarget().style.cursor = ""; +}; + +export default pointerMoveHandler; diff --git a/openlayers/modules/searchBar.js b/openlayers/modules/searchBar.js new file mode 100644 index 0000000..dcb5dc4 --- /dev/null +++ b/openlayers/modules/searchBar.js @@ -0,0 +1,18 @@ +import Search from "ol-ext/control/Search.js"; + +/** + * @module searchBar + */ + +/** Search bar component + * @constant {ol-ext.control.Search} + */ +const searchBar = new Search({ + // disable autocompletion + typing: -1, + placeholder: "Search for products...", + collapsed: "false", + className: "searchBar", +}); + +export default searchBar; diff --git a/openlayers/modules/searchInputHandler.js b/openlayers/modules/searchInputHandler.js new file mode 100644 index 0000000..1016b21 --- /dev/null +++ b/openlayers/modules/searchInputHandler.js @@ -0,0 +1,17 @@ +/** + * @module searchInputHander + */ + +/** Handles user pressing Enter key in search input field by sending current coordinates and contents of field to React Native for processing + * @param {Event} event - Keydown event in search input field + * @param {ol.Map} map - OpenLayers map + */ +const searchInputHander = (event, map) => { + if (event.key === "Enter") { + const coords = map.getView().getCenter(); + const query = event.target.value; + window.ReactNativeWebView?.postMessage(`search@${coords}:${query}`); + } +}; + +export default searchInputHander; diff --git a/openlayers/modules/toLatLon.js b/openlayers/modules/toLatLon.js new file mode 100644 index 0000000..493bbef --- /dev/null +++ b/openlayers/modules/toLatLon.js @@ -0,0 +1,26 @@ +import utmObj from "utm-latlng"; + +const utm = new utmObj(); + +/** + * @module toLatLon + */ + +/** Converts UTM coordinates in database store records to latitude/longitude for use with the map + * @param {number} easting - UTM easting of store + * @param {number} northing - UTM northing of store + * @param {string} zone - UTM zone of store + * @param {string} zoneLetter - UTM zone letter of store + * @returns {Array} - Array of coordinates as [latitude, longitude] + */ +const toLatLon = (easting, northing, zone, zoneLetter) => { + const convertedCoordinates = utm.convertUtmToLatLng( + easting, + northing, + zone, + zoneLetter + ); + return [convertedCoordinates.lat, convertedCoordinates.lng]; +}; + +export default toLatLon; diff --git a/openlayers/package-lock.json b/openlayers/package-lock.json index 16c4f0e..ec7da67 100644 --- a/openlayers/package-lock.json +++ b/openlayers/package-lock.json @@ -16,9 +16,22 @@ "vite-plugin-singlefile": "^0.13.5" }, "devDependencies": { + "jsdoc": "^4.0.2", "vite": "^4.0.4" } }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", @@ -349,6 +362,18 @@ "node": ">=12" } }, + "node_modules/@jsdoc/salty": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.7.tgz", + "integrity": "sha512-mh8LbS9d4Jq84KLw8pzho7XC2q2/IJGiJss3xwRoLD1A+EE16SjN4PfaG4jRCzKegTFLlN0Zd8SdUPE6XdoPFg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", @@ -403,6 +428,40 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/bootstrap": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", @@ -432,6 +491,18 @@ "node": ">=8" } }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/csscolorparser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", @@ -453,6 +524,15 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", @@ -489,6 +569,15 @@ "@esbuild/win32-x64": "0.16.17" } }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -536,6 +625,12 @@ "node": ">=10.19" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -585,16 +680,78 @@ "node": ">=0.12.0" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/json-stringify-pretty-compact": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz", "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==" }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/lerc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz", "integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==" }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -611,6 +768,50 @@ "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.1.tgz", "integrity": "sha512-QQ/iKiM43DM9+aujTL45Iz5o7gDeSFmy4LPl3HZmNcwCE++NxGazf+yFpY+wCb+YS23sDa1ghpo3zrNFOcHlow==" }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -628,6 +829,18 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -756,6 +969,15 @@ "quickselect": "^2.0.0" } }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -836,6 +1058,18 @@ "node": ">=0.10.0" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -858,6 +1092,18 @@ "node": ">=8.0" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "node_modules/utm-latlng": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/utm-latlng/-/utm-latlng-1.0.7.tgz", @@ -936,6 +1182,12 @@ "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.2.0.tgz", "integrity": "sha512-z4unVPZruEDC3tfyd7wvWfjclnMz34iwQpv8H28H+qREpjKkR083MBvcrWXfJrIcrSmHR5ghguOcgQqWdnBpVA==" }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -943,6 +1195,12 @@ } }, "dependencies": { + "@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true + }, "@esbuild/android-arm": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", @@ -1075,6 +1333,15 @@ "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", "optional": true }, + "@jsdoc/salty": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.7.tgz", + "integrity": "sha512-mh8LbS9d4Jq84KLw8pzho7XC2q2/IJGiJss3xwRoLD1A+EE16SjN4PfaG4jRCzKegTFLlN0Zd8SdUPE6XdoPFg==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", @@ -1116,6 +1383,40 @@ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "peer": true }, + "@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "bootstrap": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", @@ -1130,6 +1431,15 @@ "fill-range": "^7.0.1" } }, + "catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "csscolorparser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", @@ -1145,6 +1455,12 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + }, "esbuild": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", @@ -1174,6 +1490,12 @@ "@esbuild/win32-x64": "0.16.17" } }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1207,6 +1529,12 @@ "xml-utils": "^1.0.2" } }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1233,16 +1561,72 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.4" + } + }, + "jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + } + }, "json-stringify-pretty-compact": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz", "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==" }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, "lerc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz", "integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==" }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1256,6 +1640,38 @@ "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.1.tgz", "integrity": "sha512-QQ/iKiM43DM9+aujTL45Iz5o7gDeSFmy4LPl3HZmNcwCE++NxGazf+yFpY+wCb+YS23sDa1ghpo3zrNFOcHlow==" }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "requires": {} + }, + "marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -1270,6 +1686,12 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -1366,6 +1788,15 @@ "quickselect": "^2.0.0" } }, + "requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -1421,6 +1852,12 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -1434,6 +1871,18 @@ "is-number": "^7.0.0" } }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "utm-latlng": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/utm-latlng/-/utm-latlng-1.0.7.tgz", @@ -1469,6 +1918,12 @@ "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.2.0.tgz", "integrity": "sha512-z4unVPZruEDC3tfyd7wvWfjclnMz34iwQpv8H28H+qREpjKkR083MBvcrWXfJrIcrSmHR5ghguOcgQqWdnBpVA==" }, + "xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/openlayers/package.json b/openlayers/package.json index 110f193..0909e4e 100644 --- a/openlayers/package.json +++ b/openlayers/package.json @@ -7,6 +7,7 @@ "serve": "vite preview" }, "devDependencies": { + "jsdoc": "^4.0.2", "vite": "^4.0.4" }, "dependencies": {