From bb465f025027bac91ec0974ef39fe317a0381194 Mon Sep 17 00:00:00 2001 From: Kyle Johnson Date: Fri, 31 Oct 2014 18:46:37 +0000 Subject: [PATCH] Initial commit of bootstrap-based skin --- web/skins/bootstrap/Makefile.am | 15 + web/skins/bootstrap/ajax/Makefile.am | 5 + web/skins/bootstrap/css/Makefile.am | 8 + web/skins/bootstrap/css/control.css | 147 +++ web/skins/bootstrap/css/export.css | 54 + web/skins/bootstrap/css/skin.css | 439 ++++++++ web/skins/bootstrap/graphics/Makefile.am | 23 + web/skins/bootstrap/graphics/arrow-d.gif | Bin 0 -> 293 bytes web/skins/bootstrap/graphics/arrow-dl.gif | Bin 0 -> 232 bytes web/skins/bootstrap/graphics/arrow-dr.gif | Bin 0 -> 263 bytes web/skins/bootstrap/graphics/arrow-l-d.gif | Bin 0 -> 538 bytes web/skins/bootstrap/graphics/arrow-l-u.gif | Bin 0 -> 524 bytes web/skins/bootstrap/graphics/arrow-l.gif | Bin 0 -> 284 bytes web/skins/bootstrap/graphics/arrow-r.gif | Bin 0 -> 265 bytes web/skins/bootstrap/graphics/arrow-s-d.gif | Bin 0 -> 206 bytes web/skins/bootstrap/graphics/arrow-s-u.gif | Bin 0 -> 203 bytes web/skins/bootstrap/graphics/arrow-u.gif | Bin 0 -> 278 bytes web/skins/bootstrap/graphics/arrow-ul.gif | Bin 0 -> 286 bytes web/skins/bootstrap/graphics/arrow-ur.gif | Bin 0 -> 282 bytes web/skins/bootstrap/graphics/center.gif | Bin 0 -> 621 bytes web/skins/bootstrap/graphics/point-g.gif | Bin 0 -> 76 bytes web/skins/bootstrap/graphics/point-o.gif | Bin 0 -> 76 bytes web/skins/bootstrap/graphics/point-r.gif | Bin 0 -> 76 bytes web/skins/bootstrap/graphics/seq-d.gif | Bin 0 -> 68 bytes web/skins/bootstrap/graphics/seq-u.gif | Bin 0 -> 68 bytes web/skins/bootstrap/includes/Makefile.am | 11 + web/skins/bootstrap/includes/config.php | 112 ++ .../bootstrap/includes/control_functions.php | 390 +++++++ .../bootstrap/includes/export_functions.php | 963 +++++++++++++++++ web/skins/bootstrap/includes/functions.php | 112 ++ web/skins/bootstrap/includes/init.php | 0 .../bootstrap/includes/timeline_functions.php | 525 ++++++++++ web/skins/bootstrap/js/Makefile.am | 7 + web/skins/bootstrap/js/jquery-1.4.2.min.js | 154 +++ web/skins/bootstrap/js/skin.js | 310 ++++++ web/skins/bootstrap/js/skin.js.php | 40 + web/skins/bootstrap/lang/Makefile.am | 5 + web/skins/bootstrap/skin.php | 66 ++ web/skins/bootstrap/views/Makefile.am | 55 + web/skins/bootstrap/views/bandwidth.php | 58 ++ web/skins/bootstrap/views/blank.php | 37 + web/skins/bootstrap/views/console.php | 352 +++++++ web/skins/bootstrap/views/control.php | 79 ++ web/skins/bootstrap/views/controlcap.php | 512 +++++++++ web/skins/bootstrap/views/controlcaps.php | 89 ++ web/skins/bootstrap/views/controlpreset.php | 70 ++ web/skins/bootstrap/views/css/Makefile.am | 31 + web/skins/bootstrap/views/css/console.css | 97 ++ web/skins/bootstrap/views/css/control.css | 1 + web/skins/bootstrap/views/css/controlcaps.css | 3 + web/skins/bootstrap/views/css/devices.css | 4 + web/skins/bootstrap/views/css/event.css | 232 +++++ web/skins/bootstrap/views/css/events.css | 42 + web/skins/bootstrap/views/css/export.css | 15 + web/skins/bootstrap/views/css/filter.css | 25 + web/skins/bootstrap/views/css/frame.css | 30 + web/skins/bootstrap/views/css/frames.css | 15 + web/skins/bootstrap/views/css/groups.css | 6 + web/skins/bootstrap/views/css/log.css | 53 + web/skins/bootstrap/views/css/monitor.css | 5 + web/skins/bootstrap/views/css/montage.css | 41 + .../bootstrap/views/css/montage_2wide.css | 30 + .../bootstrap/views/css/montage_3wide.css | 37 + .../views/css/montage_3wide50enlarge.css | 74 ++ .../bootstrap/views/css/montage_4wide.css | 44 + .../bootstrap/views/css/montage_freeform.css | 9 + web/skins/bootstrap/views/css/options.css | 24 + web/skins/bootstrap/views/css/plugin.css | 20 + web/skins/bootstrap/views/css/stats.css | 9 + web/skins/bootstrap/views/css/timeline.css | 222 ++++ .../bootstrap/views/css/timeline.css.php | 77 ++ web/skins/bootstrap/views/css/video.css | 19 + web/skins/bootstrap/views/css/watch.css | 134 +++ web/skins/bootstrap/views/css/zone.css | 95 ++ web/skins/bootstrap/views/cycle.php | 128 +++ web/skins/bootstrap/views/device.php | 67 ++ web/skins/bootstrap/views/devices.php | 86 ++ web/skins/bootstrap/views/donate.php | 65 ++ web/skins/bootstrap/views/error.php | 43 + web/skins/bootstrap/views/event.php | 224 ++++ web/skins/bootstrap/views/eventdetail.php | 131 +++ web/skins/bootstrap/views/events.php | 263 +++++ web/skins/bootstrap/views/export.php | 131 +++ web/skins/bootstrap/views/filter.php | 331 ++++++ web/skins/bootstrap/views/filtersave.php | 86 ++ web/skins/bootstrap/views/frame.php | 100 ++ web/skins/bootstrap/views/frames.php | 103 ++ web/skins/bootstrap/views/function.php | 64 ++ web/skins/bootstrap/views/group.php | 88 ++ web/skins/bootstrap/views/groups.php | 94 ++ web/skins/bootstrap/views/js/Makefile.am | 49 + web/skins/bootstrap/views/js/console.js | 65 ++ web/skins/bootstrap/views/js/console.js.php | 28 + web/skins/bootstrap/views/js/control.js | 49 + web/skins/bootstrap/views/js/controlpreset.js | 14 + .../bootstrap/views/js/controlpreset.js.php | 9 + web/skins/bootstrap/views/js/cycle.js | 11 + web/skins/bootstrap/views/js/cycle.js.php | 5 + web/skins/bootstrap/views/js/devices.js | 47 + web/skins/bootstrap/views/js/donate.js | 14 + web/skins/bootstrap/views/js/donate.js.php | 2 + web/skins/bootstrap/views/js/event.js | 754 ++++++++++++++ web/skins/bootstrap/views/js/event.js.php | 48 + web/skins/bootstrap/views/js/events.js | 150 +++ web/skins/bootstrap/views/js/events.js.php | 13 + web/skins/bootstrap/views/js/export.js | 58 ++ web/skins/bootstrap/views/js/export.js.php | 22 + web/skins/bootstrap/views/js/filter.js | 120 +++ web/skins/bootstrap/views/js/filter.js.php | 55 + web/skins/bootstrap/views/js/group.js | 11 + web/skins/bootstrap/views/js/groups.js | 47 + web/skins/bootstrap/views/js/log.js | 314 ++++++ web/skins/bootstrap/views/js/login.js | 1 + web/skins/bootstrap/views/js/monitor.js | 56 + web/skins/bootstrap/views/js/monitor.js.php | 191 ++++ web/skins/bootstrap/views/js/monitorpreset.js | 14 + web/skins/bootstrap/views/js/monitorprobe.js | 14 + web/skins/bootstrap/views/js/montage.js | 153 +++ web/skins/bootstrap/views/js/montage.js.php | 37 + web/skins/bootstrap/views/js/options.js.php | 5 + web/skins/bootstrap/views/js/plugin.js | 29 + web/skins/bootstrap/views/js/plugin.js.php | 0 web/skins/bootstrap/views/js/postlogin.js | 1 + web/skins/bootstrap/views/js/state.js | 43 + web/skins/bootstrap/views/js/state.js.php | 2 + web/skins/bootstrap/views/js/timeline.js | 137 +++ web/skins/bootstrap/views/js/timeline.js.php | 16 + web/skins/bootstrap/views/js/user.js | 36 + web/skins/bootstrap/views/js/version.js | 18 + web/skins/bootstrap/views/js/version.js.php | 1 + web/skins/bootstrap/views/js/video.js | 38 + web/skins/bootstrap/views/js/video.js.php | 5 + web/skins/bootstrap/views/js/watch.js | 723 +++++++++++++ web/skins/bootstrap/views/js/watch.js.php | 75 ++ web/skins/bootstrap/views/js/zone.js | 509 +++++++++ web/skins/bootstrap/views/js/zone.js.php | 67 ++ web/skins/bootstrap/views/log.php | 115 +++ web/skins/bootstrap/views/login.php | 49 + web/skins/bootstrap/views/logout.php | 51 + web/skins/bootstrap/views/monitor.php | 885 ++++++++++++++++ web/skins/bootstrap/views/monitorpreset.php | 60 ++ web/skins/bootstrap/views/monitorprobe.php | 361 +++++++ web/skins/bootstrap/views/montage.php | 154 +++ web/skins/bootstrap/views/none.php | 48 + web/skins/bootstrap/views/optionhelp.php | 44 + web/skins/bootstrap/views/options.php | 323 ++++++ web/skins/bootstrap/views/plugin.php | 167 +++ web/skins/bootstrap/views/postlogin.php | 33 + web/skins/bootstrap/views/settings.php | 78 ++ web/skins/bootstrap/views/state.php | 106 ++ web/skins/bootstrap/views/stats.php | 111 ++ web/skins/bootstrap/views/status.php | 85 ++ web/skins/bootstrap/views/timeline.php | 974 ++++++++++++++++++ web/skins/bootstrap/views/user.php | 158 +++ web/skins/bootstrap/views/version.php | 93 ++ web/skins/bootstrap/views/video.php | 241 +++++ web/skins/bootstrap/views/watch.php | 231 +++++ web/skins/bootstrap/views/zone.php | 278 +++++ web/skins/bootstrap/views/zones.php | 105 ++ 159 files changed, 16842 insertions(+) create mode 100644 web/skins/bootstrap/Makefile.am create mode 100644 web/skins/bootstrap/ajax/Makefile.am create mode 100644 web/skins/bootstrap/css/Makefile.am create mode 100644 web/skins/bootstrap/css/control.css create mode 100644 web/skins/bootstrap/css/export.css create mode 100644 web/skins/bootstrap/css/skin.css create mode 100644 web/skins/bootstrap/graphics/Makefile.am create mode 100644 web/skins/bootstrap/graphics/arrow-d.gif create mode 100644 web/skins/bootstrap/graphics/arrow-dl.gif create mode 100644 web/skins/bootstrap/graphics/arrow-dr.gif create mode 100644 web/skins/bootstrap/graphics/arrow-l-d.gif create mode 100644 web/skins/bootstrap/graphics/arrow-l-u.gif create mode 100644 web/skins/bootstrap/graphics/arrow-l.gif create mode 100644 web/skins/bootstrap/graphics/arrow-r.gif create mode 100644 web/skins/bootstrap/graphics/arrow-s-d.gif create mode 100644 web/skins/bootstrap/graphics/arrow-s-u.gif create mode 100644 web/skins/bootstrap/graphics/arrow-u.gif create mode 100644 web/skins/bootstrap/graphics/arrow-ul.gif create mode 100644 web/skins/bootstrap/graphics/arrow-ur.gif create mode 100644 web/skins/bootstrap/graphics/center.gif create mode 100644 web/skins/bootstrap/graphics/point-g.gif create mode 100644 web/skins/bootstrap/graphics/point-o.gif create mode 100644 web/skins/bootstrap/graphics/point-r.gif create mode 100644 web/skins/bootstrap/graphics/seq-d.gif create mode 100644 web/skins/bootstrap/graphics/seq-u.gif create mode 100644 web/skins/bootstrap/includes/Makefile.am create mode 100644 web/skins/bootstrap/includes/config.php create mode 100644 web/skins/bootstrap/includes/control_functions.php create mode 100644 web/skins/bootstrap/includes/export_functions.php create mode 100644 web/skins/bootstrap/includes/functions.php create mode 100644 web/skins/bootstrap/includes/init.php create mode 100644 web/skins/bootstrap/includes/timeline_functions.php create mode 100644 web/skins/bootstrap/js/Makefile.am create mode 100644 web/skins/bootstrap/js/jquery-1.4.2.min.js create mode 100644 web/skins/bootstrap/js/skin.js create mode 100644 web/skins/bootstrap/js/skin.js.php create mode 100644 web/skins/bootstrap/lang/Makefile.am create mode 100644 web/skins/bootstrap/skin.php create mode 100644 web/skins/bootstrap/views/Makefile.am create mode 100644 web/skins/bootstrap/views/bandwidth.php create mode 100644 web/skins/bootstrap/views/blank.php create mode 100644 web/skins/bootstrap/views/console.php create mode 100644 web/skins/bootstrap/views/control.php create mode 100644 web/skins/bootstrap/views/controlcap.php create mode 100644 web/skins/bootstrap/views/controlcaps.php create mode 100644 web/skins/bootstrap/views/controlpreset.php create mode 100644 web/skins/bootstrap/views/css/Makefile.am create mode 100644 web/skins/bootstrap/views/css/console.css create mode 100644 web/skins/bootstrap/views/css/control.css create mode 100644 web/skins/bootstrap/views/css/controlcaps.css create mode 100644 web/skins/bootstrap/views/css/devices.css create mode 100644 web/skins/bootstrap/views/css/event.css create mode 100644 web/skins/bootstrap/views/css/events.css create mode 100644 web/skins/bootstrap/views/css/export.css create mode 100644 web/skins/bootstrap/views/css/filter.css create mode 100644 web/skins/bootstrap/views/css/frame.css create mode 100644 web/skins/bootstrap/views/css/frames.css create mode 100644 web/skins/bootstrap/views/css/groups.css create mode 100644 web/skins/bootstrap/views/css/log.css create mode 100644 web/skins/bootstrap/views/css/monitor.css create mode 100644 web/skins/bootstrap/views/css/montage.css create mode 100644 web/skins/bootstrap/views/css/montage_2wide.css create mode 100644 web/skins/bootstrap/views/css/montage_3wide.css create mode 100644 web/skins/bootstrap/views/css/montage_3wide50enlarge.css create mode 100644 web/skins/bootstrap/views/css/montage_4wide.css create mode 100644 web/skins/bootstrap/views/css/montage_freeform.css create mode 100644 web/skins/bootstrap/views/css/options.css create mode 100644 web/skins/bootstrap/views/css/plugin.css create mode 100644 web/skins/bootstrap/views/css/stats.css create mode 100644 web/skins/bootstrap/views/css/timeline.css create mode 100644 web/skins/bootstrap/views/css/timeline.css.php create mode 100644 web/skins/bootstrap/views/css/video.css create mode 100644 web/skins/bootstrap/views/css/watch.css create mode 100644 web/skins/bootstrap/views/css/zone.css create mode 100644 web/skins/bootstrap/views/cycle.php create mode 100644 web/skins/bootstrap/views/device.php create mode 100644 web/skins/bootstrap/views/devices.php create mode 100644 web/skins/bootstrap/views/donate.php create mode 100644 web/skins/bootstrap/views/error.php create mode 100644 web/skins/bootstrap/views/event.php create mode 100644 web/skins/bootstrap/views/eventdetail.php create mode 100644 web/skins/bootstrap/views/events.php create mode 100644 web/skins/bootstrap/views/export.php create mode 100644 web/skins/bootstrap/views/filter.php create mode 100644 web/skins/bootstrap/views/filtersave.php create mode 100644 web/skins/bootstrap/views/frame.php create mode 100644 web/skins/bootstrap/views/frames.php create mode 100644 web/skins/bootstrap/views/function.php create mode 100644 web/skins/bootstrap/views/group.php create mode 100644 web/skins/bootstrap/views/groups.php create mode 100644 web/skins/bootstrap/views/js/Makefile.am create mode 100644 web/skins/bootstrap/views/js/console.js create mode 100644 web/skins/bootstrap/views/js/console.js.php create mode 100644 web/skins/bootstrap/views/js/control.js create mode 100644 web/skins/bootstrap/views/js/controlpreset.js create mode 100644 web/skins/bootstrap/views/js/controlpreset.js.php create mode 100644 web/skins/bootstrap/views/js/cycle.js create mode 100644 web/skins/bootstrap/views/js/cycle.js.php create mode 100644 web/skins/bootstrap/views/js/devices.js create mode 100644 web/skins/bootstrap/views/js/donate.js create mode 100644 web/skins/bootstrap/views/js/donate.js.php create mode 100644 web/skins/bootstrap/views/js/event.js create mode 100644 web/skins/bootstrap/views/js/event.js.php create mode 100644 web/skins/bootstrap/views/js/events.js create mode 100644 web/skins/bootstrap/views/js/events.js.php create mode 100644 web/skins/bootstrap/views/js/export.js create mode 100644 web/skins/bootstrap/views/js/export.js.php create mode 100644 web/skins/bootstrap/views/js/filter.js create mode 100644 web/skins/bootstrap/views/js/filter.js.php create mode 100644 web/skins/bootstrap/views/js/group.js create mode 100644 web/skins/bootstrap/views/js/groups.js create mode 100644 web/skins/bootstrap/views/js/log.js create mode 100644 web/skins/bootstrap/views/js/login.js create mode 100644 web/skins/bootstrap/views/js/monitor.js create mode 100644 web/skins/bootstrap/views/js/monitor.js.php create mode 100644 web/skins/bootstrap/views/js/monitorpreset.js create mode 100644 web/skins/bootstrap/views/js/monitorprobe.js create mode 100644 web/skins/bootstrap/views/js/montage.js create mode 100644 web/skins/bootstrap/views/js/montage.js.php create mode 100644 web/skins/bootstrap/views/js/options.js.php create mode 100644 web/skins/bootstrap/views/js/plugin.js create mode 100644 web/skins/bootstrap/views/js/plugin.js.php create mode 100644 web/skins/bootstrap/views/js/postlogin.js create mode 100644 web/skins/bootstrap/views/js/state.js create mode 100644 web/skins/bootstrap/views/js/state.js.php create mode 100644 web/skins/bootstrap/views/js/timeline.js create mode 100644 web/skins/bootstrap/views/js/timeline.js.php create mode 100644 web/skins/bootstrap/views/js/user.js create mode 100644 web/skins/bootstrap/views/js/version.js create mode 100644 web/skins/bootstrap/views/js/version.js.php create mode 100644 web/skins/bootstrap/views/js/video.js create mode 100644 web/skins/bootstrap/views/js/video.js.php create mode 100644 web/skins/bootstrap/views/js/watch.js create mode 100644 web/skins/bootstrap/views/js/watch.js.php create mode 100644 web/skins/bootstrap/views/js/zone.js create mode 100644 web/skins/bootstrap/views/js/zone.js.php create mode 100644 web/skins/bootstrap/views/log.php create mode 100644 web/skins/bootstrap/views/login.php create mode 100644 web/skins/bootstrap/views/logout.php create mode 100644 web/skins/bootstrap/views/monitor.php create mode 100644 web/skins/bootstrap/views/monitorpreset.php create mode 100644 web/skins/bootstrap/views/monitorprobe.php create mode 100644 web/skins/bootstrap/views/montage.php create mode 100644 web/skins/bootstrap/views/none.php create mode 100644 web/skins/bootstrap/views/optionhelp.php create mode 100644 web/skins/bootstrap/views/options.php create mode 100644 web/skins/bootstrap/views/plugin.php create mode 100644 web/skins/bootstrap/views/postlogin.php create mode 100644 web/skins/bootstrap/views/settings.php create mode 100644 web/skins/bootstrap/views/state.php create mode 100644 web/skins/bootstrap/views/stats.php create mode 100644 web/skins/bootstrap/views/status.php create mode 100644 web/skins/bootstrap/views/timeline.php create mode 100644 web/skins/bootstrap/views/user.php create mode 100644 web/skins/bootstrap/views/version.php create mode 100644 web/skins/bootstrap/views/video.php create mode 100644 web/skins/bootstrap/views/watch.php create mode 100644 web/skins/bootstrap/views/zone.php create mode 100644 web/skins/bootstrap/views/zones.php diff --git a/web/skins/bootstrap/Makefile.am b/web/skins/bootstrap/Makefile.am new file mode 100644 index 000000000..986beae0d --- /dev/null +++ b/web/skins/bootstrap/Makefile.am @@ -0,0 +1,15 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic + +SUBDIRS = \ + ajax \ + css \ + graphics \ + includes \ + js \ + lang \ + views + +dist_web_DATA = \ + skin.php diff --git a/web/skins/bootstrap/ajax/Makefile.am b/web/skins/bootstrap/ajax/Makefile.am new file mode 100644 index 000000000..f910cbc5c --- /dev/null +++ b/web/skins/bootstrap/ajax/Makefile.am @@ -0,0 +1,5 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/ajax + +dist_web_DATA = # No files here diff --git a/web/skins/bootstrap/css/Makefile.am b/web/skins/bootstrap/css/Makefile.am new file mode 100644 index 000000000..5b0cbe135 --- /dev/null +++ b/web/skins/bootstrap/css/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/css + +dist_web_DATA = \ + skin.css \ + control.css \ + export.css diff --git a/web/skins/bootstrap/css/control.css b/web/skins/bootstrap/css/control.css new file mode 100644 index 000000000..97c3aba88 --- /dev/null +++ b/web/skins/bootstrap/css/control.css @@ -0,0 +1,147 @@ +.ptzControls { + vertical-align: top; + margin: 10px auto 0; + width: 300px; +} + +.ptzControls input.ptzTextBtn { + margin-top: 2px; + width: 40px; +} + +.ptzControls .controlsPanel { + margin: 0 auto; +} + +.ptzControls input[type=image] { + border: 0px; +} + +.ptzControls .controlsPanel .arrowControl { + width: 40px; + height: 180px; + margin: 0 4px; +} + +.ptzControls .controlsPanel .arrowControl input { + display: block; +} + +.ptzControls .controlsPanel .longArrowBtn { + width: 32px; + height: 48px; + margin: 0 auto; + cursor: pointer; +} + +/* + * This is a bit of a hack as these lines should be in the above + * section but that messes up layout on IE6 + */ +/* +.ptzControls .controlsPanel > div > div.longArrowBtn { + left: 50%; + margin-left: -16px; +} +*/ + +.ptzControls .controlsPanel .upBtn { + background: url("../graphics/arrow-l-u.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .downBtn { + background: url("../graphics/arrow-l-d.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .focusControls { + float: left; +} + +.ptzControls .controlsPanel .zoomControls { + float: left; +} + +.ptzControls .controlsPanel .irisControls { + float: right; +} + +.ptzControls .controlsPanel .whiteControls { + float: right; +} + +.ptzControls .controlsPanel .pantiltPanel { + margin: 0 auto; + height: 180px; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .pantiltButtons { + margin: 5px auto; + border: 1px solid #006699; + text-align: center; + padding: 1px; + width: 96px; + height: 96px; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .arrowBtn { + width: 32px; + height: 32px; + cursor: pointer; + float: left; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .upLeftBtn { + background: url("../graphics/arrow-ul.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .upBtn { + background: url("../graphics/arrow-u.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .upRightBtn { + background: url("../graphics/arrow-ur.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .leftBtn { + background: url("../graphics/arrow-l.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .centerBtn { + background: url("../graphics/center.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .rightBtn { + background: url("../graphics/arrow-r.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .downLeftBtn { + background: url("../graphics/arrow-dl.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .downBtn { + background: url("../graphics/arrow-d.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .pantiltControls .downRightBtn { + background: url("../graphics/arrow-dr.gif") no-repeat 0 0; +} + +.ptzControls .controlsPanel .pantiltPanel .powerControls { + margin: 0 auto; +} + +.ptzControls .presetControls { + margin: 0 auto; +} + +.ptzControls .presetControls input { + margin: 1px; +} + +.ptzControls .presetControls input.ptzNumBtn { + padding: 1px 2px; + width: 24px; + color: #ffffff; + text-align: center; + background-color: #016A9D; +} diff --git a/web/skins/bootstrap/css/export.css b/web/skins/bootstrap/css/export.css new file mode 100644 index 000000000..b9b542d5b --- /dev/null +++ b/web/skins/bootstrap/css/export.css @@ -0,0 +1,54 @@ +body { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size:10px; + font-weight: normal + color: #333333; +} + +table { + border-collapse: collapse; +} + +th, td { + border: 1px solid #7f7fb2; + text-align: center; + padding: 2px 4px; +} + +a:link { + color: #7f7fb2; + text-decoration: none +} + +a:visited { + color: #7f7fb2; + text-decoration: none +} + +a:hover { + color: #666699; + text-decoration: underline +} + +img.thumb { + width: 40px; +} + +td.monoRow { + line-height: 200%; + text-align: center; + vertical-align: middle; +} + +#eventFrames tr.alarm { + background-color: #fa8072; +} + +#eventFrames tr.bulk { + background-color: #cccccc; +} + +#eventFrames tr.normal { + background-color: #ffffff; +} + diff --git a/web/skins/bootstrap/css/skin.css b/web/skins/bootstrap/css/skin.css new file mode 100644 index 000000000..5ceb4e4b1 --- /dev/null +++ b/web/skins/bootstrap/css/skin.css @@ -0,0 +1,439 @@ +/* + * ZoneMinder Base Stylesheet, $Date$, $Revision$ + * Copyright (C) 2001-2008 Philip Coombes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) input[type=password], any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Primary look and feel styles + */ + +body { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + color: #333333; + font-weight: normal; + text-align: center; +} + +h1 { + font-family: inherit; + font-size: 120%; + color: #000066; + font-weight: bold; + text-align: center; +} + +h2 { + font-family: inherit; + font-size: 110%; + color: #000066; + font-weight: bold; +} + +h3 { + font-family: inherit; + font-size: 100%; + color: #016A9d; + font-weight: bold; +} + +h4 { + font-family: inherit; + font-size: 100%; + color: #016A9d; +} + +p { + font-family: inherit; + font-size: 100%; + color: #333333; + font-weight: normal; +} + +th { + font-weight: bold; + color: #016A9d; +} + +a:link { + color: #7f7fb2; + text-decoration: none; +} + +a:visited { + color: #7f7fb2; + text-decoration: none; +} + +a:hover { + color: #666699; + text-decoration: underline; +} + +label { + margin-right: 4px; +} + +input,textarea,select,button { + border: 1px #7f7fb2 solid; + font-family: inherit; + font-size: 100%; + color: #333333; +} + +input[type=text], input[type=password], textarea { + padding: 1px; +} + +input.noborder { + border: 0; +} + +input[disabled] { + color: #888888; +} + +img.normal { + border: white solid 1px; +} + +img.alarm { + border: red solid 1px; +} + +hr { + height: 1px; + width: 100%; + border: 0; + color: #7f7fb2; + background-color: #7f7fb2; +} + +/* + * Tabbed headings + */ +ul.tabList { + float: left; + list-style: none; + padding: 0; + margin: 0 0 -4px 0; + white-space: nowrap; + text-align: left; +} + +ul.tabList li { + float: left; + border: 1px solid; + color: #333333; + border: #7f7fb2 solid 1px; + border-bottom-width: 0; + margin: 0 2px 0 0; + background: #dddddd; + text-align: center; + padding: 3px 4px; +} + +ul.tabList li a { + text-decoration: none; +} + +ul.tabList li:hover { + background-color: #eeeeee; +} + +ul.tabList li.active { + background-color: #ffffff; + border-bottom: #7f7fb2 dotted 1px; +} + +ul.tabList li.active a { + font-weight: bold; +} + +/* + * Major league table for multiple inputs or presentation + */ + +#content table.major { + margin: 4px auto; + width: 100%; + border-collapse: collapse; +} + +#content table.major tr.highlight { + background-color: #eeeeee; +} + +#content table.major thead tr th { + padding-top: 6px; + padding-bottom: 6px; + vertical-align: middle; +} + +#content table.major tfoot td { + padding-top: 6px; + padding-bottom: 6px; + vertical-align: middle; +} + +#content table.major th, #content table.major td { + border: 1px solid #7f7fb2; + padding: 3px; + text-align: left; +} + +#content table.major th { + vertical-align: bottom; +} + +#content table.major td { + vertical-align: middle; +} + +#content table.major th[scope=row] { + padding: 4px 3px 3px; + vertical-align: top; +} + +#content table.major .colMark, #content table.major .colSelect { + text-align: center; +} +/* + * Lesser table for very simple forms + */ + +#content table.minor { + width: 280px; + margin: 0 auto; +} + +#content table.minor td { + padding: 4px; +} + +#content table.minor .colLeft { + width: 50%; + text-align: right; +} + +#content table.minor .colRight { + width: 50%; + text-align: left; +} + +#content table.minor input[type=submit] +{ + margin-top: 8px; + padding: 0 2px; + font-size: 120%; +} + +.overlay { + font-size: 11px; +} + +.overlay fieldset { + background-color: #f8f8f8; +} + +.validation-advice { + padding: 4px; + color: #dc143c; +} + +fieldset { + border: 1px solid black; + padding: 4px; + margin-bottom: 8px; + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; +} + +fieldset > legend { + padding: 0 2px; +} + +/* + * Behavior classes + */ +.alarm, .errorText { + color: #dc143c; +} + +.alert, .warnText { + color: #ff8c00; +} + +.ok, .infoText { + color: #688e23; +} + +.fakelink { + color: #7f7fb2; + cursor: pointer; +} + +.fakelink:hover { + color: #336699; + text-decoration: none; +} + +/* + * Generic useful classes, especially with mootools + */ + +.hidden { + display: none; +} + +.invisible { + visibility: hidden; +} + +.nowrap { + white-space: nowrap; +} + +div.clear { + clear: both; +} + +/* +.table-th-sort { + font-style:italic; +} + +td.table-td-sort { + font-style:italic; +} +*/ + +th.table-th-sort { + margin-right: 12px; +} + +th.table-th-sort span.table-th-sort-span { + float: right; + width: 12px; + height: 12px; + background: url("../graphics/arrow-s-u.gif") no-repeat 0 0; +} + +th.table-th-sort-rev span.table-th-sort-span { + float: right; + width: 12px; + height: 12px; + background: url("../graphics/arrow-s-d.gif") no-repeat 0 0; +} + +.table-tr-odd { + background-color: #f8f8f8; +} + +/* + * Primary layout styles + */ + +#page { + width: 100%; +} + +#header { + width: 96%; + line-height: 24px; + margin: 8px auto; + text-align: left; +} + +#header h2 { + left: 0; +} + +#header h2.floating { + float: left; +} + +#headerControl { + width: 50%; + text-align: center; + margin: 0 auto; +} + +#headerButtons { + float: right; +} + +#headerButtons a { + margin-left: 8px; +} + +#headerButtons input { + margin-left: 4px; +} + +#content { + width: 96%; + margin: 8px auto; + line-height: 130%; + text-align: center; +} + +#content p { + margin-top: 4px; +} + +#content p.textblock { + text-align: justify; + padding: 4px; +} + +#content p.textblock br { + margin-bottom: 8px; +} + +/* +#contentDiv { + margin: 0 auto 8px; + line-height: 140%; + text-align: center; +} +*/ + +#content > input[type=submit], #content > input[type=button], #content > button { + margin-top: 8px; +} + +#content table input[type=submit], #content table input[type=button], #content table button { + margin-top: 0; +} + +#contentButtons { + margin-top: 8px; + float: right; +} + +#contentButtons input { + margin-left: 8px; + margin-bottom: 4px; +} + +#footer { + width: 96%; + margin: 8px auto; +} + diff --git a/web/skins/bootstrap/graphics/Makefile.am b/web/skins/bootstrap/graphics/Makefile.am new file mode 100644 index 000000000..c5c7b6bba --- /dev/null +++ b/web/skins/bootstrap/graphics/Makefile.am @@ -0,0 +1,23 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/graphics + +dist_web_DATA = \ + arrow-d.gif \ + arrow-dl.gif \ + arrow-dr.gif \ + arrow-l-d.gif \ + arrow-l.gif \ + arrow-l-u.gif \ + arrow-r.gif \ + arrow-s-d.gif \ + arrow-s-u.gif \ + arrow-u.gif \ + arrow-ul.gif \ + arrow-ur.gif \ + center.gif \ + point-g.gif \ + point-o.gif \ + point-r.gif \ + seq-d.gif \ + seq-u.gif diff --git a/web/skins/bootstrap/graphics/arrow-d.gif b/web/skins/bootstrap/graphics/arrow-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..809207bebe22abe3ead35e4a16a8e55aae778c14 GIT binary patch literal 293 zcmZ?wbhEHbRA5kGIKsfdkT&zeledoj+Y%QY`v3pGVDaMqeODg5{k-AgL&e&a4O`Cz z&fIh0)^o$Q^&h_dEL?qJ{_$H=_Fe<(BN8b7WML6u_|KpNQV+6|fpw9BVqZ$;JdK|m zIj?sGRB<`v-rue?+vMH#U9u~`A7*V;O1fC)qBXr?*@vA|-mP$5&GY;6vK@B%Tsc0H zaZOBLra7>?^c|_ntDeA=WfhXp^kOyS JvqO==8UQJ0XgL4? literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-dl.gif b/web/skins/bootstrap/graphics/arrow-dl.gif new file mode 100644 index 0000000000000000000000000000000000000000..6768249ccd74574e82b11f120b81329e91e0c568 GIT binary patch literal 232 zcmV9s%3%gHYWmaS35z7 zv1G~MJWWg3RLlX+b4#9dll`9mR=9L~6M$?99cFMz8;FTP847&^IT(E=I2cEj01S>4 icwGYs0t*HNlU6MX2nY)c1O%NQ1f{1Vwzs$=5db^J*j?cO literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-dr.gif b/web/skins/bootstrap/graphics/arrow-dr.gif new file mode 100644 index 0000000000000000000000000000000000000000..d497bdbc1ee2e8727dddbfe4dbfb68c65d3c6ed6 GIT binary patch literal 263 zcmV+i0r>t$Nk%w1VITk?0J8u90A`uch;44?o&!;mN~syr~jB14!lWfq{xF@VOLITO_6 zNFX6jpg>g?Jc=~uf`d$(#uNZms#OFCqgu5%!01+_KflKO=vA!9qG8PfK$}+VQ-%rD zzE#N6ELOTh?J5kA*Q|nsEY*rccz}Umkv{hlFt9)Xg1$)EPCP(>z=8z`5VYi|G~>Yl NizRy=O}bz}06U_WZBzgN literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-l-d.gif b/web/skins/bootstrap/graphics/arrow-l-d.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7b405b1f1873df7ffacddeb3d1c3fcd73465173 GIT binary patch literal 538 zcmV+#0_FWjNk%w1VITl70M!5h0A`uh*x6NtnyR+DfSRWraG3x9|G&)Bfwj(ZlA`MC z>>+)rLy)(>+2%2Zubiy3`R?eF&a zj-#z{tH_?l+Trc=&eqzm(BPrS+tu6NDs-2##?L{IwvM>W9B`OZn!Ul>=bpXHf3(i= z@$ss`&G`8E$I;f3zt!B};6>4Mw^QgHMZH{K%xUTlXfDXJFX cY3--hA|HlE`0&+818OSD9ue_Wt=b>}JKdrQUjP6A literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-l-u.gif b/web/skins/bootstrap/graphics/arrow-l-u.gif new file mode 100644 index 0000000000000000000000000000000000000000..9422c0f4752d91b3c32056de0dcfb5a73be78ba2 GIT binary patch literal 524 zcmZ?wbhEHbRA4Y*xXQr5kT&z`jhlvT>sM{t?byFfwqVBp|Nk3iEuXVy%Yn0(U%h_Q zu=QL@_dLbgmHTf!>)&za@w4adbu$Hv7bh+{6xuRt=fR_A&YUTlw8*k@#{A>A-hcbq zw|MRO$8VSHKePVAgZpnj2hQAc?%J)Zx9=6MKA~MQecG-ws}G%>yZ6k;j~{>h__68e z`QsO_-Ffh6!oDj&w~zr8f3mQMF#KoG0qF(#iGl6ELvw+Lj#U4NB?glNttRp@9Qe3~ z%U)>ZljPDYmY|gmmwlTKB?kPoa9Zr1opkJN-Z9I_s)$38*`KPaQ^MjKOOnHc+p2^^ zb-NpN{p2RJ$$3^xZLD#Z;+@sT+w8)!pqs_DYgu=%_v)!-e494&t(q#lWwR&u0`Am3 zv-ZUvn0hGe$b@5|C%RAhpJ_YiccJl;*OjVkyZ7$DbNF5uKkMTsPoMIqs;azx^Y*Q3 zs=CDIFJHf^r^*Wc{`2>*Y^qOygvW*iN8!{EgNPFw5}id;g<@uSY)m@JBFLX{=fp(i zV|v&_JWXB?NBndI8ml%4j{U6Zik;Zly-Qy-^& zt?`?z@W$dmY{SXNdADWtoz{F$%ZzWx$+Kx`RPpObQuXKwC{bpa;59l^HS_ptiyKfud!V67s9H2{_%X|MnQ literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-r.gif b/web/skins/bootstrap/graphics/arrow-r.gif new file mode 100644 index 0000000000000000000000000000000000000000..e36acc8d86ea14850a22aef9dd396ea56601cf12 GIT binary patch literal 265 zcmZ?wbhEHbRA5kGIKsfdkT&zeled90_bAq`?B93g|Ns9DTh2Xr`&qDf@%jr79Q(Hw zu0FB<*0cBDekLwDH2?T5!?yKP_Fe<(BN8b7WML6u_|KpNQV+6|fwe6`u`eZao`%$t zoM?r9?dc2~&Q$Pf@VRLy_hHVM53nlot z=WHpGFj850y2Is{?7rR?S@Ssfml23J&} hXTL+v+=XZrz0KA5;8mu50Z|sGV}9%sF>)$$j0PR<#Ry6p<#-gB8$a`2`WdMxpS1xy!`m= Q01Hc#P{V?a4h{^~04mHuEdT%j literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-u.gif b/web/skins/bootstrap/graphics/arrow-u.gif new file mode 100644 index 0000000000000000000000000000000000000000..f76f5e0055b15316fb9e98791d76498427c6f952 GIT binary patch literal 278 zcmZ?wbhEHbRA5kGIKsfdkT&!D@Ju z#zlL+oUmX>xUyx!bKZHUKAcu$IuyLgK6}FT6d9}ma6V|0 literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/arrow-ul.gif b/web/skins/bootstrap/graphics/arrow-ul.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e620edf1b0850de49ab0f042298f01a2cce37a4 GIT binary patch literal 286 zcmZ?wbhEHbRA5kGIKsfdkT&zeleYmgb}QDd?B93g|NsB@-+XS^dT#%%XM)9x9s9Sf zzwp4YZGGaRL+`)+ELeSF!SP#D_Fe<(BN8b7WML6u_|KpNQV+6|fpvC*VqZ$;yo^=r za;oLJie$KxcD!PG^T$r3iJ7tSfT+OUB}L-Z7X#%S z^+axAsmEuDi=qer_AQ_AMK(tC#P!g+dX2^=wd59t>b4Fa{T@!nzLp6ZR<>~|Q#2~9 z+4*?lXK4gSE6tBw6v2?T+oo-yZ?@j*ro49dp1nN#5A2zQEj;>1OV9Q(KR z@4NEg?dSCu9u%%V5jb?WPj~x v!OTi=_47j(DM!TUE^u6-647iVW5OCXHvH literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/center.gif b/web/skins/bootstrap/graphics/center.gif new file mode 100644 index 0000000000000000000000000000000000000000..4924105159c3281cb399b8d8cc737a73556c1f0a GIT binary patch literal 621 zcmZ?wbhEHbRA5kGxXQr5kT&zeledv`_sdnU=-G4m`>#LT1q+v+y5rElwQ|Gh2X8;` zzx7O`am}nFH{O5ynX=@tMENq$DLZpl9cRy*Z`!%>*2|Co|Nj>#Ui|FC*C_|Coq71W zdHeY}NAI~!+7U2gw`9e#tIysWw60gKTlMVw_o6i?oF{IZe&~AL=CdKQ_kREWebLF= zNAJG8_vX|33lD61wg8<&Dp35%!Xm=(pFszt5#%QZw*L;@1s*z5{l}**j=0&P*Vg&P zNim^k)gmr|sHm{HD@uIKDjW{8KQIhoxVNzDiBfAt2xB{QO4kK-0d>Bt{79$h{CY(# zRu5J+r6A_~?5HUWLg60H68yqba$Na%ro_&6X<=ZFb5RLey2fK=kh-f>iAqPzM%R`6 z^8_-S1%-LMcP(?zJ(jxALUCMk*RAMyrWL!GM7O_lFEx0b& zEd0!O#xkA|)7plXfEf=KJ~`kl)~?W@uF||M;+@VMk)XUL#V(#ekEj!zljlyT7*(DmJMRT&(u2uDfchD!raB>YYJB0>+C4sunT?6~%A f0h8%j*8^e)CoFWi-^^?!6X9`j?OR1h1_o;Y7Qgmy literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/point-g.gif b/web/skins/bootstrap/graphics/point-g.gif new file mode 100644 index 0000000000000000000000000000000000000000..4b790a63359388742bcd6646632cd763b0be1dbe GIT binary patch literal 76 zcmZ?wbhEHbWM^P!n8*MI{~7-O{|{s-{$$}~U|?d<0f~a-88~DaSUFe}HYhYOu&}d5 XczjTBYGaa7GO^g0aHNTmk--`OG&K(v literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/point-o.gif b/web/skins/bootstrap/graphics/point-o.gif new file mode 100644 index 0000000000000000000000000000000000000000..7abad3743e04ecb7c1e2c32e82403d0c6f712b4a GIT binary patch literal 76 zcmZ?wbhEHbWM^P!n8*ME|7RNi|NkGzQ2fcl$-uzGpaT*G$un@sGO%*6C~Qz@U|?Zq Yi}3iM;MB$>qhw;SG2uuPBO`+~0AvLZ;s5{u literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/graphics/point-r.gif b/web/skins/bootstrap/graphics/point-r.gif new file mode 100644 index 0000000000000000000000000000000000000000..5d06dd6e002c6c5916ed2d781fe3242f3abe7791 GIT binary patch literal 76 zcmZ?wbhEHbWM^P!n8*ME|AFW~kYG^!$->FNz{H>f5(UXKaL6*SaUtxVop&ik Q@tk#hzUKo`Nmd4H0NREX3jhEB literal 0 HcmV?d00001 diff --git a/web/skins/bootstrap/includes/Makefile.am b/web/skins/bootstrap/includes/Makefile.am new file mode 100644 index 000000000..690df231a --- /dev/null +++ b/web/skins/bootstrap/includes/Makefile.am @@ -0,0 +1,11 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/includes + +dist_web_DATA = \ + init.php \ + config.php \ + functions.php \ + control_functions.php \ + export_functions.php \ + timeline_functions.php diff --git a/web/skins/bootstrap/includes/config.php b/web/skins/bootstrap/includes/config.php new file mode 100644 index 000000000..9599c6112 --- /dev/null +++ b/web/skins/bootstrap/includes/config.php @@ -0,0 +1,112 @@ + "100x", + "5000" => "50x", + "2500" => "25x", + "1000" => "10x", + "400" => "4x", + "200" => "2x", + "100" => $SLANG['Real'], + "50" => "1/2x", + "25" => "1/4x", +); + +$scales = array( + "400" => "4x", + "300" => "3x", + "200" => "2x", + "150" => "1.5x", + "100" => $SLANG['Actual'], + "75" => "3/4x", + "50" => "1/2x", + "33" => "1/3x", + "25" => "1/4x", +); + +$bwArray = array( + "high" => $SLANG['High'], + "medium" => $SLANG['Medium'], + "low" => $SLANG['Low'] +); + +switch ( $_COOKIE['zmBandwidth'] ) +{ + case "high" : + { + define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_H_REFRESH_MAIN ); // How often (in seconds) the main console window refreshes + define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_H_REFRESH_CYCLE ); // How often the cycle watch windows swaps to the next monitor + define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_H_REFRESH_IMAGE ); // How often the watched image is refreshed (if not streaming) + define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_H_REFRESH_STATUS ); // How often the little status frame refreshes itself in the watch window + define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_H_REFRESH_EVENTS ); // How often the event listing is refreshed in the watch window, only for recent events + define( "ZM_WEB_CAN_STREAM", ZM_WEB_H_CAN_STREAM ); // Override the automatic detection of browser streaming capability + define( "ZM_WEB_STREAM_METHOD", ZM_WEB_H_STREAM_METHOD ); // Which method should be used to send video streams to your browser + define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_H_DEFAULT_SCALE ); // What the default scaling factor applied to 'live' or 'event' views is (%) + define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_H_DEFAULT_RATE ); // What the default replay rate factor applied to 'event' views is (%) + define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_H_VIDEO_BITRATE ); // What the bitrate of any streamed video should be + define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_H_VIDEO_MAXFPS ); // What the maximum frame rate of any streamed video should be + define( "ZM_WEB_SCALE_THUMBS", ZM_WEB_H_SCALE_THUMBS ); // Image scaling for thumbnails, bandwidth versus cpu in rescaling + define( "ZM_WEB_EVENTS_VIEW", ZM_WEB_H_EVENTS_VIEW ); // What the default view of multiple events should be. + define( "ZM_WEB_SHOW_PROGRESS", ZM_WEB_H_SHOW_PROGRESS ); // Whether to show the progress of replay in event view. + define( "ZM_WEB_AJAX_TIMEOUT", ZM_WEB_H_AJAX_TIMEOUT ); // Timeout to use for Ajax requests, no timeout used if unset + break; + } + case "medium" : + { + define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_M_REFRESH_MAIN ); // How often (in seconds) the main console window refreshes + define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_M_REFRESH_CYCLE ); // How often the cycle watch windows swaps to the next monitor + define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_M_REFRESH_IMAGE ); // How often the watched image is refreshed (if not streaming) + define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_M_REFRESH_STATUS ); // How often the little status frame refreshes itself in the watch window + define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_M_REFRESH_EVENTS ); // How often the event listing is refreshed in the watch window, only for recent events + define( "ZM_WEB_CAN_STREAM", ZM_WEB_M_CAN_STREAM ); // Override the automatic detection of browser streaming capability + define( "ZM_WEB_STREAM_METHOD", ZM_WEB_M_STREAM_METHOD ); // Which method should be used to send video streams to your browser + define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_M_DEFAULT_SCALE ); // What the default scaling factor applied to 'live' or 'event' views is (%) + define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_M_DEFAULT_RATE ); // What the default replay rate factor applied to 'event' views is (%) + define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_M_VIDEO_BITRATE ); // What the bitrate of any streamed video should be + define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_M_VIDEO_MAXFPS ); // What the maximum frame rate of any streamed video should be + define( "ZM_WEB_SCALE_THUMBS", ZM_WEB_M_SCALE_THUMBS ); // Image scaling for thumbnails, bandwidth versus cpu in rescaling + define( "ZM_WEB_EVENTS_VIEW", ZM_WEB_M_EVENTS_VIEW ); // What the default view of multiple events should be. + define( "ZM_WEB_SHOW_PROGRESS", ZM_WEB_M_SHOW_PROGRESS ); // Whether to show the progress of replay in event view. + define( "ZM_WEB_AJAX_TIMEOUT", ZM_WEB_M_AJAX_TIMEOUT ); // Timeout to use for Ajax requests, no timeout used if unset + break; + } + case "low" : + { + define( "ZM_WEB_REFRESH_MAIN", ZM_WEB_L_REFRESH_MAIN ); // How often (in seconds) the main console window refreshes + define( "ZM_WEB_REFRESH_CYCLE", ZM_WEB_L_REFRESH_CYCLE ); // How often the cycle watch windows swaps to the next monitor + define( "ZM_WEB_REFRESH_IMAGE", ZM_WEB_L_REFRESH_IMAGE ); // How often the watched image is refreshed (if not streaming) + define( "ZM_WEB_REFRESH_STATUS", ZM_WEB_L_REFRESH_STATUS ); // How often the little status frame refreshes itself in the watch window + define( "ZM_WEB_REFRESH_EVENTS", ZM_WEB_L_REFRESH_EVENTS ); // How often the event listing is refreshed in the watch window, only for recent events + define( "ZM_WEB_CAN_STREAM", ZM_WEB_L_CAN_STREAM ); // Override the automatic detection of browser streaming capability + define( "ZM_WEB_STREAM_METHOD", ZM_WEB_L_STREAM_METHOD ); // Which method should be used to send video streams to your browser + define( "ZM_WEB_DEFAULT_SCALE", ZM_WEB_L_DEFAULT_SCALE ); // What the default scaling factor applied to 'live' or 'event' views is (%) + define( "ZM_WEB_DEFAULT_RATE", ZM_WEB_L_DEFAULT_RATE ); // What the default replay rate factor applied to 'event' views is (%) + define( "ZM_WEB_VIDEO_BITRATE", ZM_WEB_L_VIDEO_BITRATE ); // What the bitrate of any streamed video should be + define( "ZM_WEB_VIDEO_MAXFPS", ZM_WEB_L_VIDEO_MAXFPS ); // What the maximum frame rate of any streamed video should be + define( "ZM_WEB_SCALE_THUMBS", ZM_WEB_L_SCALE_THUMBS ); // Image scaling for thumbnails, bandwidth versus cpu in rescaling + define( "ZM_WEB_EVENTS_VIEW", ZM_WEB_L_EVENTS_VIEW ); // What the default view of multiple events should be. + define( "ZM_WEB_SHOW_PROGRESS", ZM_WEB_L_SHOW_PROGRESS ); // Whether to show the progress of replay in event view. + define( "ZM_WEB_AJAX_TIMEOUT", ZM_WEB_L_AJAX_TIMEOUT ); // Timeout to use for Ajax requests, no timeout used if unset + break; + } +} + +?> diff --git a/web/skins/bootstrap/includes/control_functions.php b/web/skins/bootstrap/includes/control_functions.php new file mode 100644 index 000000000..da5296085 --- /dev/null +++ b/web/skins/bootstrap/includes/control_functions.php @@ -0,0 +1,390 @@ + +
+
+
+
onclick="controlCmd('')">
+
+
+ + + + +
+ +
+
+
+
onclick="controlCmd('')">
+
+
+ + + + +
+
+
+
+
onclick="controlCmd('')">
+
+
+ + + + +
+ +
+
+
+
onclick="controlCmd('')">
+
+
+ + + + +
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+" value="" onclick="controlCmd('');"/>
+
+
+ + + + + +
+
+ +
+
+
+ + + + + + + +
+
+ +
+ +
+ +
+ +
+ diff --git a/web/skins/bootstrap/includes/export_functions.php b/web/skins/bootstrap/includes/export_functions.php new file mode 100644 index 000000000..31eb6812e --- /dev/null +++ b/web/skins/bootstrap/includes/export_functions.php @@ -0,0 +1,963 @@ + + + + + <?= $title ?> + + + + +'.$SLANG['Frames'].','; + if( $exportImages ) $otherlinks .= ''.$SLANG['Images'].','; + $otherlinks = substr($otherlinks,0,-1); + + +?> + +
+
+

: ()

+ + + + + + + + + + + + + + +
()
+
+
+ + +'.$SLANG['Event'].','; + if( $exportImages ) $otherlinks .= ''.$SLANG['Images'].','; + $otherlinks = substr($otherlinks,0,-1); + +?> + +
+
+

: ()

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Frame <?= $frame['FrameId'] ?>
+
+
+ + +'.$SLANG['Event'].','; + if( $exportFrames ) $otherlinks .= ''.$SLANG['Frames'].','; + $otherlinks = substr($otherlinks,0,-1); + + $filelist = array_keys($myfilelist); + sort($filelist,SORT_NUMERIC); + $slides = '"'.implode('","',$filelist).'"'; + $listcount = count($filelist); +?> + + + +

: ()

+ + + + +
+
+
+ +
+
+
 
+
 
+
+
+ + + + + + + + +

Master

+ +
+ + +
+ + +
+
+

All

+ $eids
"; + } + ?> + +
+ + + "; + echo "

Monitor: " . $monitorNames[$monitor] . "

"; + foreach ($eids as $eid) + { + if ($eventMonitorId[$eid] == $monitor) + { + ?> +
+ '; + } + + ?> + +
+ + + +
+ + + + + + + + + + <?= ZM_WEB_TITLE_PREFIX ?> - <?= validHtmlStr($title) ?> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/skins/bootstrap/includes/init.php b/web/skins/bootstrap/includes/init.php new file mode 100644 index 000000000..e69de29bb diff --git a/web/skins/bootstrap/includes/timeline_functions.php b/web/skins/bootstrap/includes/timeline_functions.php new file mode 100644 index 000000000..cf92f8689 --- /dev/null +++ b/web/skins/bootstrap/includes/timeline_functions.php @@ -0,0 +1,525 @@ +"; + if ( $scaleRange >= $minLines ) + { + $scale['range'] = $scaleRange; + break; + } + } + if ( !isset($scale['range']) ) + { + $scale['range'] = (int)($range/($scale['factor']*$align)); + } + $scale['divisor'] = 1; + while ( ($scale['range']/$scale['divisor']) > $maxLines ) + { + $scale['divisor']++; + } + $scale['lines'] = (int)($scale['range']/$scale['divisor']); + return( $scale ); +} + +function getYScale( $range, $minLines, $maxLines ) +{ + $scale['range'] = $range; + $scale['divisor'] = 1; + while ( $scale['range']/$scale['divisor'] > $maxLines ) + { + $scale['divisor']++; + } + $scale['lines'] = (int)(($scale['range']-1)/$scale['divisor'])+1; + + return( $scale ); +} + +function getSlotFrame( $slot ) +{ + $slotFrame = isset($slot['frame'])?$slot['frame']['FrameId']:1; + if ( false && $slotFrame ) + { + $slotFrame -= $monitor['PreEventCount']; + if ( $slotFrame < 1 ) + $slotFrame = 1; + } + return( $slotFrame ); +} + +function parseFilterToTree( $filter ) +{ + if ( count($filter['terms']) > 0 ) + { + $postfixExpr = array(); + $postfixStack = array(); + + $priorities = array( + '<' => 1, + '<=' => 1, + '>' => 1, + '>=' => 1, + '=' => 2, + '!=' => 2, + '=~' => 2, + '!~' => 2, + '=[]' => 2, + '![]' => 2, + 'and' => 3, + 'or' => 4, + ); + + for ( $i = 0; $i <= count($filter['terms']); $i++ ) + { + if ( !empty($filter['terms'][$i]['cnj']) ) + { + while( true ) + { + if ( !count($postfixStack) ) + { + $postfixStack[] = array( 'type'=>"cnj", 'value'=>$filter['terms'][$i]['cnj'], 'sqlValue'=>$filter['terms'][$i]['cnj']); + break; + } + elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) + { + $postfixStack[] = array( 'type'=>"cnj", 'value'=>$filter['terms'][$i]['cnj'], 'sqlValue'=>$filter['terms'][$i]['cnj']); + break; + } + elseif ( $priorities[$filter['terms'][$i]['cnj']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) + { + $postfixStack[] = array( 'type'=>"cnj", 'value'=>$filter['terms'][$i]['cnj'], 'sqlValue'=>$filter['terms'][$i]['cnj']); + break; + } + else + { + $postfixExpr[] = array_pop( $postfixStack ); + } + } + } + if ( !empty($filter['terms'][$i]['obr']) ) + { + for ( $j = 0; $j < $filter['terms'][$i]['obr']; $j++ ) + { + $postfixStack[] = array( 'type'=>"obr", 'value'=>$filter['terms'][$i]['obr']); + } + } + if ( !empty($filter['terms'][$i]['attr']) ) + { + $dtAttr = false; + switch ( $filter['terms'][$i]['attr']) + { + case 'MonitorName': + $sqlValue = 'M.'.preg_replace( '/^Monitor/', '', $filter['terms'][$i]['attr']); + break; + case 'Name': + $sqlValue = "E.Name"; + break; + case 'Cause': + $sqlValue = "E.Cause"; + break; + case 'DateTime': + $sqlValue = "E.StartTime"; + $dtAttr = true; + break; + case 'Date': + $sqlValue = "to_days( E.StartTime )"; + $dtAttr = true; + break; + case 'Time': + $sqlValue = "extract( hour_second from E.StartTime )"; + break; + case 'Weekday': + $sqlValue = "weekday( E.StartTime )"; + break; + case 'Id': + case 'Name': + case 'MonitorId': + case 'Length': + case 'Frames': + case 'AlarmFrames': + case 'TotScore': + case 'AvgScore': + case 'MaxScore': + case 'Archived': + $sqlValue = "E.".$filter['terms'][$i]['attr']; + break; + case 'DiskPercent': + $sqlValue = getDiskPercent(); + break; + case 'DiskBlocks': + $sqlValue = getDiskBlocks(); + break; + default : + $sqlValue = $filter['terms'][$i]['attr']; + break; + } + if ( $dtAttr ) + { + $postfixExpr[] = array( 'type'=>"attr", 'value'=>$filter['terms'][$i]['attr'], 'sqlValue'=>$sqlValue, 'dtAttr'=>true ); + } + else + { + $postfixExpr[] = array( 'type'=>"attr", 'value'=>$filter['terms'][$i]['attr'], 'sqlValue'=>$sqlValue ); + } + } + if ( isset($filter['terms'][$i]['op']) ) + { + if ( empty($filter['terms'][$i]['op']) ) + { + $filter['terms'][$i]['op' ]= '='; + } + switch ( $filter['terms'][$i]['op' ]) + { + case '=' : + case '!=' : + case '>=' : + case '>' : + case '<' : + case '<=' : + $sqlValue = $filter['terms'][$i]['op']; + break; + case '=~' : + $sqlValue = "regexp"; + break; + case '!~' : + $sqlValue = "not regexp"; + break; + case '=[]' : + $sqlValue = 'in ('; + break; + case '![]' : + $sqlValue = 'not in ('; + break; + } + while( true ) + { + if ( !count($postfixStack) ) + { + $postfixStack[] = array( 'type'=>"op", 'value'=>$filter['terms'][$i]['op'], 'sqlValue'=>$sqlValue ); + break; + } + elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) + { + $postfixStack[] = array( 'type'=>"op", 'value'=>$filter['terms'][$i]['op'], 'sqlValue'=>$sqlValue ); + break; + } + elseif ( $priorities[$filter['terms'][$i]['op']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) + { + $postfixStack[] = array( 'type'=>"op", 'value'=>$filter['terms'][$i]['op'], 'sqlValue'=>$sqlValue ); + break; + } + else + { + $postfixExpr[] = array_pop( $postfixStack ); + } + } + } + if ( isset($filter['terms'][$i]['val']) ) + { + $valueList = array(); + foreach ( preg_split( '/["\'\s]*?,["\'\s]*?/', preg_replace( '/^["\']+?(.+)["\']+?$/', '$1', $filter['terms'][$i]['val' ]) ) as $value ) + { + switch ( $filter['terms'][$i]['attr']) + { + case 'MonitorName': + case 'Name': + case 'Cause': + case 'Notes': + $value = "'$value'"; + break; + case 'DateTime': + $value = "'".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."'"; + break; + case 'Date': + $value = "to_days( '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )"; + break; + case 'Time': + $value = "extract( hour_second from '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )"; + break; + case 'Weekday': + $value = "weekday( '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )"; + break; + } + $valueList[] = $value; + } + $postfixExpr[] = array( 'type'=>"val", 'value'=>$filter['terms'][$i]['val'], 'sqlValue'=>join( ',', $valueList ) ); + } + if ( !empty($filter['terms'][$i]['cbr']) ) + { + for ( $j = 0; $j < $filter['terms'][$i]['cbr']; $j++ ) + { + while ( count($postfixStack) ) + { + $element = array_pop( $postfixStack ); + if ( $element['type'] == "obr" ) + { + $postfixExpr[count($postfixExpr)-1]['bracket'] = true; + break; + } + $postfixExpr[] = $element; + } + } + } + } + while ( count($postfixStack) ) + { + $postfixExpr[] = array_pop( $postfixStack ); + } + + $exprStack = array(); + //foreach ( $postfixExpr as $element ) + //{ + //echo $element['value']." "; + //} + //echo "
"; + foreach ( $postfixExpr as $element ) + { + if ( $element['type'] == 'attr' || $element['type'] == 'val' ) + { + $node = array( 'data'=>$element, 'count'=>0 ); + $exprStack[] = $node; + } + elseif ( $element['type'] == 'op' || $element['type'] == 'cnj' ) + { + $right = array_pop( $exprStack ); + $left = array_pop( $exprStack ); + $node = array( 'data'=>$element, 'count'=>2+$left['count']+$right['count'], 'right'=>$right, 'left'=>$left ); + $exprStack[] = $node; + } + else + { + Fatal( "Unexpected element type '".$element['type']."', value '".$element['value']."'" ); + } + } + if ( count($exprStack) != 1 ) + { + Fatal( "Expression stack has ".count($exprStack)." elements" ); + } + $exprTree = array_pop( $exprStack ); + return( $exprTree ); + } + return( false ); +} + +function _parseTreeToInfix( $node ) +{ + $expression = ''; + if ( isset($node) ) + { + if ( isset($node['left']) ) + { + if ( !empty($node['data']['bracket']) ) + $expression .= '( '; + $expression .= _parseTreeToInfix( $node['left'] ); + } + $expression .= $node['data']['value']." "; + if ( isset($node['right']) ) + { + $expression .= _parseTreeToInfix( $node['right'] ); + if ( !empty($node['data']['bracket']) ) + $expression .= ') '; + } + } + return( $expression ); +} + +function parseTreeToInfix( $tree ) +{ + return( _parseTreeToInfix( $tree ) ); +} + +function _parseTreeToSQL( $node, $cbr=false ) +{ + $expression = ''; + if ( $node ) + { + if ( isset($node['left']) ) + { + if ( !empty($node['data']['bracket']) ) + $expression .= '( '; + $expression .= _parseTreeToSQL( $node['left'] ); + } + $inExpr = $node['data']['type'] == 'op' && ($node['data']['value'] == '=[]' || $node['data']['value'] == '![]'); + $expression .= $node['data']['sqlValue']; + if ( !$inExpr ) + $expression .= ' '; + if ( $cbr ) + $expression .= ') '; + if ( isset($node['right']) ) + { + $expression .= _parseTreeToSQL( $node['right'], $inExpr ); + if ( !empty($node['data']['bracket']) ) + $expression .= ') '; + } + } + return( $expression ); +} + +function parseTreeToSQL( $tree ) +{ + return( _parseTreeToSQL( $tree ) ); +} + +function _parseTreeToFilter( $node, &$terms, &$level ) +{ + $elements = array(); + if ( $node ) + { + if ( isset($node['left']) ) + { + if ( !empty($node['data']['bracket']) ) + $terms[$level]['obr'] = 1; + _parseTreeToFilter( $node['left'], $terms, $level ); + } + if ( $node['data']['type'] == 'cnj' ) + { + $level++; + } + $terms[$level][$node['data']['type']] = $node['data']['value']; + if ( isset($node['right']) ) + { + _parseTreeToFilter( $node['right'], $terms, $level ); + if ( !empty($node['data']['bracket']) ) + $terms[$level]['cbr'] = 1; + } + } +} + +function parseTreeToFilter( $tree ) +{ + $terms = array(); + if ( isset($tree) ) + { + $level = 0; + _parseTreeToFilter( $tree, $terms, $level ); + } + return( array( 'terms' => $terms ) ); +} + +function parseTreeToQuery( $tree ) +{ + $filter = parseTreeToFilter( $tree ); + parseFilter( $filter, false, '&' ); + return( $filter['query'] ); +} + +function _drawTree( $node, $level ) +{ + if ( isset($node['left']) ) + { + _drawTree( $node['left'], $level+1 ); + } + echo str_repeat( ".", $level*2 ).$node['data']['value']."
"; + if ( isset($node['right']) ) + { + _drawTree( $node['right'], $level+1 ); + } +} + +function drawTree( $tree ) +{ + _drawTree( $tree, 0 ); +} + +function _extractDatetimeRange( &$node, &$minTime, &$maxTime, &$expandable, $subOr ) +{ + $pruned = $leftPruned = $rightPruned = false; + if ( $node ) + { + if ( isset($node['left']) && isset($node['right']) ) + { + if ( $node['data']['type'] == 'cnj' && $node['data']['value'] == 'or' ) + { + $subOr = true; + } + elseif ( !empty($node['left']['data']['dtAttr']) ) + { + if ( $subOr ) + { + $expandable = false; + } + elseif ( $node['data']['type'] == 'op' ) + { + if ( $node['data']['value'] == '>' || $node['data']['value'] == '>=' ) + { + if ( !$minTime || $minTime > $node['right']['data']['sqlValue'] ) + { + $minTime = $node['right']['data']['value']; + return( true ); + } + } + if ( $node['data']['value'] == '<' || $node['data']['value'] == '<=' ) + { + if ( !$maxTime || $maxTime < $node['right']['data']['sqlValue'] ) + { + $maxTime = $node['right']['data']['value']; + return( true ); + } + } + } + else + { + Fatal( "Unexpected node type '".$node['data']['type']."'" ); + } + return( false ); + } + + $leftPruned = _extractDatetimeRange( $node['left'], $minTime, $maxTime, $expandable, $subOr ); + $rightPruned = _extractDatetimeRange( $node['right'], $minTime, $maxTime, $expandable, $subOr ); + + if ( $leftPruned && $rightPruned ) + { + $pruned = true; + } + elseif ( $leftPruned ) + { + $node = $node['right']; + } + elseif ( $rightPruned ) + { + $node = $node['left']; + } + } + } + return( $pruned ); +} + +function extractDatetimeRange( &$tree, &$minTime, &$maxTime, &$expandable ) +{ + $minTime = ""; + $maxTime = ""; + $expandable = true; + + _extractDateTimeRange( $tree, $minTime, $maxTime, $expandable, false ); +} + +function appendDatetimeRange( &$tree, $minTime, $maxTime=false ) +{ + $attrNode = array( 'data'=>array( 'type'=>'attr', 'value'=>'DateTime', 'sqlValue'=>'E.StartTime', 'dtAttr'=>true ), 'count'=>0 ); + $valNode = array( 'data'=>array( 'type'=>'val', 'value'=>$minTime, 'sqlValue'=>$minTime ), 'count'=>0 ); + $opNode = array( 'data'=>array( 'type'=>'op', 'value'=>'>=', 'sqlValue'=>'>=' ), 'count'=>2, 'left'=>$attrNode, 'right'=>$valNode ); + if ( isset($tree) ) + { + $cnjNode = array( 'data'=>array( 'type'=>'cnj', 'value'=>'and', 'sqlValue'=>'and' ), 'count'=>2+$tree['count']+$opNode['count'], 'left'=>$tree, 'right'=>$opNode ); + $tree = $cnjNode; + } + else + { + $tree = $opNode; + } + + if ( $maxTime ) + { + $attrNode = array( 'data'=>array( 'type'=>'attr', 'value'=>'DateTime', 'sqlValue'=>'E.StartTime', 'dtAttr'=>true ), 'count'=>0 ); + $valNode = array( 'data'=>array( 'type'=>'val', 'value'=>$maxTime, 'sqlValue'=>$maxTime ), 'count'=>0 ); + $opNode = array( 'data'=>array( 'type'=>'op', 'value'=>'<=', 'sqlValue'=>'<=' ), 'count'=>2, 'left'=>$attrNode, 'right'=>$valNode ); + $cnjNode = array( 'data'=>array( 'type'=>'cnj', 'value'=>'and', 'sqlValue'=>'and' ), 'count'=>2+$tree['count']+$opNode['count'], 'left'=>$tree, 'right'=>$opNode ); + $tree = $cnjNode; + } +} + +?> diff --git a/web/skins/bootstrap/js/Makefile.am b/web/skins/bootstrap/js/Makefile.am new file mode 100644 index 000000000..22f944d9e --- /dev/null +++ b/web/skins/bootstrap/js/Makefile.am @@ -0,0 +1,7 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/js + +dist_web_DATA = \ + skin.js \ + skin.js.php diff --git a/web/skins/bootstrap/js/jquery-1.4.2.min.js b/web/skins/bootstrap/js/jquery-1.4.2.min.js new file mode 100644 index 000000000..7c2430802 --- /dev/null +++ b/web/skins/bootstrap/js/jquery-1.4.2.min.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/web/skins/bootstrap/js/skin.js b/web/skins/bootstrap/js/skin.js new file mode 100644 index 000000000..b09a646da --- /dev/null +++ b/web/skins/bootstrap/js/skin.js @@ -0,0 +1,310 @@ +// +// ZoneMinder base static javascript file, $Date$, $Revision$ +// Copyright (C) 2001-2008 Philip Coombes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// + +// +// This file should only contain static JavaScript and no php. +// Use skin.js.php for JavaScript that need pre-processing +// + +// Javascript window sizes +var popupSizes = { + 'bandwidth': { 'width': 300, 'height': 120 }, + 'console': { 'width': 750, 'height': 312 }, + 'control': { 'width': 380, 'height': 480 }, + 'controlcaps': { 'width': 780, 'height': 320 }, + 'controlcap': { 'width': 400, 'height': 400 }, + 'cycle': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 62 }, + 'device': { 'width': 260, 'height': 150 }, + 'devices': { 'width': 400, 'height': 240 }, + 'donate': { 'width': 500, 'height': 280 }, + 'event': { 'addWidth': 108, 'minWidth': 496, 'addHeight': 230, minHeight: 540 }, + 'eventdetail': { 'width': 600, 'height': 220 }, + 'events': { 'width': 960, 'height': 780 }, + 'export': { 'width': 400, 'height': 340 }, + 'filter': { 'width': 720, 'height': 360 }, + 'filtersave': { 'width': 610, 'height': 120 }, + 'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 100 }, + 'frames': { 'width': 500, 'height': 600 }, + 'function': { 'width': 300, 'height': 92 }, + 'group': { 'width': 360, 'height': 180 }, + 'groups': { 'width': 440, 'height': 220 }, + 'image': { 'addWidth': 48, 'addHeight': 80 }, + 'log': { 'width': 1080, 'height': 720 }, + 'login': { 'width': 720, 'height': 480 }, + 'logout': { 'width': 260, 'height': 100 }, + 'monitor': { 'width': 450, 'height': 440 }, + 'monitorpreset':{ 'width': 440, 'height': 200 }, + 'monitorprobe': { 'width': 500, 'height': 240 }, + 'monitorselect':{ 'width': 160, 'height': 200 }, + 'montage': { 'width': -1, 'height': -1 }, + 'optionhelp': { 'width': 400, 'height': 320 }, + 'options': { 'width': 1000, 'height': 660 }, + 'preset': { 'width': 300, 'height': 120 }, + 'settings': { 'width': 220, 'height': 225 }, + 'state': { 'width': 370, 'height': 134 }, + 'stats': { 'width': 840, 'height': 200 }, + 'timeline': { 'width': 760, 'height': 540 }, + 'user': { 'width': 360, 'height': 420 }, + 'version': { 'width': 360, 'height': 140 }, + 'video': { 'width': 420, 'height': 360 }, + 'videoview': { 'addWidth': 48, 'addHeight': 80 }, + 'watch': { 'addWidth': 96, 'minWidth': 420, 'addHeight': 384 }, + 'zone': { 'addWidth': 450, 'addHeight': 200, 'minHeight': 450 }, + 'zones': { 'addWidth': 72, 'addHeight': 232 } +}; + +var popupOptions = "resizable,scrollbars,status=no"; + +function checkSize() { + if (window.outerHeight) { + var w = window.outerWidth; + var prevW = w; + var h = window.outerHeight; + var prevH = h; + if (h > screen.availHeight) + h = screen.availHeight; + if (w > screen.availWidth) + w = screen.availWidth; + if (w != prevW || h != prevH) + window.resizeTo(w,h); + } +} + +// Deprecated +function newWindow( url, name, width, height ) +{ + var windowId = window.open( url, name, popupOptions+",width="+width+",height="+height ); +} + +function getPopupSize( tag, width, height ) +{ + var popupSize = Object.clone( popupSizes[tag] ); + if ( !popupSize ) + { + Error( "Can't find window size for tag '"+tag+"'" ); + return( { 'width': 0, 'height': 0 } ); + } + if ( popupSize.width && popupSize.height ) + { + if ( width || height ) + Warning( "Ignoring passed dimensions "+width+"x"+height+" when getting popup size for tag '"+tag+"'" ); + return( popupSize ); + } + if ( popupSize.addWidth ) + { + popupSize.width = popupSize.addWidth; + if ( !width ) + Error( "Got addWidth but no passed width when getting popup size for tag '"+tag+"'" ); + else + popupSize.width += parseInt(width); + } + else if ( width ) + { + popupSize.width = width; + Error( "Got passed width but no addWidth when getting popup size for tag '"+tag+"'" ); + } + if ( popupSize.minWidth && popupSize.width < popupSize.minWidth ) + { + Warning( "Adjusting to minimum width when getting popup size for tag '"+tag+"'" ); + popupSize.width = popupSize.minWidth; + } + if ( popupSize.addHeight ) + { + popupSize.height = popupSize.addHeight; + if ( !height ) + Error( "Got addHeight but no passed height when getting popup size for tag '"+tag+"'" ); + else + popupSize.height += parseInt(height); + } + else if ( height ) + { + popupSize.height = height; + Error( "Got passed height but no addHeight when getting popup size for tag '"+tag+"'" ); + } + if ( popupSize.minHeight && popupSize.height < popupSize.minHeight ) + { + Warning( "Adjusting to minimum height when getting popup size for tag '"+tag+"'" ); + popupSize.height = popupSize.minHeight; + } + Debug( popupSize ); + return( popupSize ); +} + +function zmWindow() +{ + var zmWin = window.open( 'http://www.zoneminder.com', 'ZoneMinder' ); + zmWin.focus(); +} + +function createPopup( url, name, tag, width, height ) +{ + var popupSize = getPopupSize( tag, width, height ); + var popupDimensions = ""; + if ( popupSize.width > 0 ) + popupDimensions += ",width="+popupSize.width; + if ( popupSize.height > 0 ) + popupDimensions += ",height="+popupSize.height; + var popup = window.open( url, name, popupOptions+popupDimensions ); + popup.focus(); +} + +function createEventPopup( eventId, eventFilter, width, height ) +{ + var url = '?view=event&eid='+eventId; + if ( eventFilter ) + url += eventFilter; + var name = 'zmEvent'; + var popupSize = getPopupSize( 'event', width, height ); + var popup = window.open( url, name, popupOptions+",width="+popupSize.width+",height="+popupSize.height ); + popup.focus(); +} + +function createFramesPopup( eventId, width, height ) +{ + var url = '?view=frames&eid='+eventId; + var name = 'zmFrames'; + var popupSize = getPopupSize( 'frames', width, height ); + var popup = window.open( url, name, popupOptions+",width="+popupSize.width+",height="+popupSize.height ); + popup.focus(); +} + +function createFramePopup( eventId, frameId, width, height ) +{ + var url = '?view=frame&eid='+eventId+'&fid='+frameId; + var name = 'zmFrame'; + var popupSize = getPopupSize( 'frame', width, height ); + var popup = window.open( url, name, popupOptions+",width="+popupSize.width+",height="+popupSize.height ); + popup.focus(); +} + +function windowToFront() +{ + top.window.focus(); +} + +function closeWindow() +{ + top.window.close(); +} + +function refreshWindow() +{ + window.location.reload( true ); +} + +function refreshParentWindow() +{ + if ( window.opener ) + window.opener.location.reload( true ); +} + +//Shows a message if there is an error in the streamObj or the stream doesn't exist. Returns true if error, false otherwise. +function checkStreamForErrors( funcName, streamObj ) +{ + if ( !streamObj ) + { + Error( funcName+": stream object was null" ); + return true; + } + if ( streamObj.result == "Error" ) + { + Error( funcName+" stream error: "+streamObj.message ); + return true; + } + return false; +} + +function secsToTime( seconds ) +{ + var timeString = "--"; + if ( seconds < 60 ) + timeString = seconds.toString(); + else if ( seconds < 60*60 ) + { + var timeMins = parseInt(seconds/60); + var timeSecs = seconds%60; + if ( timeSecs < 10 ) + timeSecs = '0'+timeSecs.toString().substr( 0, 4 ); + else + timeSecs = timeSecs.toString().substr( 0, 5 ); + timeString = timeMins+":"+timeSecs; + } + else + { + var timeHours = parseInt(seconds/3600); + var timeMins = (seconds%3600)/60; + var timeSecs = seconds%60; + if ( timeMins < 10 ) + timeMins = '0'+timeMins.toString().substr( 0, 4 ); + else + timeMins = timeMins.toString().substr( 0, 5 ); + if ( timeSecs < 10 ) + timeSecs = '0'+timeSecs.toString().substr( 0, 4 ); + else + timeSecs = timeSecs.toString().substr( 0, 5 ); + timeString = timeHours+":"+timeMins+":"+timeSecs; + } + return( timeString ); +} + +function submitTab( tab ) +{ + var form = $('contentForm'); + form.action.value = ""; + form.tab.value = tab; + form.submit(); +} + +function configureDeleteButton( element ) +{ + var form = element.form; + var checked = element.checked; + if ( !checked ) + { + for ( var i = 0; i < form.elements.length; i++ ) + { + if ( form.elements[i].name == element.name ) + { + if ( form.elements[i].checked ) + { + checked = true; + break; + } + } + } + } + form.deleteBtn.disabled = !checked; +} + +function confirmDelete( message ) +{ + return( confirm( message?message:'Are you sure you wish to delete?' ) ); +} + +if ( refreshParent ) +{ + refreshParentWindow(); +} + +if ( focusWindow ) +{ + windowToFront(); +} +window.addEvent( 'domready', checkSize); + diff --git a/web/skins/bootstrap/js/skin.js.php b/web/skins/bootstrap/js/skin.js.php new file mode 100644 index 000000000..16b8f055e --- /dev/null +++ b/web/skins/bootstrap/js/skin.js.php @@ -0,0 +1,40 @@ + +var AJAX_TIMEOUT = ; + +var currentView = ''; +var thisUrl = ""; +var skinPath = ""; + +var canEditSystem = ; +var canViewSystem = ; + +var refreshParent = ; + +var focusWindow = ; + +var imagePrefix = ""; diff --git a/web/skins/bootstrap/lang/Makefile.am b/web/skins/bootstrap/lang/Makefile.am new file mode 100644 index 000000000..6a089b4fa --- /dev/null +++ b/web/skins/bootstrap/lang/Makefile.am @@ -0,0 +1,5 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/lang + +dist_web_DATA = # No files here diff --git a/web/skins/bootstrap/skin.php b/web/skins/bootstrap/skin.php new file mode 100644 index 000000000..c6af0dd59 --- /dev/null +++ b/web/skins/bootstrap/skin.php @@ -0,0 +1,66 @@ + diff --git a/web/skins/bootstrap/views/Makefile.am b/web/skins/bootstrap/views/Makefile.am new file mode 100644 index 000000000..58c72b78f --- /dev/null +++ b/web/skins/bootstrap/views/Makefile.am @@ -0,0 +1,55 @@ +AUTOMAKE_OPTIONS = gnu + +SUBDIRS = \ + css \ + js + +webdir = @WEB_PREFIX@/skins/classic/views + +dist_web_DATA = \ + bandwidth.php \ + blank.php \ + console.php \ + controlcap.php \ + controlcaps.php \ + control.php \ + controlpreset.php \ + cycle.php \ + device.php \ + devices.php \ + donate.php \ + error.php \ + eventdetail.php \ + event.php \ + events.php \ + export.php \ + filter.php \ + filtersave.php \ + frame.php \ + frames.php \ + function.php \ + group.php \ + groups.php \ + log.php \ + login.php \ + logout.php \ + Makefile.am \ + monitor.php \ + monitorpreset.php \ + monitorprobe.php \ + montage.php \ + none.php \ + optionhelp.php \ + options.php \ + postlogin.php \ + settings.php \ + state.php \ + stats.php \ + status.php \ + timeline.php \ + user.php \ + version.php \ + video.php \ + watch.php \ + zone.php \ + zones.php diff --git a/web/skins/bootstrap/views/bandwidth.php b/web/skins/bootstrap/views/bandwidth.php new file mode 100644 index 000000000..5c09ed446 --- /dev/null +++ b/web/skins/bootstrap/views/bandwidth.php @@ -0,0 +1,58 @@ + + +
+ +
+
+ + +

+

+
+ +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/blank.php b/web/skins/bootstrap/views/blank.php new file mode 100644 index 000000000..ac5c9caa7 --- /dev/null +++ b/web/skins/bootstrap/views/blank.php @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/web/skins/bootstrap/views/console.php b/web/skins/bootstrap/views/console.php new file mode 100644 index 000000000..001d56e2d --- /dev/null +++ b/web/skins/bootstrap/views/console.php @@ -0,0 +1,352 @@ + $SLANG['Events'], + "filter" => array( + "terms" => array( + ) + ), + ), + array( + "title" => $SLANG['Hour'], + "filter" => array( + "terms" => array( + array( "attr" => "DateTime", "op" => ">=", "val" => "-1 hour" ), + ) + ), + ), + array( + "title" => $SLANG['Day'], + "filter" => array( + "terms" => array( + array( "attr" => "DateTime", "op" => ">=", "val" => "-1 day" ), + ) + ), + ), + array( + "title" => $SLANG['Week'], + "filter" => array( + "terms" => array( + array( "attr" => "DateTime", "op" => ">=", "val" => "-7 day" ), + ) + ), + ), + array( + "title" => $SLANG['Month'], + "filter" => array( + "terms" => array( + array( "attr" => "DateTime", "op" => ">=", "val" => "-1 month" ), + ) + ), + ), + array( + "title" => $SLANG['Archived'], + "filter" => array( + "terms" => array( + array( "attr" => "Archived", "op" => "=", "val" => "1" ), + ) + ), + ), +); + +$running = daemonCheck(); +$status = $running?$SLANG['Running']:$SLANG['Stopped']; + +$group = NULL; +if ( ! empty($_COOKIE['zmGroup']) ) { + if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) ) + $groupIds = array_flip(explode( ',', $group['MonitorIds'] )); +} + +noCacheHeaders(); + +$maxWidth = 0; +$maxHeight = 0; +$cycleCount = 0; +$minSequence = 0; +$maxSequence = 1; +$seqIdList = array(); +$monitors = dbFetchAll( "select * from Monitors order by Sequence asc" ); +$displayMonitors = array(); +for ( $i = 0; $i < count($monitors); $i++ ) +{ + if ( !visibleMonitor( $monitors[$i]['Id'] ) ) + { + continue; + } + if ( $group && !empty($groupIds) && !array_key_exists( $monitors[$i]['Id'], $groupIds ) ) + { + continue; + } + $monitors[$i]['Show'] = true; + if ( empty($minSequence) || ($monitors[$i]['Sequence'] < $minSequence) ) + { + $minSequence = $monitors[$i]['Sequence']; + } + if ( $monitors[$i]['Sequence'] > $maxSequence ) + { + $maxSequence = $monitors[$i]['Sequence']; + } + $monitors[$i]['zmc'] = zmcStatus( $monitors[$i] ); + $monitors[$i]['zma'] = zmaStatus( $monitors[$i] ); + $monitors[$i]['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitors[$i]['Id']) ); + $counts = array(); + for ( $j = 0; $j < count($eventCounts); $j++ ) + { + $filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( "cnj" => "and", "attr" => "MonitorId", "op" => "=", "val" => $monitors[$i]['Id'] ) ); + parseFilter( $filter ); + $counts[] = "count(if(1".$filter['sql'].",1,NULL)) as EventCount$j"; + $monitors[$i]['eventCounts'][$j]['filter'] = $filter; + } + $sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?"; + $counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) ); + if ( $monitors[$i]['Function'] != 'None' ) + { + $cycleCount++; + $scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE ); + $scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE ); + if ( $maxWidth < $scaleWidth ) $maxWidth = $scaleWidth; + if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight; + } + if ( $counts ) $monitors[$i] = array_merge( $monitors[$i], $counts ); + $seqIdList[] = $monitors[$i]['Id']; + $displayMonitors[] = $monitors[$i]; +} +$lastId = 0; +$seqIdUpList = array(); +foreach ( $seqIdList as $seqId ) +{ + if ( !empty($lastId) ) + $seqIdUpList[$seqId] = $lastId; + else + $seqIdUpList[$seqId] = $seqId; + $lastId = $seqId; +} +$lastId = 0; +$seqIdDownList = array(); +foreach ( array_reverse($seqIdList) as $seqId ) +{ + if ( !empty($lastId) ) + $seqIdDownList[$seqId] = $lastId; + else + $seqIdDownList[$seqId] = $seqId; + $lastId = $seqId; +} + +$cycleWidth = $maxWidth; +$cycleHeight = $maxHeight; + +$eventsView = ZM_WEB_EVENTS_VIEW; +$eventsWindow = 'zm'.ucfirst(ZM_WEB_EVENTS_VIEW); + +$eventCount = 0; +for ( $i = 0; $i < count($eventCounts); $i++ ) +{ + $eventCounts[$i]['total'] = 0; +} +$zoneCount = 0; +foreach( $displayMonitors as $monitor ) +{ + for ( $i = 0; $i < count($eventCounts); $i++ ) + { + $eventCounts[$i]['total'] += $monitor['EventCount'.$i]; + } + $zoneCount += $monitor['ZoneCount']; +} + +$seqUpFile = getSkinFile( 'graphics/seq-u.gif' ); +$seqDownFile = getSkinFile( 'graphics/seq-d.gif' ); + +$versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':''; + +xhtmlHeaders( __FILE__, $SLANG['Console'] ); +?> + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
'.$SLANG['Fn'.$monitor['Function']].( empty($monitor['Enabled']) ? ', disabled' : '' ) .'', canEdit( 'Monitors' ) ) ?>'.$monitor['Device'].' ('.$monitor['Channel'].')', canEdit( 'Monitors' ) ) ?>'.preg_replace( '/^.*@/', '', $monitor['Host'] ).'', canEdit( 'Monitors' ) ) ?>'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'', canEdit( 'Monitors' ) ) ?>'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'', canEdit( 'Monitors' ) ) ?>'.$shortpath.'', canEdit( 'Monitors' ) ) ?>'.preg_replace( '/^.*\//', '', $monitor['Path'] ).'', canEdit( 'Monitors' ) ) ?> ', $monitor['Sequence']>$minSequence ) ?>', $monitor['Sequence']<$maxSequence ) ?> disabled="disabled"/>
+
+
+
+ + diff --git a/web/skins/bootstrap/views/control.php b/web/skins/bootstrap/views/control.php new file mode 100644 index 000000000..28845243d --- /dev/null +++ b/web/skins/bootstrap/views/control.php @@ -0,0 +1,79 @@ + + +
+ +
+
+ +
+
+
+ + diff --git a/web/skins/bootstrap/views/controlcap.php b/web/skins/bootstrap/views/controlcap.php new file mode 100644 index 000000000..29bb16cfa --- /dev/null +++ b/web/skins/bootstrap/views/controlcap.php @@ -0,0 +1,512 @@ + $SLANG['New'], + 'Type' => "Local", + 'Protocol' => "", + 'CanWake' => "", + 'CanSleep' => "", + 'CanReset' => "", + 'CanMove' => "", + 'CanMoveDiag' => "", + 'CanMoveMap' => "", + 'CanMoveAbs' => "", + 'CanMoveRel' => "", + 'CanMoveCon' => "", + 'CanPan' => "", + 'MinPanRange' => "", + 'MaxPanRange' => "", + 'MinPanStep' => "", + 'MaxPanStep' => "", + 'HasPanSpeed' => "", + 'MinPanSpeed' => "", + 'MaxPanSpeed' => "", + 'HasTurboPan' => "", + 'TurboPanSpeed' => "", + 'CanTilt' => "", + 'MinTiltRange' => "", + 'MaxTiltRange' => "", + 'MinTiltStep' => "", + 'MaxTiltStep' => "", + 'HasTiltSpeed' => "", + 'MinTiltSpeed' => "", + 'MaxTiltSpeed' => "", + 'HasTurboTilt' => "", + 'TurboTiltSpeed' => "", + 'CanZoom' => "", + 'CanZoomAbs' => "", + 'CanZoomRel' => "", + 'CanZoomCon' => "", + 'MinZoomRange' => "", + 'MaxZoomRange' => "", + 'MinZoomStep' => "", + 'MaxZoomStep' => "", + 'HasZoomSpeed' => "", + 'MinZoomSpeed' => "", + 'MaxZoomSpeed' => "", + 'CanFocus' => "", + 'CanAutoFocus' => "", + 'CanFocusAbs' => "", + 'CanFocusRel' => "", + 'CanFocusCon' => "", + 'MinFocusRange' => "", + 'MaxFocusRange' => "", + 'MinFocusStep' => "", + 'MaxFocusStep' => "", + 'HasFocusSpeed' => "", + 'MinFocusSpeed' => "", + 'MaxFocusSpeed' => "", + 'CanIris' => "", + 'CanAutoIris' => "", + 'CanIrisAbs' => "", + 'CanIrisRel' => "", + 'CanIrisCon' => "", + 'MinIrisRange' => "", + 'MaxIrisRange' => "", + 'MinIrisStep' => "", + 'MaxIrisStep' => "", + 'HasIrisSpeed' => "", + 'MinIrisSpeed' => "", + 'MaxIrisSpeed' => "", + 'CanGain' => "", + 'CanAutoGain' => "", + 'CanGainAbs' => "", + 'CanGainRel' => "", + 'CanGainCon' => "", + 'MinGainRange' => "", + 'MaxGainRange' => "", + 'MinGainStep' => "", + 'MaxGainStep' => "", + 'HasGainSpeed' => "", + 'MinGainSpeed' => "", + 'MaxGainSpeed' => "", + 'CanWhite' => "", + 'CanAutoWhite' => "", + 'CanWhiteAbs' => "", + 'CanWhiteRel' => "", + 'CanWhiteCon' => "", + 'MinWhiteRange' => "", + 'MaxWhiteRange' => "", + 'MinWhiteStep' => "", + 'MaxWhiteStep' => "", + 'HasWhiteSpeed' => "", + 'MinWhiteSpeed' => "", + 'MaxWhiteSpeed' => "", + 'HasPresets' => "", + 'NumPresets' => "", + 'HasHomePreset' => "", + 'CanSetPresets' => "", + ); + } + $newControl = $control; +} + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['ControlCap']." - ".$newControl['Name'] ); +?> + +
+ +
+
    +$value ) +{ + if ( $tab == $name ) + { +?> +
  • + +
  • + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$SLANG['Local'], 'Remote'=>$SLANG['Remote'], 'Ffmpeg'=>$SLANG['Ffmpeg'], 'Libvlc'=>$SLANG['Libvlc'], 'cURL'=>"cURL"); +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked">
checked="checked"/>
checked="checked"/>
checked="checked">
checked="checked"/>
checked="checked"/>
checked="checked">
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked">
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/controlcaps.php b/web/skins/bootstrap/views/controlcaps.php new file mode 100644 index 000000000..4007caa79 --- /dev/null +++ b/web/skins/bootstrap/views/controlcaps.php @@ -0,0 +1,89 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
disabled="disabled"/>
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/controlpreset.php b/web/skins/bootstrap/views/controlpreset.php new file mode 100644 index 000000000..7928f6e69 --- /dev/null +++ b/web/skins/bootstrap/views/controlpreset.php @@ -0,0 +1,70 @@ + + +
+ +
+
+ + + + + +

+

+
+ +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/css/Makefile.am b/web/skins/bootstrap/views/css/Makefile.am new file mode 100644 index 000000000..39c270cf7 --- /dev/null +++ b/web/skins/bootstrap/views/css/Makefile.am @@ -0,0 +1,31 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/views/css + +dist_web_DATA = \ + console.css \ + controlcaps.css \ + control.css \ + devices.css \ + event.css \ + events.css \ + export.css \ + filter.css \ + frame.css \ + frames.css \ + groups.css \ + log.css \ + monitor.css \ + montage_2wide.css \ + montage_3wide50enlarge.css \ + montage_3wide.css \ + montage_4wide.css \ + montage.css \ + montage_freeform.css \ + options.css \ + stats.css \ + timeline.css \ + timeline.css.php \ + video.css \ + watch.css \ + zone.css diff --git a/web/skins/bootstrap/views/css/console.css b/web/skins/bootstrap/views/css/console.css new file mode 100644 index 000000000..49920402a --- /dev/null +++ b/web/skins/bootstrap/views/css/console.css @@ -0,0 +1,97 @@ +#systemTime { + float: left; +} + +#title { + margin: 0 auto; + text-align: center; + width: 50%; +} + +#systemStats { + float: right; +} + +#monitorSummary { + float: left; + text-align: left; + width: 20%; +} + +#devices { + float: left; +} + +#loginBandwidth { + margin: 0 auto; + text-align: center; + width: 40%; +} + +#cycleMontage { + float: right; +} + +#options { + float: right; + text-align: right; + width: 20%; +} + +#consoleTable { + width: 100%; +} + +#consoleTable tr.highlight { + background-color: #eeeeee; +} + +#consoleTable thead th { + padding-bottom: 4px; + vertical-align: middle; +} + +#consoleTable tfoot td { + padding-top: 4px; + vertical-align: middle; +} + +#consoleTable th,td { + height: 16px; + text-align: left; +} + +#consoleTable .colOrder { + text-align: center; +} + +#consoleTable .colMark { + width: 32px; + text-align: center; +} + +#consoleTable .colEvents { + text-align: right; +} + +#consoleTable .colZones { + text-align: right; +} + +#consoleTable .colLeftButtons { + text-align: left; +} + +#consoleTable .colLeftButtons input { + margin-right: 24px; +} + +#consoleTable .colRightButtons { + text-align: right; + padding-right: 8px; +} + +#consoleTable .colRightButtons input { + margin: 0 8px; +} + diff --git a/web/skins/bootstrap/views/css/control.css b/web/skins/bootstrap/views/css/control.css new file mode 100644 index 000000000..0096ffcd7 --- /dev/null +++ b/web/skins/bootstrap/views/css/control.css @@ -0,0 +1 @@ +@import url(../../css/control.css); diff --git a/web/skins/bootstrap/views/css/controlcaps.css b/web/skins/bootstrap/views/css/controlcaps.css new file mode 100644 index 000000000..1a2783fd7 --- /dev/null +++ b/web/skins/bootstrap/views/css/controlcaps.css @@ -0,0 +1,3 @@ +#content table.major .colCanMove, #content table.major .colCanZoom, #content table.major .colCanFocus, #content table.major .colCanIris, #content table.major .colCanWhiteBal, #content table.major .colHasPresets { + text-align: center; +} diff --git a/web/skins/bootstrap/views/css/devices.css b/web/skins/bootstrap/views/css/devices.css new file mode 100644 index 000000000..6015985d0 --- /dev/null +++ b/web/skins/bootstrap/views/css/devices.css @@ -0,0 +1,4 @@ +input.set { + border: 1px #7F7FB2 dashed; +} + diff --git a/web/skins/bootstrap/views/css/event.css b/web/skins/bootstrap/views/css/event.css new file mode 100644 index 000000000..995a06c1d --- /dev/null +++ b/web/skins/bootstrap/views/css/event.css @@ -0,0 +1,232 @@ +#dataBar { + width: 100%; + margin: 2px auto; + text-align: center; +} + +#dataBar #dataTable { + width: 100%; +} + +#dataBar #dataTable td { + text-align: center; + padding: 2px; +} + +#menuBar1 { + width: 100%; + height: 1.5em; + padding: 3px 0; + text-align: center; + clear: both; +} + +#menuBar1 #nameControl { + float: left; +} + +#menuBar1 #nameControl #eventName { + margin-right: 4px; +} + +#menuBar1 #replayControl { + float: right; + margin-left: 8px; +} + +#menuBar1 #scaleControl { + float: right; + margin-left: 8px; +} + +#menuBar2 { + width: 100%; + height: 1.2em; + padding: 3px 0; + margin-bottom: 4px; +} + +#menuBar2 div { + text-align: left; + float: left; + padding: 0 12px; +} + +#menuBar2 #closeWindow { + float: right; + text-align: right; +} + +#imageFeed { + text-align: center; +} + +#monitorStatus { + width: 100%; + margin-top: 3px; + margin-bottom: 2px; + text-align: center; +} + +#monitorStatus #enableAlarms { + position: absolute; + left: 4px; +} + +#monitorStatus #forceAlarm { + position: absolute; + right: 4px; +} + +#monitorStatus #monitorState { +} + +#dvrControls { + margin-top: 3px; + margin-bottom: 2px; + text-align: center; +} + +#dvrControls input { + height: 20px; + width: 28px; + padding-bottom: 3px; + margin: 0 3px; +} + +#dvrControls input[disabled=disabled] { + color: #aaaaaa; +} + +#dvrControls input.active { + border: 1px solid blue; +} + +#dvrControls input.inactive { + border: 1px solid green; +} + +#dvrControls input.unavail { + border: 1px solid red; +} + +#replayStatus { + margin: 3px 0 2px; + text-align: center; + clear: both; +} + +#replayStatus > span { + padding: 0 4px; +} + +#progressBar { + position: relative; + border: 1px solid #666666; + height: 15px; + margin: 0 auto; +} + +#progressBar .progressBox { + position: absolute; + top: 0px; + left: 0px; + height: 15px; + background: #eeeeee; + border-left: 1px solid #999999; +} + +#progressBar .complete { + background: #aaaaaa; +} + +#eventStills { + width: 100%; + position: relative; +} + +#eventThumbsPanel { + position: relative; + width: 100%; + margin: 4px auto; + z-index: 1; +} + +#eventThumbs { + margin: 0 auto; + width: 100%; + overflow: hidden; + height: 300px; +} + +#eventThumbs img { + height: 25px; /* HACK - Although this is pixels it will be interpreted as a scale %ge, so 25px = 25% scaling for thumbnails */ + margin: 2px; + background-color: #dddddd; +} + +#eventThumbs img.placeholder { + /* width: 100px; */ +} + +#eventThumbs img.selected { +} + +#eventImagePanel { + position: absolute; + z-index: 10; +} + +#eventImageFrame { + border: 2px solid gray; + background-color: white; + padding: 4px; +} + +#eventImage { +} + +#eventImageBar { + margin-top: 2px; +} + +#eventImageStats { + float: left; +} + +#eventImageData { + margin: 0 auto; + padding-top: 2px; +} + +#eventImageClose { + float: right; +} + +#eventImageNav { + position: relative; +} + +#eventImageNav input { + width: 32px; + font-size: 16px; +} + +#thumbsSliderPanel { + width: 400px; + margin: 4px auto 0; + background: #888888; + padding: 1px; +} + +#thumbsSlider { + width: 400px; + height: 10px; + background: #dddddd; +} + +#thumbsKnob { + width: 8px; + height: 10px; + background-color: #444444; +} diff --git a/web/skins/bootstrap/views/css/events.css b/web/skins/bootstrap/views/css/events.css new file mode 100644 index 000000000..5726e904d --- /dev/null +++ b/web/skins/bootstrap/views/css/events.css @@ -0,0 +1,42 @@ +#controls { + height: 16px; + width: 100%; + text-align: center; + margin: 0 auto; + position: relative; +} + +#controls a { + width: 32%; +} + +#controls #refreshLink { + position: absolute; + left: 0%; + text-align: left; +} + +#controls #filterLink { + position: absolute; + left: 34%; + text-align: center; +} + +#controls #timelineLink { + position: absolute; + left: 68%; + text-align: right; +} + +#contentTable.major .colTime { + white-space: nowrap; +} + +#contentTable.major .colId, #contentTable.major .colDuration, #contentTable.major .colFrames, #contentTable.major .colAlarmFrames, #contentTable.major .colTotScore, #contentTable.major .colMaxScore, #contentTable.major .colAvgScore { + text-align: center; +} + +#contentTable.major td.colDuration { + text-align: right; + padding-right: 8px; +} diff --git a/web/skins/bootstrap/views/css/export.css b/web/skins/bootstrap/views/css/export.css new file mode 100644 index 000000000..e22851ca0 --- /dev/null +++ b/web/skins/bootstrap/views/css/export.css @@ -0,0 +1,15 @@ +#contentTable + input { + margin-top: 6px; +} + +#contentTable th, #contentTable td { + white-space: nowrap; +} + +#exportProgress { + margin: 8px auto 4px; +} + +#downloadLink { + margin-top: 8px; +} diff --git a/web/skins/bootstrap/views/css/filter.css b/web/skins/bootstrap/views/css/filter.css new file mode 100644 index 000000000..2287cfea2 --- /dev/null +++ b/web/skins/bootstrap/views/css/filter.css @@ -0,0 +1,25 @@ +#filterSelector { +} + +table.filterTable { + width: 100%; +} + +#fieldsTable td { + height: 16px; +} + +#fieldsTable input[type=button] { + width: 1.6em; + margin-left: 2px; + text-align: center; +} + +#sortTable input[type=text] { + margin-right: 4px; +} + +#actionsTable input[type=text] { + margin-left: 4px; +} + diff --git a/web/skins/bootstrap/views/css/frame.css b/web/skins/bootstrap/views/css/frame.css new file mode 100644 index 000000000..2c7789349 --- /dev/null +++ b/web/skins/bootstrap/views/css/frame.css @@ -0,0 +1,30 @@ +#controls { + width: 80%; + text-align: center; + margin: 0 auto; +} + +#controls a { + width: 40px; + margin-left: -20px; +} + +#firstLink { + position: absolute; + left: 13%; +} + +#prevLink { + position: absolute; + left: 37%; +} + +#nextLink { + position: absolute; + left: 63%; +} + +#lastLink { + position: absolute; + left: 87%; +} diff --git a/web/skins/bootstrap/views/css/frames.css b/web/skins/bootstrap/views/css/frames.css new file mode 100644 index 000000000..249fa3751 --- /dev/null +++ b/web/skins/bootstrap/views/css/frames.css @@ -0,0 +1,15 @@ +#contentTable.major .colId, #contentTable.major .colType, #contentTable.major .colTimeStamp, #contentTable.major .colTimeDelta, #contentTable.major .colScore { + text-align: center; +} + +tr.alarm { + background-color: #fa8072; +} + +tr.bulk { + background-color: #cccccc; +} + +tr.normal { + background-color: #ffffff; +} diff --git a/web/skins/bootstrap/views/css/groups.css b/web/skins/bootstrap/views/css/groups.css new file mode 100644 index 000000000..64f5013de --- /dev/null +++ b/web/skins/bootstrap/views/css/groups.css @@ -0,0 +1,6 @@ +#contentTable .colSelect { + text-align: center; +} + +#contentTable .colSelect input { +} diff --git a/web/skins/bootstrap/views/css/log.css b/web/skins/bootstrap/views/css/log.css new file mode 100644 index 000000000..44f309b9b --- /dev/null +++ b/web/skins/bootstrap/views/css/log.css @@ -0,0 +1,53 @@ +#logSummary { + margin: 4px auto 0; + border-collapse: collapse; +} + +#logSummary tr { + margin: 0; + padding: 0; +} + +#logSummary td { + border: 1px solid #7f7fb2; + padding: 0 6px; + text-align: center; + font-size: 10px; + line-height: 15px; +} + +tr.log-fat td { + background-color:#ffcccc; + font-weight: bold; +} + +tr.log-err td { + background-color:#ffcccc; +} + +tr.log-war td { + background-color: #ffe4b5; +} + +tr.log-dbg td { + color: #666666; + font-style: italic; +} + +#exportLog label { + vertical-align: middle; +} + +#exportLog input[type=radio] { + margin-right: 4px; + vertical-align: middle; +} + +#exportError { + display: none; + color: #dc143c; + margin-bottom: 8px; +} + +#exportErrorText { +} diff --git a/web/skins/bootstrap/views/css/monitor.css b/web/skins/bootstrap/views/css/monitor.css new file mode 100644 index 000000000..7cac28fe1 --- /dev/null +++ b/web/skins/bootstrap/views/css/monitor.css @@ -0,0 +1,5 @@ +.swatch { + border: 1px solid black; + margin-left: 3px; + padding: 0px; +} diff --git a/web/skins/bootstrap/views/css/montage.css b/web/skins/bootstrap/views/css/montage.css new file mode 100644 index 000000000..1afd402a7 --- /dev/null +++ b/web/skins/bootstrap/views/css/montage.css @@ -0,0 +1,41 @@ +#header { + width: 99%; +} + +#layout { + margin-right: 10px; +} + +#content { + width: 99%; +} + +#monitors .alarm { + color: #ff0000; +} + +#monitors .alert { + color: #ffa500; +} + +#monitors .imageFeed { + text-align: center; + vertical-align: middle; +} + +#monitors .imageFeed img.idle { + border: 2px solid #ffffff; +} + +#monitors .imageFeed img.alarm { + border: 2px solid #ff0000; +} + +#monitors .imageFeed img.alert { + border: 2px solid #ffa500; +} + +#monitors .monitorState { + margin: 2px auto; + text-align: center; +} diff --git a/web/skins/bootstrap/views/css/montage_2wide.css b/web/skins/bootstrap/views/css/montage_2wide.css new file mode 100644 index 000000000..b0fa77298 --- /dev/null +++ b/web/skins/bootstrap/views/css/montage_2wide.css @@ -0,0 +1,30 @@ +#monitors { + width: 100%; + margin: 0 auto; + text-align: center; +} + +#monitors .monitorFrame { + padding: 1px; + float: left; +} + +#monitors .monitor { +} + +#monitorFrame0, #monitorFrame2, #monitorFrame4, #monitorFrame6, #monitorFrame8, #monitorFrame10, #monitorFrame12, #monitorFrame14 { + width: 49%; + clear: both; +} + +#monitor0, #monitor2, #monitor4, #monitor6, #monitor8, #monitor10, #monitor12, #monitor14 { + float: right; +} + +#monitorFrame1, #monitorFrame3, #monitorFrame5, #monitorFrame7, #monitorFrame9, #monitorFrame11, #monitorFrame13, #monitorFrame15 { + width: 49%; +} + +#monitor1, #monitor3, #monitor5, #monitor7, #monitor9, #monitor11, #monitor13, #monitor15 { + float: left; +} diff --git a/web/skins/bootstrap/views/css/montage_3wide.css b/web/skins/bootstrap/views/css/montage_3wide.css new file mode 100644 index 000000000..81f0c00ae --- /dev/null +++ b/web/skins/bootstrap/views/css/montage_3wide.css @@ -0,0 +1,37 @@ +#monitors { + width: 100%; + margin: 0 auto; + text-align: center; +} + +#monitors .monitorFrame { + padding: 1px; + float: left; + width: 33%; +} + +#monitors .monitor { + text-align: center; +} + +#monitorFrame0, #monitorFrame3, #monitorFrame6, #monitorFrame9, #monitorFrame12, #monitorFrame15 { + clear: both; +} + +#monitor0, #monitor3, #monitor6, #monitor9, #monitor12, #monitor15 { + float: right; +} + +#monitorFrame1, #monitorFrame4, #monitorFrame7, #monitorFrame10, #monitorFrame13, #monitorFrame16 { + text-align: center; +} + +#monitor1, #monitor4, #monitor7, #monitor10, #monitor13, #monitor16 { +} + +#monitorFrame2, #monitorFrame5, #monitorFrame8, #monitorFrame11, #monitorFrame14, #monitorFrame17 { +} + +#monitor2, #monitor5, #monitor8, #monitor11, #monitor14, #monitor17 { + float: left; +} diff --git a/web/skins/bootstrap/views/css/montage_3wide50enlarge.css b/web/skins/bootstrap/views/css/montage_3wide50enlarge.css new file mode 100644 index 000000000..59bedd9ba --- /dev/null +++ b/web/skins/bootstrap/views/css/montage_3wide50enlarge.css @@ -0,0 +1,74 @@ +#monitors { + width: 100%; + margin: 0 auto; + text-align: center; +} + +#monitors .monitorFrame { + float: left; + padding: 1px; +} + +#monitors .monitor { + text-align: center; +} + +#monitorFrame0, #monitorFrame3, #monitorFrame6, #monitorFrame9, #monitorFrame12, #monitorFrame15 { + width: 32%; + text-align: right; + clear: both; +} + +#monitor0, #monitor3, #monitor6, #monitor9, #monitor12, #monitor15 { + margin-left: auto; + margin-right: 0; +} + +#monitorFrame1, #monitorFrame4, #monitorFrame7, #monitorFrame10, #monitorFrame13, #monitorFrame16 { + width: 32%; + text-align: center; +} + +#monitor1, #monitor4, #monitor7, #monitor10, #monitor13, #monitor16 { + margin-left: auto; + margin-right: auto; +} + +#monitorFrame2, #monitorFrame5, #monitorFrame8, #monitorFrame11, #monitorFrame14, #monitorFrame17 { + width: 32%; + text-align: left; +} + +#monitor2, #monitor5, #monitor8, #monitor11, #monitor14, #monitor17 { + margin-left: 0; + margin-right: auto; +} + +#monitors .imageFeed img { + width: 100%; + height: 100%; +} + +#monitors .monitorFrame > div.alarm, #monitors .monitorFrame > div.alert { + position: absolute; + width: 96%; + left: 2%; + top: 72px; +} + +#monitors .monitorFrame > div.alert { + z-index: 100; +} + +#monitors .monitorFrame > div.alarm { + z-index: 200; +} + +#monitors .monitorFrame div.alarm, #monitors .monitorFrame div.alert { + font-size: 140%; + line-height: 160%; +} + +#monitors .monitorFrame div.monitorState { + text-align: center; +} diff --git a/web/skins/bootstrap/views/css/montage_4wide.css b/web/skins/bootstrap/views/css/montage_4wide.css new file mode 100644 index 000000000..4e5b7bc49 --- /dev/null +++ b/web/skins/bootstrap/views/css/montage_4wide.css @@ -0,0 +1,44 @@ +#monitors { + width: 100%; + margin: 0 auto; + text-align: center; +} + +#monitors .monitorFrame { + padding: 1px; + float: left; + width: 24.5%; +} + +#monitors .monitor { + text-align: center; +} + +#monitorFrame0, #monitorFrame4, #monitorFrame8, #monitorFrame12, #monitorFrame16, #monitorFrame20 { + clear: both; +} + +#monitor0, #monitor4, #monitor8, #monitor12, #monitor16, #monitor20 { + float: right; +} + +#monitorFrame1, #monitorFrame5, #monitorFrame9, #monitorFrame13, #monitorFrame17, #monitorFrame21 { + text-align: center; +} + +#monitor1, #monitor5, #monitor9, #monitor13, #monitor17, #monitor21 { +} + +#monitorFrame2, #monitorFrame6, #monitorFrame10, #monitorFrame14, #monitorFrame18, #monitorFrame22 { + text-align: center; +} + +#monitor2, #monitor6, #monitor10, #monitor14, #monitor18, #monitor22 { +} + +#monitorFrame3, #monitorFrame7, #monitorFrame11, #monitorFrame15, #monitorFrame19, #monitorFrame23 { +} + +#monitor3, #monitor7, #monitor11, #monitor15, #monitor19, #monitor23 { + float: left; +} diff --git a/web/skins/bootstrap/views/css/montage_freeform.css b/web/skins/bootstrap/views/css/montage_freeform.css new file mode 100644 index 000000000..da6a4bb22 --- /dev/null +++ b/web/skins/bootstrap/views/css/montage_freeform.css @@ -0,0 +1,9 @@ +#monitors { + margin: 0 auto; + text-align: center; +} + +#monitors .monitorFrame { + float: left; + padding: 1px; +} diff --git a/web/skins/bootstrap/views/css/options.css b/web/skins/bootstrap/views/css/options.css new file mode 100644 index 000000000..f2635edea --- /dev/null +++ b/web/skins/bootstrap/views/css/options.css @@ -0,0 +1,24 @@ +input.small { + width: 6em; +} + +input.medium { + width: 9em; +} + +input.large { + width: 20em; +} + +#contentTable.optionTable th, #contentTable.optionTable td { + vertical-align: top; +} + +#contentTable.userTable th, #contentTable.userTable td { + text-align: center; +} + +#contentTable.userTable .colMonitor, #contentTable.userTable .colUsername { + text-align: left; +} + diff --git a/web/skins/bootstrap/views/css/plugin.css b/web/skins/bootstrap/views/css/plugin.css new file mode 100644 index 000000000..040e26558 --- /dev/null +++ b/web/skins/bootstrap/views/css/plugin.css @@ -0,0 +1,20 @@ +#settingsPanel { + float: left; + margin: 0 2px; +} + +#pluginSettings { + border-collapse: collapse; +} + +#pluginSettings th, #pluginSettings td { + border: 1px solid #7f7fb2; + padding: 3px; + text-align: left; +} + +#pluginSettings th[scope=row] { + padding: 4px 3px 3px; + vertical-align: top; + white-space: nowrap; +} diff --git a/web/skins/bootstrap/views/css/stats.css b/web/skins/bootstrap/views/css/stats.css new file mode 100644 index 000000000..c47e85e3a --- /dev/null +++ b/web/skins/bootstrap/views/css/stats.css @@ -0,0 +1,9 @@ +#contentTable.major .colZone, #contentTable.major .colPixelDiff, #contentTable.major .colAlarmPx, #contentTable.major .colFilterPx, #contentTable.major .colBlobPx, #contentTable.major .colBlobs, #contentTable.major .colBlobSizes, #contentTable.major .colAlarmLimits, #contentTable.major .colScore { + + text-align: center; +} + +#contentTable.major .rowNoStats { + text-align: center; + padding: 20px; +} diff --git a/web/skins/bootstrap/views/css/timeline.css b/web/skins/bootstrap/views/css/timeline.css new file mode 100644 index 000000000..6b66ea4e1 --- /dev/null +++ b/web/skins/bootstrap/views/css/timeline.css @@ -0,0 +1,222 @@ +#content { + position: relative; + text-align: center; + border: 1px solid #666666; + margin: 0 auto; +} + +#title { + position: relative; + margin: 0 auto; + color: #016A9D; + height: 30px; + font-size: 13px; + font-weight: bold; + line-height: 20px; +} + +#listLink { + position: absolute; + top: 5px; + left: 20px; + height: 15px; +} + +#closeLink { + position: absolute; + top: 5px; + right: 20px; + height: 15px; +} + +#topPanel { + position: relative; + height: 220px; + margin: 4px auto 6px; +} + +#topPanel #imagePanel +{ + width: 50%; + float: left; + text-align: right; +} + +#topPanel #image { + float: right; + margin: 0 auto; + width: 90%; + text-align: right; + margin-right: 2px; + background-color: #eeeeee; + border: 1px solid #c8c8c8; +} + +#topPanel #image img { + float: left; + top: 0px; + background-color: #f8f8f8; + width: 100%; +} + +#topPanel #dataPanel { + width: 45%; + float: left; + text-align: left; + margin-left: 2px; +} + +#topPanel #textPanel { + text-align: left; + width: 100%; + height: 140px; + margin: 0 auto; + color: #016A9D; + font-size: 11px; + font-weight: bold; + line-height: 14px; + background-color: #eeeeee; + border: 1px solid #c8c8c8; + padding: 2px; +} + +#topPanel #navPanel { + width: 100%; + height: 70px; + margin: 4px auto; +} + +#topPanel #navPanel input { + background-color: #eeeeee; + border: 1px solid #c8c8c8; + padding: 5px; +} + +#chartPanel { + position: relative; + margin: 0 auto; +} + +#chartPanel #chart { + position: relative; + border: 1px solid black; + margin: 0 auto; + z-index: 0; +} + +#chartPanel #activity { + position: absolute; + text-align: center; + left: 0px; + border-bottom: 1px solid #cccccc; +} + +#chartPanel #activity div.activity { + position: absolute; + bottom: 0px; + z-index: 3; + width: 1px; +} + +#chartPanel .events { + position: absolute; + text-align: center; + left: 0px; + background-color: #fcfcfc; + border-bottom: 1px solid black; +} + +#chartPanel .event { + position: absolute; + bottom: 0px; + z-index: 3; +} + +#chartLabels { + margin: 25px auto 0; + text-align: center; +} + +#range { + width: 30%; + margin: 0 auto; + color: #016A9D; + font-size: 11px; + font-weight: bold; + line-height: 20px; +} + +#key { + float: right; + margin-top: -4px; + text-align: right; +} + +span.keyEntry { +} + +img.keyBox { + position: relative; + border: 1px solid black; + width: 16px; + height: 16px; + top: 4px; + margin-left: 4px; +} + +div.majGridX { + position: absolute; + z-index: 1; + top: 0px; + width: 1px; + border-left: dotted 1px #cccccc; +} + +div.majTickX { + position: absolute; + bottom: -7px; + width: 1px; + height: 7px; + border-left: solid 1px black; +} + +div.majLabelX { + position: absolute; + text-align: center; + bottom: -20px; + width: 50px; + font-size: 9px; + font-weight: normal; +} + +div.majGridY { + position: absolute; + z-index: 1; + left: 0px; + height: 1px; + border-top: dotted 1px #cccccc; +} + +div.majTickY { + position: absolute; + left: -7px; + height: 1px; + width: 7px; + border-top: solid 1px black; +} + +div.majLabelY { + position: absolute; + text-align: right; + left: -30px; + width: 20px; + font-size: 9px; + font-weight: normal; +} + +div.zoom { + position: absolute; + z-index: 2; + bottom: 0px; +} + diff --git a/web/skins/bootstrap/views/css/timeline.css.php b/web/skins/bootstrap/views/css/timeline.css.php new file mode 100644 index 000000000..3bc75fbcf --- /dev/null +++ b/web/skins/bootstrap/views/css/timeline.css.php @@ -0,0 +1,77 @@ +.chartSize { + width: px; + height: px; +} + +.graphSize { + width: px; + height: px; +} + +.graphHeight { + height: px; +} + +.graphWidth { + width: px; +} + +.imageSize { + width: px; + height: px; +} + +.imageHeight { + height: px; +} + +.activitySize { + width: px; + height: px; +} + +.eventsSize { + width: px; + height: px; +} + +.eventsHeight { + height: px; +} + +#chartPanel .eventsPos { + top: px; +} + +#chartPanel .activityPos { + top: px; +} + +#chartPanel .eventsPos { + top: px; +} + +.monitorColour { + background-color: ; +} + diff --git a/web/skins/bootstrap/views/css/video.css b/web/skins/bootstrap/views/css/video.css new file mode 100644 index 000000000..7e9708f2c --- /dev/null +++ b/web/skins/bootstrap/views/css/video.css @@ -0,0 +1,19 @@ +#contentTable + input { + margin-top: 6px; +} + +#videoProgress { + margin: 8px auto 4px; +} + +#videoFilesHeader { + margin: 8px auto 4px; +} + +#videoNoFiles { + margin: 4px auto; +} + +#videoFile { + margin-bottom: 6px; +} diff --git a/web/skins/bootstrap/views/css/watch.css b/web/skins/bootstrap/views/css/watch.css new file mode 100644 index 000000000..82cfca234 --- /dev/null +++ b/web/skins/bootstrap/views/css/watch.css @@ -0,0 +1,134 @@ +@import url(../../css/control.css); + +#menuBar { + margin: 6px auto 4px; + text-align: center; +} + +#menuBar #monitorName { + float: left; +} + +#menuBar #closeControl { + float: right; +} + +#menuBar #menuControls { + margin: 0 auto; + width: 60%; +} + +#menuBar #menuControls #controlControl { + float: left; +} + +#menuBar #menuControls #eventsControl { + float: left; +} + +#menuBar #menuControls #settingsControl { + float: right; +} + +#menuBar #menuControls #scaleControl { + margin: 0 auto; +} + +#imageFeed{ + text-align: center; +} + +#monitorStatus { + margin: 4px auto; + text-align: center; +} + +#monitorStatus #enableDisableAlarms { + float: left; +} + +#monitorStatus #forceCancelAlarm { + float: right; +} + +#monitorStatus #monitorState { +} + +#dvrControls { + margin-top: 3px; + margin-bottom: 2px; + text-align: center; +} + +#dvrControls input { + height: 20px; + width: 28px; + padding-bottom: 3px; + margin: 0 3px; +} + +#dvrControls input[disabled] { + color: #aaaaaa; +} + +#dvrControls input.active { + border: 1px solid blue; +} + +#dvrControls input.inactive { + border: 1px solid green; +} + +#dvrControls input.unavail { + border: 1px solid red; +} + +#replayStatus { + margin: 3px 0 2px; + text-align: center; + clear: both; +} + +#replayStatus > span { + padding: 0 4px; +} + +#events { + margin: 0 auto; +} + +#eventList { + width: 100%; +} + +#eventList thead td { + font-weight: bold; +} + +#eventList th, #eventList td { + text-align: center; +} + +li { + display: inline; + list-style-type: none; +} + +span.alarm { + color: #DC143C; + font-weight: bold; +} + +span.alert { + color: #FF8C00; + font-weight: bold; +} + +#eventList tr.recent { + background-color: #B0E0E6; +} + +#eventList tr.highlight { + background-color: #DCDCDC; +} + diff --git a/web/skins/bootstrap/views/css/zone.css b/web/skins/bootstrap/views/css/zone.css new file mode 100644 index 000000000..2f6754275 --- /dev/null +++ b/web/skins/bootstrap/views/css/zone.css @@ -0,0 +1,95 @@ +#settingsPanel { + float: left; + margin: 0 2px; +} + +#zoneSettings { + border-collapse: collapse; +} + +#zoneSettings th, #zoneSettings td { + border: 1px solid #7f7fb2; + padding: 3px; + text-align: left; +} + +#zoneSettings th[scope=row] { + padding: 4px 3px 3px; + vertical-align: top; + white-space: nowrap; +} + +#definitionPanel { + float: left; + margin: 0 2px; + text-align: center; +} + +#definitionPanel input[type=submit], #definitionPanel input[type=submit] { + margin: 0 4px; +} + +#imagePanel { + position: relative; +} + +/* NB: The size of the imageFrame determines the area within which the markers + * may be moved. When adjusting the padding and margins of the imageFrame and + * the DIVs within it, test that the markers behave sensibly when dragged to + * the extreme edges of the imageFrame. */ +#imageFrame { + position: relative; + padding: 0 3px 3px 0; /* Compensate for negative margins in the markers just below. */ +} + +#imageFrame div { + position: absolute; + width: 7px; + height: 7px; + margin-left: -3px; + margin-top: -3px; + z-index: 5; +} + +#imageFrame div { + background-image: url(../../graphics/point-g.gif); +} + +#imageFrame div.highlight { + background-image: url(../../graphics/point-o.gif); +} + +#imageFrame div.active { + background-image: url(../../graphics/point-r.gif); +} + +#zonePoints { + margin: 8px 0; + border-collapse: collapse; +} + +#zonePoints td { + vertical-align: top; +} + +#zonePoints table { + border-collapse: collapse; +} + +#zonePoints table tr.highlight { + background-color: #f0e68c; +} + +#zonePoints table tr.active { + background-color: #ffa07a; +} + +#zonePoints table th, #zonePoints table td { + border: 1px solid #7f7fb2; + padding: 3px; + text-align: center; +} + +#zonePoints table a { + margin: 0 2px; +} diff --git a/web/skins/bootstrap/views/cycle.php b/web/skins/bootstrap/views/cycle.php new file mode 100644 index 000000000..95757c54c --- /dev/null +++ b/web/skins/bootstrap/views/cycle.php @@ -0,0 +1,128 @@ + + +
+ +
+
+ +
+
+
+ + diff --git a/web/skins/bootstrap/views/device.php b/web/skins/bootstrap/views/device.php new file mode 100644 index 000000000..a5d59096f --- /dev/null +++ b/web/skins/bootstrap/views/device.php @@ -0,0 +1,67 @@ + "", + "Name" => "New Device", + "KeyString" => "" + ); +} + +xhtmlHeaders( __FILE__, $SLANG['Device']." - ".$newDevice['Name'] ); +?> + +
+ +
+
+ + + + + + + + + + + + + + +
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/devices.php b/web/skins/bootstrap/views/devices.php new file mode 100644 index 000000000..15100a4cd --- /dev/null +++ b/web/skins/bootstrap/views/devices.php @@ -0,0 +1,86 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + +
'.validHtmlStr($device['Name']).' ('.validHtmlStr($device['KeyString']).')', canEdit( 'Devices' ) ) ?> onclick="switchDeviceOn( this, '' )"/> onclick="switchDeviceOff( this, '' )"/> disabled="disabled"/>
+
+ /> + + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/donate.php b/web/skins/bootstrap/views/donate.php new file mode 100644 index 000000000..34ee4efa3 --- /dev/null +++ b/web/skins/bootstrap/views/donate.php @@ -0,0 +1,65 @@ + $SLANG['DonateYes'], + "hour" => $SLANG['DonateRemindHour'], + "day" => $SLANG['DonateRemindDay'], + "week" => $SLANG['DonateRemindWeek'], + "month" => $SLANG['DonateRemindMonth'], + "never" => $SLANG['DonateRemindNever'], + "already" => $SLANG['DonateAlready'], +); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Donate'] ); +?> + +
+ +
+
+ + +

+ +

+

+ +

+
+ + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/error.php b/web/skins/bootstrap/views/error.php new file mode 100644 index 000000000..c18ae307e --- /dev/null +++ b/web/skins/bootstrap/views/error.php @@ -0,0 +1,43 @@ + + +
+ +
+

+ +

+

+ +

+

+ +

+
+
+ + diff --git a/web/skins/bootstrap/views/event.php b/web/skins/bootstrap/views/event.php new file mode 100644 index 000000000..3d06f4c9e --- /dev/null +++ b/web/skins/bootstrap/views/event.php @@ -0,0 +1,224 @@ + $SLANG['ReplaySingle'], + 'all' => $SLANG['ReplayAll'], + 'gapless' => $SLANG['ReplayGapless'], +); + +if ( isset( $_REQUEST['streamMode'] ) ) + $streamMode = validHtmlStr($_REQUEST['streamMode']); +else + $streamMode = canStream()?'stream':'stills'; + +if ( isset( $_REQUEST['replayMode'] ) ) + $replayMode = validHtmlStr($_REQUEST['replayMode']); +if ( isset( $_COOKIE['replayMode']) && preg_match('#^[a-z]+$#', $_COOKIE['replayMode']) ) + $replayMode = validHtmlStr($_COOKIE['replayMode']); +else { + $keys = array_keys( $replayModes ); + $replayMode = array_shift( $keys ); +} + +parseSort(); +parseFilter( $_REQUEST['filter'] ); +$filterQuery = $_REQUEST['filter']['query']; + +$panelSections = 40; +$panelSectionWidth = (int)ceil(reScale($event['Width'],$scale)/$panelSections); +$panelWidth = ($panelSections*$panelSectionWidth-1); + +$connkey = generateConnKey(); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Event'] ); +?> + +
+
+
+ + + + + + + + + +
s">/">//
+
+ + +
+
+ +
+

+ + + + + + + + + +

+
+ Mode:   + Rate: x + Progress: s + Zoom: x +
+ +
+ +
+
+ + diff --git a/web/skins/bootstrap/views/eventdetail.php b/web/skins/bootstrap/views/eventdetail.php new file mode 100644 index 000000000..e9aa9a5a5 --- /dev/null +++ b/web/skins/bootstrap/views/eventdetail.php @@ -0,0 +1,131 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/events.php b/web/skins/bootstrap/views/events.php new file mode 100644 index 000000000..46c3407fa --- /dev/null +++ b/web/skins/bootstrap/views/events.php @@ -0,0 +1,263 @@ + $limit ) +{ + $nEvents = $limit; +} +$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE); +if ( $pages > 1 ) { + if ( !empty($page) ) { + if ( $page < 0 ) + $page = 1; + if ( $page > $pages ) + $page = $pages; + } +} +if ( !empty($page) ) { + $limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE); + if ( empty( $limit ) ) + { + $limitAmount = ZM_WEB_EVENTS_PER_PAGE; + } + else + { + $limitLeft = $limit - $limitStart; + $limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft; + } + $eventsSql .= " limit $limitStart, $limitAmount"; +} elseif ( !empty( $limit ) ) { + $eventsSql .= " limit 0, ".$limit; +} + +$maxWidth = 0; +$maxHeight = 0; +$archived = false; +$unarchived = false; +$events = array(); +foreach ( dbFetchAll( $eventsSql ) as $event ) +{ + $events[] = $event; + $scale = max( reScale( SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE ); + $eventWidth = reScale( $event['Width'], $scale ); + $eventHeight = reScale( $event['Height'], $scale ); + if ( $maxWidth < $eventWidth ) $maxWidth = $eventWidth; + if ( $maxHeight < $eventHeight ) $maxHeight = $eventHeight; + if ( $event['Archived'] ) + $archived = true; + else + $unarchived = true; +} + +$maxShortcuts = 5; +$pagination = getPagination( $pages, $page, $maxShortcuts, $filterQuery.$sortQuery.'&limit='.$limit ); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Events'] ); + +?> + +
+ +
+
+ + + + + + + + +

+ +

+ + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
disabled="disabled"/>
' ) ?>  disabled="disabled"/>
+ +

+ +
+ + + + + + +
+ +
+
+
+ + diff --git a/web/skins/bootstrap/views/export.php b/web/skins/bootstrap/views/export.php new file mode 100644 index 000000000..5ca464f88 --- /dev/null +++ b/web/skins/bootstrap/views/export.php @@ -0,0 +1,131 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
checked="checked" onclick="configureExportButton( this )"/>
checked="checked" onclick="configureExportButton( this )"/>
checked="checked" onclick="configureExportButton( this )"/>
checked="checked" onclick="configureExportButton( this )"/>
checked="checked" onclick="configureExportButton( this )"/>
+ checked="checked" onclick="configureExportButton( this )"/> + checked="checked" onclick="configureExportButton( this )"/> +
+ +
+
+ +

+ + + + + +
+ + diff --git a/web/skins/bootstrap/views/filter.php b/web/skins/bootstrap/views/filter.php new file mode 100644 index 000000000..bbc73a1b6 --- /dev/null +++ b/web/skins/bootstrap/views/filter.php @@ -0,0 +1,331 @@ +$SLANG['ChooseFilter'] ); +foreach ( dbFetchAll( "select * from Filters order by Name" ) as $row ) +{ + $filterNames[$row['Name']] = $row['Name']; + if ( $row['Background'] ) + $filterNames[$row['Name']] .= "*"; + if ( !empty($_REQUEST['reload']) && isset($_REQUEST['filterName']) && $_REQUEST['filterName'] == $row['Name'] ) + $dbFilter = $row; +} + +$backgroundStr = ""; +if ( isset($dbFilter) ) +{ + if ( $dbFilter['Background'] ) + $backgroundStr = '['.strtolower($SLANG['Background']).']'; + $_REQUEST['filter'] = jsonDecode( $dbFilter['Query'] ); + $_REQUEST['sort_field'] = isset($_REQUEST['filter']['sort_field'])?$_REQUEST['filter']['sort_field']:"DateTime"; + $_REQUEST['sort_asc'] = isset($_REQUEST['filter']['sort_asc'])?$_REQUEST['filter']['sort_asc']:"1"; + $_REQUEST['limit'] = isset($_REQUEST['filter']['limit'])?$_REQUEST['filter']['limit']:""; + unset( $_REQUEST['filter']['sort_field'] ); + unset( $_REQUEST['filter']['sort_asc'] ); + unset( $_REQUEST['filter']['limit'] ); +} + +$conjunctionTypes = array( + 'and' => $SLANG['ConjAnd'], + 'or' => $SLANG['ConjOr'] +); +$obracketTypes = array(); +$cbracketTypes = array(); +if ( isset($_REQUEST['filter']['terms']) ) +{ + for ( $i = 0; $i <= count($_REQUEST['filter']['terms'])-2; $i++ ) + { + $obracketTypes[$i] = str_repeat( "(", $i ); + $cbracketTypes[$i] = str_repeat( ")", $i ); + } +} + +$attrTypes = array( + 'MonitorId' => $SLANG['AttrMonitorId'], + 'MonitorName' => $SLANG['AttrMonitorName'], + 'Id' => $SLANG['AttrId'], + 'Name' => $SLANG['AttrName'], + 'Cause' => $SLANG['AttrCause'], + 'Notes' => $SLANG['AttrNotes'], + 'DateTime' => $SLANG['AttrDateTime'], + 'Date' => $SLANG['AttrDate'], + 'Time' => $SLANG['AttrTime'], + 'Weekday' => $SLANG['AttrWeekday'], + 'Length' => $SLANG['AttrDuration'], + 'Frames' => $SLANG['AttrFrames'], + 'AlarmFrames' => $SLANG['AttrAlarmFrames'], + 'TotScore' => $SLANG['AttrTotalScore'], + 'AvgScore' => $SLANG['AttrAvgScore'], + 'MaxScore' => $SLANG['AttrMaxScore'], + 'Archived' => $SLANG['AttrArchiveStatus'], + 'DiskPercent' => $SLANG['AttrDiskPercent'], + 'DiskBlocks' => $SLANG['AttrDiskBlocks'], + 'SystemLoad' => $SLANG['AttrSystemLoad'], +); +$opTypes = array( + '=' => $SLANG['OpEq'], + '!=' => $SLANG['OpNe'], + '>=' => $SLANG['OpGtEq'], + '>' => $SLANG['OpGt'], + '<' => $SLANG['OpLt'], + '<=' => $SLANG['OpLtEq'], + '=~' => $SLANG['OpMatches'], + '!~' => $SLANG['OpNotMatches'], + '=[]' => $SLANG['OpIn'], + '![]' => $SLANG['OpNotIn'], +); +$archiveTypes = array( + '0' => $SLANG['ArchUnarchived'], + '1' => $SLANG['ArchArchived'] +); +$weekdays = array(); +for ( $i = 0; $i < 7; $i++ ) +{ + $weekdays[$i] = strftime( "%A", mktime( 12, 0, 0, 1, $i+1, 2001 ) ); +} +$sort_fields = array( + 'Id' => $SLANG['AttrId'], + 'Name' => $SLANG['AttrName'], + 'Cause' => $SLANG['AttrCause'], + 'Notes' => $SLANG['AttrNotes'], + 'MonitorName' => $SLANG['AttrMonitorName'], + 'DateTime' => $SLANG['AttrDateTime'], + 'Length' => $SLANG['AttrDuration'], + 'Frames' => $SLANG['AttrFrames'], + 'AlarmFrames' => $SLANG['AttrAlarmFrames'], + 'TotScore' => $SLANG['AttrTotalScore'], + 'AvgScore' => $SLANG['AttrAvgScore'], + 'MaxScore' => $SLANG['AttrMaxScore'], +); +$sort_dirns = array( + '1' => $SLANG['SortAsc'], + '0' => $SLANG['SortDesc'] +); +if ( empty($_REQUEST['sort_field']) ) +{ + $_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD; + $_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == "asc"); +} + +$hasCal = file_exists( 'tools/jscalendar/calendar.js' ); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['EventFilter'] ); +?> + +
+ +
+
+ + + + + + + + +
+
1 ) { echo buildSelect( $selectName, $filterNames, "submitToFilter( this, 1 );" ); } else { ?>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  2 ) { echo buildSelect( "filter[terms][$i][obr]", $obracketTypes ); } else { ?>  2 ) { echo buildSelect( "filter[terms][$i][cbr]", $cbracketTypes ); } else { ?>  1 ) { ?>
+
+ + + + + + + +
"/>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
checked="checked" onclick="updateButtons( this )"/>
checked="checked" onclick="updateButtons( this )"/>
checked="checked" onclick="updateButtons( this )"/>
checked="checked" onclick="updateButtons( this )"/>
checked="checked" onclick="updateButtons( this )"/>
checked="checked"/>" size="32" maxlength="255" onchange="updateButtons( this )"/>
checked="checked" onclick="updateButtons( this )"/>
+
+
+ + + + + + + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/filtersave.php b/web/skins/bootstrap/views/filtersave.php new file mode 100644 index 000000000..ba040d72f --- /dev/null +++ b/web/skins/bootstrap/views/filtersave.php @@ -0,0 +1,86 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + +

+ +

+ +

+ +

+ +

+ checked="checked"/> +

+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/frame.php b/web/skins/bootstrap/views/frame.php new file mode 100644 index 000000000..c9c871fca --- /dev/null +++ b/web/skins/bootstrap/views/frame.php @@ -0,0 +1,100 @@ +$fid, 'Type'=>'Normal', 'Score'=>0 ); +} else { + $frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId = ? AND Score = ?', NULL, array( $eid, $event['MaxScore'] ) ); +} + +$maxFid = $event['Frames']; + +$firstFid = 1; +$prevFid = $frame['FrameId']-1; +$nextFid = $frame['FrameId']+1; +$lastFid = $maxFid; + +$alarmFrame = $frame['Type']=='Alarm'; + +if ( isset( $_REQUEST['scale'] ) ) + $scale = validInt($_REQUEST['scale']); +else + $scale = max( reScale( SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE ); + +$imageData = getImageSrc( $event, $frame, $scale, (isset($_REQUEST['show']) && $_REQUEST['show']=="capt") ); + +$imagePath = $imageData['thumbPath']; +$eventPath = $imageData['eventPath']; +$dImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-d.jpg", $eventPath, $frame['FrameId'] ); +$rImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-r.jpg", $eventPath, $frame['FrameId'] ); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Frame']." - ".$event['Id']." - ".$frame['FrameId'] ); +?> + +
+ +
+

"><?= $frame['EventId']." class=""/>

+

+ 1 ) { ?> + + 1 ) { ?> + + + + + + +

+ +

+

" width="" height="" class=""/>

+ +

+

+ +
+
+ + diff --git a/web/skins/bootstrap/views/frames.php b/web/skins/bootstrap/views/frames.php new file mode 100644 index 000000000..ec306a3f6 --- /dev/null +++ b/web/skins/bootstrap/views/frames.php @@ -0,0 +1,103 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + diff --git a/web/skins/bootstrap/views/function.php b/web/skins/bootstrap/views/function.php new file mode 100644 index 000000000..cacc3ee07 --- /dev/null +++ b/web/skins/bootstrap/views/function.php @@ -0,0 +1,64 @@ + + +
+ +
+
+ + + +

+ + checked="checked"/> +

+
+ + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/group.php b/web/skins/bootstrap/views/group.php new file mode 100644 index 000000000..bb81774d6 --- /dev/null +++ b/web/skins/bootstrap/views/group.php @@ -0,0 +1,88 @@ + "", + "Name" => "New Group", + "MonitorIds" => "" + ); +} + +xhtmlHeaders( __FILE__, $SLANG['Group']." - ".$newGroup['Name'] ); +?> + +
+ +
+
+ + + + + + + + + + + + + + +
+ +
+
+ disabled="disabled"/> + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/groups.php b/web/skins/bootstrap/views/groups.php new file mode 100644 index 000000000..87f8b9ebe --- /dev/null +++ b/web/skins/bootstrap/views/groups.php @@ -0,0 +1,94 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
onclick="configureButtons( this );"/>
onclick="configureButtons( this );"/>
+
+ + /> + /> + /> + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/js/Makefile.am b/web/skins/bootstrap/views/js/Makefile.am new file mode 100644 index 000000000..ba1845e0c --- /dev/null +++ b/web/skins/bootstrap/views/js/Makefile.am @@ -0,0 +1,49 @@ +AUTOMAKE_OPTIONS = gnu + +webdir = @WEB_PREFIX@/skins/classic/views/js + +dist_web_DATA = \ + console.js \ + console.js.php \ + control.js \ + controlpreset.js \ + controlpreset.js.php \ + cycle.js \ + cycle.js.php \ + devices.js \ + donate.js \ + donate.js.php \ + event.js \ + event.js.php \ + events.js \ + events.js.php \ + export.js \ + export.js.php \ + filter.js \ + filter.js.php \ + group.js \ + groups.js \ + log.js \ + login.js \ + Makefile.am \ + monitor.js \ + monitor.js.php \ + monitorpreset.js \ + monitorprobe.js \ + montage.js \ + montage.js.php \ + options.js.php \ + postlogin.js \ + state.js \ + state.js.php \ + timeline.js \ + timeline.js.php \ + user.js \ + version.js \ + version.js.php \ + video.js \ + video.js.php \ + watch.js \ + watch.js.php \ + zone.js \ + zone.js.php diff --git a/web/skins/bootstrap/views/js/console.js b/web/skins/bootstrap/views/js/console.js new file mode 100644 index 000000000..5182a5fd5 --- /dev/null +++ b/web/skins/bootstrap/views/js/console.js @@ -0,0 +1,65 @@ +function setButtonStates( element ) +{ + var form = element.form; + var checked = 0; + for ( var i = 0; i < form.elements.length; i++ ) + { + if ( form.elements[i].type == "checkbox" ) + { + if ( form.elements[i].checked ) + { + if ( checked++ > 1 ) + break; + } + } + } + $(element).getParent( 'tr' ).toggleClass( 'highlight' ); + form.editBtn.disabled = (checked!=1); + form.deleteBtn.disabled = (checked==0); +} + +function editMonitor( element ) +{ + var form = element.form; + for ( var i = 0; i < form.elements.length; i++ ) + { + if ( form.elements[i].type == "checkbox" ) + { + if ( form.elements[i].checked ) + { + var monitorId = form.elements[i].value; + createPopup( '?view=monitor&mid='+monitorId, 'zmMonitor'+monitorId, 'monitor' ); + form.elements[i].checked = false; + setButtonStates( form.elements[i] ); + //$(form.elements[i]).getParent( 'tr' ).removeClass( 'highlight' ); + break; + } + } + } +} + +function deleteMonitor( element ) +{ + if ( confirm( 'Warning, deleting a monitor also deletes all events and database entries associated with it.\nAre you sure you wish to delete?' ) ) + { + var form = element.form; + form.elements['action'].value = 'delete'; + form.submit(); + } +} + +function reloadWindow() +{ + window.location.replace( thisUrl ); +} + +function initPage() +{ + reloadWindow.periodical( consoleRefreshTimeout ); + if ( showVersionPopup ) + createPopup( '?view=version', 'zmVersion', 'version' ); + if ( showDonatePopup ) + createPopup( '?view=donate', 'zmDonate', 'donate' ); +} + +window.addEvent( 'domready', initPage ); diff --git a/web/skins/bootstrap/views/js/console.js.php b/web/skins/bootstrap/views/js/console.js.php new file mode 100644 index 000000000..90f66a619 --- /dev/null +++ b/web/skins/bootstrap/views/js/console.js.php @@ -0,0 +1,28 @@ +var consoleRefreshTimeout = ; + + 0 ) + { + if ( ZM_DYN_DONATE_REMINDER_TIME < time() ) + { + $showDonatePopup = true; + } + } + else + { + $nextReminder = time() + 30*24*60*60; + dbQuery( "update Config set Value = '".$nextReminder."' where Name = 'ZM_DYN_DONATE_REMINDER_TIME'" ); + } + } +} +?> +var showVersionPopup = ; +var showDonatePopup = ; diff --git a/web/skins/bootstrap/views/js/control.js b/web/skins/bootstrap/views/js/control.js new file mode 100644 index 000000000..819f088d8 --- /dev/null +++ b/web/skins/bootstrap/views/js/control.js @@ -0,0 +1,49 @@ +var controlParms = "view=request&request=control"; +var controlReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, onSuccess: getControlResponse } ); + +function getControlResponse( respObj, respText ) +{ + if ( !respObj ) + return; + //console.log( respText ); + if ( respObj.result != 'Ok' ) + { + alert( "Control response was status = "+respObj.status+"\nmessage = "+respObj.message ); + } +} + +function controlCmd( control, event, xtell, ytell ) +{ + var locParms = "&id="+$('mid').get('value'); + if ( event && (xtell || ytell) ) + { + var xEvent = new Event( event ); + var target = xEvent.target; + var coords = $(target).getCoordinates(); + + var l = coords.left; + var t = coords.top; + var x = xEvent.page.x - l; + var y = xEvent.page.y - t; + + if ( xtell ) + { + var xge = parseInt( (x*100)/coords.width ); + if ( xtell == -1 ) + xge = 100 - xge; + else if ( xtell == 2 ) + xge = 2*(50 - xge); + locParms += "&xge="+xge; + } + if ( ytell ) + { + var yge = parseInt( (y*100)/coords.height ); + if ( ytell == -1 ) + yge = 100 - yge; + else if ( ytell == 2 ) + yge = 2*(50 - yge); + locParms += "&yge="+yge; + } + } + controlReq.send( controlParms+"&control="+control+locParms ); +} diff --git a/web/skins/bootstrap/views/js/controlpreset.js b/web/skins/bootstrap/views/js/controlpreset.js new file mode 100644 index 000000000..ec2629cae --- /dev/null +++ b/web/skins/bootstrap/views/js/controlpreset.js @@ -0,0 +1,14 @@ +function updateLabel() +{ + var presetIndex = $('contentForm').preset.getValue(); + if ( labels[presetIndex] ) + { + $('contentForm').newLabel.value = labels[presetIndex]; + } + else + { + $('contentForm').newLabel.value = ""; + } +} + +window.addEvent( 'domready', updateLabel ); diff --git a/web/skins/bootstrap/views/js/controlpreset.js.php b/web/skins/bootstrap/views/js/controlpreset.js.php new file mode 100644 index 000000000..0aac01bf6 --- /dev/null +++ b/web/skins/bootstrap/views/js/controlpreset.js.php @@ -0,0 +1,9 @@ +var labels = new Array(); +$label ) +{ +?> +labels[] = ""; + diff --git a/web/skins/bootstrap/views/js/cycle.js b/web/skins/bootstrap/views/js/cycle.js new file mode 100644 index 000000000..e799a422e --- /dev/null +++ b/web/skins/bootstrap/views/js/cycle.js @@ -0,0 +1,11 @@ +function nextCycleView() +{ + window.location.replace( '?view=cycle&group='+currGroup+'&mid='+nextMid+'&mode='+mode, cycleRefreshTimeout ); +} + +function initCycle() +{ + nextCycleView.periodical( cycleRefreshTimeout ); +} + +window.addEvent( 'domready', initCycle ); diff --git a/web/skins/bootstrap/views/js/cycle.js.php b/web/skins/bootstrap/views/js/cycle.js.php new file mode 100644 index 000000000..c9dabaec4 --- /dev/null +++ b/web/skins/bootstrap/views/js/cycle.js.php @@ -0,0 +1,5 @@ +var currGroup = ""; +var nextMid = ""; +var mode = ""; + +var cycleRefreshTimeout = ; diff --git a/web/skins/bootstrap/views/js/devices.js b/web/skins/bootstrap/views/js/devices.js new file mode 100644 index 000000000..8191518fc --- /dev/null +++ b/web/skins/bootstrap/views/js/devices.js @@ -0,0 +1,47 @@ +function switchDeviceOn( element, key ) +{ + var form = element.form; + form.view.value = currentView; + form.action.value = 'device'; + form.command.value = 'on'; + form.key.value = key; + form.submit(); +} + +function switchDeviceOff( element, key ) +{ + var form = element.form; + form.view.value = currentView; + form.action.value = 'device'; + form.command.value = 'off'; + form.key.value = key; + form.submit(); +} + +function deleteDevice( element ) +{ + var form = element.form; + form.view.value = currentView; + form.action.value = 'delete'; + form.submit(); +} + +function configureButtons( element, name ) +{ + var form = element.form; + var checked = false; + for (var i = 0; i < form.elements.length; i++) + { + if ( form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + checked = true; + break; + } + } + } + form.deleteBtn.disabled = !checked; +} + +window.focus(); diff --git a/web/skins/bootstrap/views/js/donate.js b/web/skins/bootstrap/views/js/donate.js new file mode 100644 index 000000000..87d99198b --- /dev/null +++ b/web/skins/bootstrap/views/js/donate.js @@ -0,0 +1,14 @@ +function submitForm( element ) +{ + var form = element.form; + if ( form.option.selectedIndex == 0 ) + form.view.value = currentView; + else + form.view.value = 'none'; + form.submit(); +} + +if ( action == "donate" && option == "go" ) +{ + zmWindow(); +} diff --git a/web/skins/bootstrap/views/js/donate.js.php b/web/skins/bootstrap/views/js/donate.js.php new file mode 100644 index 000000000..9d24e392f --- /dev/null +++ b/web/skins/bootstrap/views/js/donate.js.php @@ -0,0 +1,2 @@ +var action = ''; +var option = ''; diff --git a/web/skins/bootstrap/views/js/event.js b/web/skins/bootstrap/views/js/event.js new file mode 100644 index 000000000..a1b2a2e55 --- /dev/null +++ b/web/skins/bootstrap/views/js/event.js @@ -0,0 +1,754 @@ +function setButtonState( element, butClass ) +{ + element.className = butClass; + element.disabled = (butClass != 'inactive'); +} + +function changeScale() +{ + var scale = $('scale').get('value'); + var baseWidth = eventData.Width; + var baseHeight = eventData.Height; + var newWidth = ( baseWidth * scale ) / SCALE_BASE; + var newHeight = ( baseHeight * scale ) / SCALE_BASE; + + streamScale( scale ); + + /*Stream could be an applet so can't use moo tools*/ + var streamImg = document.getElementById('evtStream'); + streamImg.style.width = newWidth + "px"; + streamImg.style.height = newHeight + "px"; +} + +function changeReplayMode() +{ + var replayMode = $('replayMode').get('value'); + + Cookie.write( 'replayMode', replayMode, { duration: 10*365 }) + + refreshWindow(); +} + +var streamParms = "view=request&request=stream&connkey="+connKey; +var streamCmdTimer = null; + +var streamStatus = null; +var lastEventId = 0; + +function getCmdResponse( respObj, respText ) +{ + if ( checkStreamForErrors( "getCmdResponse" ,respObj ) ) + return; + + if ( streamCmdTimer ) + streamCmdTimer = clearTimeout( streamCmdTimer ); + + streamStatus = respObj.status; + + var eventId = streamStatus.event; + if ( eventId != lastEventId ) + { + eventQuery( eventId ); + lastEventId = eventId; + } + if ( streamStatus.paused == true ) + { + $('modeValue').set( 'text', "Paused" ); + $('rate').addClass( 'hidden' ); + streamPause( false ); + } + else + { + $('modeValue').set( 'text', "Replay" ); + $('rateValue').set( 'text', streamStatus.rate ); + $('rate').removeClass( 'hidden' ); + streamPlay( false ); + } + $('progressValue').set( 'text', secsToTime( parseInt(streamStatus.progress) ) ); + $('zoomValue').set( 'text', streamStatus.zoom ); + if ( streamStatus.zoom == "1.0" ) + setButtonState( $('zoomOutBtn'), 'unavail' ); + else + setButtonState( $('zoomOutBtn'), 'inactive' ); + + updateProgressBar(); + + streamCmdTimer = streamQuery.delay( streamTimeout ); +} + +var streamReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getCmdResponse } ); + +function streamPause( action ) +{ + setButtonState( $('pauseBtn'), 'active' ); + setButtonState( $('playBtn'), 'inactive' ); + setButtonState( $('fastFwdBtn'), 'unavail' ); + setButtonState( $('slowFwdBtn'), 'inactive' ); + setButtonState( $('slowRevBtn'), 'inactive' ); + setButtonState( $('fastRevBtn'), 'unavail' ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_PAUSE ); +} + +function streamPlay( action ) +{ + setButtonState( $('pauseBtn'), 'inactive' ); + if (streamStatus) + setButtonState( $('playBtn'), streamStatus.rate==1?'active':'inactive' ); + setButtonState( $('fastFwdBtn'), 'inactive' ); + setButtonState( $('slowFwdBtn'), 'unavail' ); + setButtonState( $('slowRevBtn'), 'unavail' ); + setButtonState( $('fastRevBtn'), 'inactive' ); + if ( action ) + { + streamReq.send( streamParms+"&command="+CMD_PLAY ); + } +} + +function streamFastFwd( action ) +{ + setButtonState( $('pauseBtn'), 'inactive' ); + setButtonState( $('playBtn'), 'inactive' ); + setButtonState( $('fastFwdBtn'), 'inactive' ); + setButtonState( $('slowFwdBtn'), 'unavail' ); + setButtonState( $('slowRevBtn'), 'unavail' ); + setButtonState( $('fastRevBtn'), 'inactive' ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_FASTFWD ); +} + +function streamSlowFwd( action ) +{ + setButtonState( $('pauseBtn'), 'inactive' ); + setButtonState( $('playBtn'), 'inactive' ); + setButtonState( $('fastFwdBtn'), 'unavail' ); + setButtonState( $('slowFwdBtn'), 'active' ); + setButtonState( $('slowRevBtn'), 'inactive' ); + setButtonState( $('fastRevBtn'), 'unavail' ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_SLOWFWD ); + setButtonState( $('pauseBtn'), 'active' ); + setButtonState( $('slowFwdBtn'), 'inactive' ); +} + +function streamSlowRev( action ) +{ + setButtonState( $('pauseBtn'), 'inactive' ); + setButtonState( $('playBtn'), 'inactive' ); + setButtonState( $('fastFwdBtn'), 'unavail' ); + setButtonState( $('slowFwdBtn'), 'inactive' ); + setButtonState( $('slowRevBtn'), 'active' ); + setButtonState( $('fastRevBtn'), 'unavail' ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_SLOWREV ); + setButtonState( $('pauseBtn'), 'active' ); + setButtonState( $('slowRevBtn'), 'inactive' ); +} + +function streamFastRev( action ) +{ + setButtonState( $('pauseBtn'), 'inactive' ); + setButtonState( $('playBtn'), 'inactive' ); + setButtonState( $('fastFwdBtn'), 'inactive' ); + setButtonState( $('slowFwdBtn'), 'unavail' ); + setButtonState( $('slowRevBtn'), 'unavail' ); + setButtonState( $('fastRevBtn'), 'inactive' ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_FASTREV ); +} + +function streamPrev( action ) +{ + streamPlay( false ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_PREV ); +} + +function streamNext( action ) +{ + streamPlay( false ); + if ( action ) + streamReq.send( streamParms+"&command="+CMD_NEXT ); +} + +function streamZoomIn( x, y ) +{ + streamReq.send( streamParms+"&command="+CMD_ZOOMIN+"&x="+x+"&y="+y ); +} + +function streamZoomOut() +{ + streamReq.send( streamParms+"&command="+CMD_ZOOMOUT ); +} + +function streamScale( scale ) +{ + streamReq.send( streamParms+"&command="+CMD_SCALE+"&scale="+scale ); +} + +function streamPan( x, y ) +{ + streamReq.send( streamParms+"&command="+CMD_PAN+"&x="+x+"&y="+y ); +} + +function streamSeek( offset ) +{ + streamReq.send( streamParms+"&command="+CMD_SEEK+"&offset="+offset ); +} + +function streamQuery() +{ + streamReq.send( streamParms+"&command="+CMD_QUERY ); +} + +var slider = null; +var scroll = null; + +function getEventResponse( respObj, respText ) +{ + if ( checkStreamForErrors( "getEventResponse", respObj ) ) + return; + + eventData = respObj.event; + if ( !$('eventStills').hasClass( 'hidden' ) && currEventId != eventData.Id ) + resetEventStills(); + currEventId = eventData.Id; + + $('dataId').set( 'text', eventData.Id ); + if ( eventData.Notes ) + { + $('dataCause').setProperty( 'title', eventData.Notes ); + } + else + { + $('dataCause').setProperty( 'title', causeString ); + } + $('dataCause').set( 'text', eventData.Cause ); + $('dataTime').set( 'text', eventData.StartTime ); + $('dataDuration').set( 'text', eventData.Length ); + $('dataFrames').set( 'text', eventData.Frames+"/"+eventData.AlarmFrames ); + $('dataScore').set( 'text', eventData.TotScore+"/"+eventData.AvgScore+"/"+eventData.MaxScore ); + $('eventName').setProperty( 'value', eventData.Name ); + + if ( canEditEvents ) + { + if ( parseInt(eventData.Archived) ) + { + $('archiveEvent').addClass( 'hidden' ); + $('unarchiveEvent').removeClass( 'hidden' ); + } + else + { + $('archiveEvent').removeClass( 'hidden' ); + $('unarchiveEvent').addClass( 'hidden' ); + } + } + //var eventImg = $('eventImage'); + //eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } ); + drawProgressBar(); + nearEventsQuery( eventData.Id ); +} + +var eventReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getEventResponse } ); + +function eventQuery( eventId ) +{ + var eventParms = "view=request&request=status&entity=event&id="+eventId; + eventReq.send( eventParms ); +} + +var prevEventId = 0; +var nextEventId = 0; + +function getNearEventsResponse( respObj, respText ) +{ + if ( checkStreamForErrors( "getNearEventsResponse", respObj ) ) + return; + prevEventId = respObj.nearevents.PrevEventId; + nextEventId = respObj.nearevents.NextEventId; + + $('prevEventBtn').disabled = !prevEventId; + $('nextEventBtn').disabled = !nextEventId; +} + +var nearEventsReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getNearEventsResponse } ); + +function nearEventsQuery( eventId ) +{ + var parms = "view=request&request=status&entity=nearevents&id="+eventId; + nearEventsReq.send( parms ); +} + +var frameBatch = 40; + +function loadEventThumb( event, frame, loadImage ) +{ + var thumbImg = $('eventThumb'+frame.FrameId); + if ( !thumbImg ) + { + console.error( "No holder found for frame "+frame.FrameId ); + return; + } + var img = new Asset.image( imagePrefix+frame.Image.imagePath, + { + 'onload': ( function( loadImage ) + { + thumbImg.setProperty( 'src', img.getProperty( 'src' ) ); + thumbImg.removeClass( 'placeholder' ); + thumbImg.setProperty( 'class', frame.Type=='Alarm'?'alarm':'normal' ); + thumbImg.setProperty( 'title', frame.FrameId+' / '+((frame.Type=='Alarm')?frame.Score:0) ); + thumbImg.removeEvents( 'click' ); + thumbImg.addEvent( 'click', function() { locateImage( frame.FrameId, true ); } ); + if ( loadImage ) + loadEventImage( event, frame ); + } ).pass( loadImage ) + } + ); +} + +function updateStillsSizes( noDelay ) +{ + var containerDim = $('eventThumbs').getSize(); + + var containerWidth = containerDim.x; + var containerHeight = containerDim.y; + var popupWidth = parseInt($('eventImage').getStyle( 'width' )); + var popupHeight = parseInt($('eventImage').getStyle( 'height' )); + + var left = (containerWidth - popupWidth)/2; + if ( left < 0 ) left = 0; + var top = (containerHeight - popupHeight)/2; + if ( top < 0 ) top = 0; + if ( popupHeight == 0 && !noDelay ) // image not yet loaded lets give it another second + { + updateStillsSizes.pass( true ).delay( 50 ); + return; + } + $('eventImagePanel').setStyles( { + 'left': left, + 'top': top + } ); +} + +function loadEventImage( event, frame ) +{ + console.debug( "Loading "+event.Id+"/"+frame.FrameId ); + var eventImg = $('eventImage'); + var thumbImg = $('eventThumb'+frame.FrameId); + if ( eventImg.getProperty( 'src' ) != thumbImg.getProperty( 'src' ) ) + { + var eventImagePanel = $('eventImagePanel'); + + if ( eventImagePanel.getStyle( 'display' ) != 'none' ) + { + var lastThumbImg = $('eventThumb'+eventImg.getProperty( 'alt' )); + lastThumbImg.removeClass('selected'); + lastThumbImg.setOpacity( 1.0 ); + } + + eventImg.setProperties( { + 'class': frame.Type=='Alarm'?'alarm':'normal', + 'src': thumbImg.getProperty( 'src' ), + 'title': thumbImg.getProperty( 'title' ), + 'alt': thumbImg.getProperty( 'alt' ), + 'width': event.Width, + 'height': event.Height + } ); + $('eventImageBar').setStyle( 'width', event.Width ); + if ( frame.Type=='Alarm' ) + $('eventImageStats').removeClass( 'hidden' ); + else + $('eventImageStats').addClass( 'hidden' ); + thumbImg.addClass( 'selected' ); + thumbImg.setOpacity( 0.5 ); + + if ( eventImagePanel.getStyle( 'display' ) == 'none' ) + { + eventImagePanel.setOpacity( 0 ); + updateStillsSizes(); + eventImagePanel.setStyle( 'display', 'block' ); + new Fx.Tween( eventImagePanel, { duration: 500, transition: Fx.Transitions.Sine } ).start( 'opacity', 0, 1 ); + } + + $('eventImageNo').set( 'text', frame.FrameId ); + $('prevImageBtn').disabled = (frame.FrameId==1); + $('nextImageBtn').disabled = (frame.FrameId==event.Frames); + } +} + +function hideEventImageComplete() +{ + var eventImg = $('eventImage'); + var thumbImg = $('eventThumb'+$('eventImage').getProperty( 'alt' )); + thumbImg.removeClass('selected'); + thumbImg.setOpacity( 1.0 ); + $('prevImageBtn').disabled = true; + $('nextImageBtn').disabled = true; + $('eventImagePanel').setStyle( 'display', 'none' ); + $('eventImageStats').addClass( 'hidden' ); +} + +function hideEventImage() +{ + if ( $('eventImagePanel').getStyle( 'display' ) != 'none' ) + new Fx.Tween( $('eventImagePanel'), { duration: 500, transition: Fx.Transitions.Sine, onComplete: hideEventImageComplete } ).start( 'opacity', 1, 0 ); +} + +function resetEventStills() +{ + hideEventImage(); + $('eventThumbs').empty(); + if ( true || !slider ) + { + slider = new Slider( $('thumbsSlider'), $('thumbsKnob'), { + /*steps: eventData.Frames,*/ + onChange: function( step ) + { + if ( !step ) + step = 0; + var fid = parseInt((step * eventData.Frames)/this.options.steps); + if ( fid < 1 ) + fid = 1; + else if ( fid > eventData.Frames ) + fid = eventData.Frames; + checkFrames( eventData.Id, fid ); + scroll.toElement( 'eventThumb'+fid ); + } + } ).set( 0 ); + } + if ( $('eventThumbs').getStyle( 'height' ).match( /^\d+/ ) < (parseInt(eventData.Height)+80) ) + $('eventThumbs').setStyle( 'height', (parseInt(eventData.Height)+80)+'px' ); +} + +function getFrameResponse( respObj, respText ) +{ + if ( checkStreamForErrors( "getFrameResponse", respObj ) ) + return; + + var frame = respObj.frameimage; + + if ( !eventData ) + { + console.error( "No event "+frame.EventId+" found" ); + return; + } + + if ( !eventData['frames'] ) + eventData['frames'] = new Object(); + + eventData['frames'][frame.FrameId] = frame; + + loadEventThumb( eventData, frame, respObj.loopback=="true" ); +} + +var frameReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getFrameResponse } ); + +function frameQuery( eventId, frameId, loadImage ) +{ + var parms = "view=request&request=status&entity=frameimage&id[0]="+eventId+"&id[1]="+frameId+"&loopback="+loadImage; + frameReq.send( parms ); +} + +var currFrameId = null; + +function checkFrames( eventId, frameId, loadImage ) +{ + if ( !eventData ) + { + console.error( "No event "+eventId+" found" ); + return; + } + + if ( !eventData['frames'] ) + eventData['frames'] = new Object(); + + currFrameId = frameId; + + var loFid = frameId - frameBatch/2; + if ( loFid < 1 ) + loFid = 1; + var hiFid = loFid + (frameBatch-1); + if ( hiFid > eventData.Frames ) + hiFid = eventData.Frames; + + for ( var fid = loFid; fid <= hiFid; fid++ ) + { + if ( !$('eventThumb'+fid) ) + { + var img = new Element( 'img', { 'id': 'eventThumb'+fid, 'src': 'graphics/transparent.gif', 'alt': fid, 'class': 'placeholder' } ); + img.addEvent( 'click', function () { eventData['frames'][fid] = null; checkFrames( eventId, fid ) } ); + frameQuery( eventId, fid, loadImage && (fid == frameId) ); + var imgs = $('eventThumbs').getElements( 'img' ); + var injected = false; + if ( fid < imgs.length ) + { + img.inject( imgs[fid-1], 'before' ); + injected = true; + } + else + { + injected = imgs.some( + function( thumbImg, index ) + { + if ( parseInt(img.getProperty( 'alt' )) < parseInt(thumbImg.getProperty( 'alt' )) ) + { + img.inject( thumbImg, 'before' ); + return( true ); + } + return( false ); + } + ); + } + if ( !injected ) + { + img.inject( $('eventThumbs') ); + } + var scale = parseInt(img.getStyle('height')); + img.setStyles( { + 'width': parseInt((eventData.Width*scale)/100), + 'height': parseInt((eventData.Height*scale)/100) + } ); + } + else if ( eventData['frames'][fid] ) + { + if ( loadImage && (fid == frameId) ) + { + loadEventImage( eventData, eventData['frames'][fid], loadImage ); + } + } + } + $('prevThumbsBtn').disabled = (frameId==1); + $('nextThumbsBtn').disabled = (frameId==eventData.Frames); +} + +function locateImage( frameId, loadImage ) +{ + if ( slider ) + slider.fireEvent( 'tick', slider.toPosition( parseInt((frameId-1)*slider.options.steps/eventData.Frames) )); + checkFrames( eventData.Id, frameId, loadImage ); + scroll.toElement( 'eventThumb'+frameId ); +} + +function prevImage() +{ + if ( currFrameId > 1 ) + locateImage( parseInt(currFrameId)-1, true ); +} + +function nextImage() +{ + if ( currFrameId < eventData.Frames ) + locateImage( parseInt(currFrameId)+1, true ); +} + +function prevThumbs() +{ + if ( currFrameId > 1 ) + locateImage( parseInt(currFrameId)>10?(parseInt(currFrameId)-10):1, $('eventImagePanel').getStyle('display')!="none" ); +} + +function nextThumbs() +{ + if ( currFrameId < eventData.Frames ) + locateImage( parseInt(currFrameId)<(eventData.Frames-10)?(parseInt(currFrameId)+10):eventData.Frames, $('eventImagePanel').getStyle('display')!="none" ); +} + +function prevEvent() +{ + if ( prevEventId ) + { + eventQuery( prevEventId ); + streamPrev( true ); + } +} + +function nextEvent() +{ + if ( nextEventId ) + { + eventQuery( nextEventId ); + streamNext( true ); + } +} + +function getActResponse( respObj, respText ) +{ + if ( checkStreamForErrors( "getActResponse", respObj ) ) + return; + + if ( respObj.refreshParent ) + refreshParentWindow(); + + if ( respObj.refreshEvent ) + eventQuery( eventData.Id ); +} + +var actReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getActResponse } ); + +function actQuery( action, parms ) +{ + var actParms = "view=request&request=event&id="+eventData.Id+"&action="+action; + if ( parms != null ) + actParms += "&"+Object.toQueryString( parms ); + actReq.send( actParms ); +} + +function deleteEvent() +{ + actQuery( 'delete' ); + streamNext( true ); +} + +function renameEvent() +{ + var newName = $('eventName').get('value'); + actQuery( 'rename', { eventName: newName } ); +} + +function editEvent() +{ + createPopup( '?view=eventdetail&eid='+eventData.Id, 'zmEventDetail', 'eventdetail' ); +} + +function exportEvent() +{ + createPopup( '?view=export&eid='+eventData.Id, 'zmExport', 'export' ); +} + +function archiveEvent() +{ + actQuery( 'archive' ); +} + +function unarchiveEvent() +{ + actQuery( 'unarchive' ); +} + +function showEventFrames() +{ + createPopup( '?view=frames&eid='+eventData.Id, 'zmFrames', 'frames' ); +} + +function showStream() +{ + $('eventStills').addClass( 'hidden' ); + $('eventStream').removeClass( 'hidden' ); + $('streamEvent').addClass( 'hidden' ); + $('stillsEvent').removeClass( 'hidden' ); + + //$(window).removeEvent( 'resize', updateStillsSizes ); +} + +function showStills() +{ + $('eventStream').addClass( 'hidden' ); + $('eventStills').removeClass( 'hidden' ); + $('stillsEvent').addClass( 'hidden' ); + $('streamEvent').removeClass( 'hidden' ); + streamPause( true ); + if ( !scroll ) + { + scroll = new Fx.Scroll( 'eventThumbs', { + wait: false, + duration: 500, + offset: { 'x': 0, 'y': 0 }, + transition: Fx.Transitions.Quad.easeInOut + } + ); + } + resetEventStills(); + $(window).addEvent( 'resize', updateStillsSizes ); +} + +function showFrameStats() +{ + var fid = $('eventImageNo').get('text'); + createPopup( '?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height ); +} + +function videoEvent() +{ + createPopup( '?view=video&eid='+eventData.Id, 'zmVideo', 'video', eventData.Width, eventData.Height ); +} + +function drawProgressBar() +{ + var barWidth = 0; + $('progressBar').addClass( 'invisible' ); + var cells = $('progressBar').getElements( 'div' ); + var cellWidth = parseInt( eventData.Width/$$(cells).length ); + $$(cells).forEach( + function( cell, index ) + { + if ( index == 0 ) + $(cell).setStyles( { 'left': barWidth, 'width': cellWidth, 'borderLeft': 0 } ); + else + $(cell).setStyles( { 'left': barWidth, 'width': cellWidth } ); + var offset = parseInt((index*eventData.Length)/$$(cells).length); + $(cell).setProperty( 'title', '+'+secsToTime(offset)+'s' ); + $(cell).removeEvent( 'click' ); + $(cell).addEvent( 'click', function(){ streamSeek( offset ); } ); + barWidth += $(cell).getCoordinates().width; + } + ); + $('progressBar').setStyle( 'width', barWidth ); + $('progressBar').removeClass( 'invisible' ); +} + +function updateProgressBar() +{ + if ( eventData && streamStatus ) + { + var cells = $('progressBar').getElements( 'div' ); + var completeIndex = parseInt((($$(cells).length+1)*streamStatus.progress)/eventData.Length); + $$(cells).forEach( + function( cell, index ) + { + if ( index < completeIndex ) + { + if ( !$(cell).hasClass( 'complete' ) ) + { + $(cell).addClass( 'complete' ); + } + } + else + { + if ( $(cell).hasClass( 'complete' ) ) + { + $(cell).removeClass( 'complete' ); + } + } + } + ); + } +} + +function handleClick( event ) +{ + var target = event.target; + var x = event.page.x - $(target).getLeft(); + var y = event.page.y - $(target).getTop(); + + if ( event.shift ) + streamPan( x, y ); + else + streamZoomIn( x, y ); +} + +function initPage() +{ + streamCmdTimer = streamQuery.delay( 250 ); + eventQuery.pass( eventData.Id ).delay( 500 ); + + if ( canStreamNative ) + { + var streamImg = $('imageFeed').getElement('img'); + if ( !streamImg ) + streamImg = $('imageFeed').getElement('object'); + $(streamImg).addEvent( 'click', function( event ) { handleClick( event ); } ); + } +} + +// Kick everything off +window.addEvent( 'domready', initPage ); diff --git a/web/skins/bootstrap/views/js/event.js.php b/web/skins/bootstrap/views/js/event.js.php new file mode 100644 index 000000000..9ae458651 --- /dev/null +++ b/web/skins/bootstrap/views/js/event.js.php @@ -0,0 +1,48 @@ +// +// Import constants +// +var CMD_NONE = ; +var CMD_PAUSE = ; +var CMD_PLAY = ; +var CMD_STOP = ; +var CMD_FASTFWD = ; +var CMD_SLOWFWD = ; +var CMD_SLOWREV = ; +var CMD_FASTREV = ; +var CMD_ZOOMIN = ; +var CMD_ZOOMOUT = ; +var CMD_PAN = ; +var CMD_SCALE = ; +var CMD_PREV = ; +var CMD_NEXT = ; +var CMD_SEEK = ; +var CMD_QUERY = ; + +var SCALE_BASE = ; + +// +// PHP variables to JS +// +var connKey = ''; + +var eventData = { + Id: , + Width: , + Height: , + Length: +}; + +var filterQuery = ''; +var sortQuery = ''; + +var scale = ; +var canEditEvents = ; +var streamTimeout = ; + +var canStreamNative = ; + +// +// Strings +// +var deleteString = ""; +var causeString = ""; diff --git a/web/skins/bootstrap/views/js/events.js b/web/skins/bootstrap/views/js/events.js new file mode 100644 index 000000000..6aa129932 --- /dev/null +++ b/web/skins/bootstrap/views/js/events.js @@ -0,0 +1,150 @@ +function closeWindows() +{ + window.close(); + // This is a hack. The only way to close an existing window is to try and open it! + var filterWindow = window.open( thisUrl+'?view=none', 'zmFilter', 'width=1,height=1' ); + filterWindow.close(); +} + +function toggleCheckbox( element, name ) +{ + var form = element.form; + var checked = element.checked; + for (var i = 0; i < form.elements.length; i++) + if (form.elements[i].name.indexOf(name) == 0) + form.elements[i].checked = checked; + form.viewBtn.disabled = !checked; + form.editBtn.disabled = !checked; + form.archiveBtn.disabled = unarchivedEvents?!checked:true; + form.unarchiveBtn.disabled = archivedEvents?!checked:true; + form.exportBtn.disabled = !checked; + form.deleteBtn.disabled = !checked; +} + +function configureButton( element, name ) +{ + var form = element.form; + var checked = element.checked; + if ( !checked ) + { + for (var i = 0; i < form.elements.length; i++) + { + if ( form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + checked = true; + break; + } + } + } + } + if ( !element.checked ) + form.toggleCheck.checked = false; + form.viewBtn.disabled = !checked; + form.editBtn.disabled = !checked; + form.archiveBtn.disabled = (!checked)||(!unarchivedEvents); + form.unarchiveBtn.disabled = (!checked)||(!archivedEvents); + form.exportBtn.disabled = !checked; + form.deleteBtn.disabled = !checked; +} + +function deleteEvents( element, name ) +{ + var form = element.form; + var count = 0; + for (var i = 0; i < form.elements.length; i++) + { + if (form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + count++; + break; + } + } + } + if ( count > 0 ) + { + if ( confirm( confirmDeleteEventsString ) ) + { + form.action.value = 'delete'; + form.submit(); + } + } +} + +function editEvents( element, name ) +{ + var form = element.form; + var eids = new Array(); + for (var i = 0; i < form.elements.length; i++) + { + if (form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + eids[eids.length] = 'eids[]='+form.elements[i].value; + } + } + } + createPopup( '?view=eventdetail&'+eids.join( '&' ), 'zmEventDetail', 'eventdetail' ); +} + +function exportEvents( element, name ) +{ + var form = element.form; + var eids = new Array(); + for (var i = 0; i < form.elements.length; i++) + { + if (form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + eids[eids.length] = 'eids[]='+form.elements[i].value; + } + } + } + createPopup( '?view=export&'+eids.join( '&' ), 'zmExport', 'export' ); +} + +function viewEvents( element, name ) +{ + var form = element.form; + var events = new Array(); + for (var i = 0; i < form.elements.length; i++) + { + if ( form.elements[i].name.indexOf(name) == 0) + { + if ( form.elements[i].checked ) + { + events[events.length] = form.elements[i].value; + } + } + } + if ( events.length > 0 ) + { + createPopup( '?view=event&eid='+events[0]+'&filter[terms][0][attr]=Id&&filter[terms][0][op]=%3D%5B%5D&&filter[terms][0][val]='+events.join('%2C')+sortQuery+'&page=1&play=1', 'zmEvent', 'event', maxWidth, maxHeight ); + } +} + +function archiveEvents( element, name ) +{ + var form = element.form; + form.action.value = 'archive'; + form.submit(); +} + +function unarchiveEvents( element, name ) +{ + var form = element.form; + form.action.value = 'unarchive'; + form.submit(); +} + +if ( openFilterWindow ) +{ + //opener.location.reload(true); + createPopup( '?view=filter&page='+thisPage+filterQuery, 'zmFilter', 'filter' ); + location.replace( '?view='+currentView+'&page='+thisPage+filterQuery ); +} diff --git a/web/skins/bootstrap/views/js/events.js.php b/web/skins/bootstrap/views/js/events.js.php new file mode 100644 index 000000000..497d0c96e --- /dev/null +++ b/web/skins/bootstrap/views/js/events.js.php @@ -0,0 +1,13 @@ +//var openFilterWindow = ; +var openFilterWindow = false; + +var archivedEvents = ; +var unarchivedEvents = ; + +var filterQuery = ''; +var sortQuery = ''; + +var maxWidth = ; +var maxHeight = ; + +var confirmDeleteEventsString = ""; diff --git a/web/skins/bootstrap/views/js/export.js b/web/skins/bootstrap/views/js/export.js new file mode 100644 index 000000000..482b41d72 --- /dev/null +++ b/web/skins/bootstrap/views/js/export.js @@ -0,0 +1,58 @@ +function configureExportButton( element ) +{ + var form = element.form; + + var checkCount = 0; + var radioCount = 0; + for ( var i = 0; i < form.elements.length; i++ ) + if ( form.elements[i].type == "checkbox" && form.elements[i].checked ) + checkCount++; + else if ( form.elements[i].type == "radio" && form.elements[i].checked ) + radioCount++; + form.elements['exportButton'].disabled = (checkCount == 0 || radioCount == 0); +} + +function startDownload( exportFile ) +{ + window.location.replace( exportFile ); +} + +var exportTimer = null; + +function exportProgress() +{ + var tickerText = $('exportProgressTicker').get('text'); + if ( tickerText.length < 1 || tickerText.length > 4 ) + $('exportProgressTicker').set( 'text', '.' ); + else + $('exportProgressTicker').appendText( '.' ); +} + +function exportResponse( respObj, respText ) +{ + window.location.replace( thisUrl+'?view='+currentView+'&'+eidParm+'&exportFile='+respObj.exportFile+'&generated='+((respObj.result=='Ok')?1:0) ); +} + +function exportEvent( form ) +{ + var parms = 'view=request&request=event&action=export'; + parms += '&'+$(form).toQueryString(); + var query = new Request.JSON( { url: thisUrl, method: 'post', data: parms, onSuccess: exportResponse } ); + query.send(); + $('exportProgress').removeClass( 'hidden' ); + $('exportProgress').setProperty( 'class', 'warnText' ); + $('exportProgressText').set( 'text', exportProgressString ); + exportProgress(); + exportTimer = exportProgress.periodical( 500 ); +} + +function initPage() +{ + configureExportButton( $('exportButton') ); + if ( exportReady ) + { + startDownload.pass( exportFile ).delay( 1500 ); + } +} + +window.addEvent( 'domready', initPage ); diff --git a/web/skins/bootstrap/views/js/export.js.php b/web/skins/bootstrap/views/js/export.js.php new file mode 100644 index 000000000..e51089c14 --- /dev/null +++ b/web/skins/bootstrap/views/js/export.js.php @@ -0,0 +1,22 @@ + +var eidParm = ''; + +var eidParm = 'eid='; + + +var exportReady = ; +var exportFile = ''; + +var exportProgressString = ''; diff --git a/web/skins/bootstrap/views/js/filter.js b/web/skins/bootstrap/views/js/filter.js new file mode 100644 index 000000000..300862640 --- /dev/null +++ b/web/skins/bootstrap/views/js/filter.js @@ -0,0 +1,120 @@ +function updateButtons( element ) +{ + var form = element.form; + + if ( element.type == 'checkbox' && element.checked ) + form.elements['executeButton'].disabled = false; + else + { + var canExecute = false; + if ( form.elements['autoArchive'].checked ) + canExecute = true; + else if ( typeof ZM_OPT_FFMPEG !== "undefined" && form.elements['autoVideo'].checked ) + canExecute = true; + else if ( typeof ZM_OPT_UPLOAD !== "undefined" && form.elements['autoUpload'].checked ) + canExecute = true; + else if ( typeof ZM_OPT_EMAIL !== "undefined" && form.elements['autoEmail'].checked ) + canExecute = true; + else if ( typeof ZM_OPT_MESSAGE !== "undefined" && form.elements['autoMessage'].checked ) + canExecute = true; + else if ( form.elements['autoExecute'].checked && form.elements['autoExecuteCmd'].value != '' ) + canExecute = true; + else if ( form.elements['autoDelete'].checked ) + canExecute = true; + form.elements['executeButton'].disabled = !canExecute; + } +} + +function clearValue( element, line ) +{ + var form = element.form; + var val = form.elements['filter[terms]['+line+'][val]']; + val.value = ''; +} + +function submitToFilter( element, reload ) +{ + var form = element.form; + form.target = window.name; + form.view.value = 'filter'; + form.reload.value = reload; + form.submit(); +} + +function submitToEvents( element ) +{ + var form = element.form; + if ( validateForm( form ) ) + { + form.target = 'zmEvents'; + form.view.value = 'events'; + form.action.value = ''; + form.execute.value = 0; + form.submit(); + } +} + +function executeFilter( element ) +{ + var form = element.form; + if ( validateForm( form ) ) + { + form.target = 'zmEvents'; + form.view.value = 'events'; + form.action.value = 'filter'; + form.execute.value = 1; + form.submit(); + } +} + +function saveFilter( element ) +{ + var form = element.form; + + var popupName = 'zmEventsFilterSave'; + createPopup( thisUrl, popupName, 'filtersave' ); + + form.target = popupName; + form.view.value = 'filtersave'; + form.submit(); +} + +function deleteFilter( element, name ) +{ + if ( confirm( deleteSavedFilterString+" '"+name+"'" ) ) + { + var form = element.form; + form.action.value = 'delete'; + form.fid.value = name; + submitToFilter( element, 1 ); + } +} + +function addTerm( element, line ) +{ + var form = element.form; + form.target = window.name; + form.view.value = currentView; + form.action.value = 'filter'; + form.subaction.value = 'addterm'; + form.line.value = line; + form.submit(); +} + +function delTerm( element, line ) +{ + var form = element.form; + form.target = window.name; + form.view.value = currentView; + form.action.value = 'filter'; + form.subaction.value = 'delterm'; + form.line.value = line; + form.submit(); +} + +function init() +{ + updateButtons( $('executeButton') ); +} + +window.addEvent( 'domready', init ); diff --git a/web/skins/bootstrap/views/js/filter.js.php b/web/skins/bootstrap/views/js/filter.js.php new file mode 100644 index 000000000..924bf88f4 --- /dev/null +++ b/web/skins/bootstrap/views/js/filter.js.php @@ -0,0 +1,55 @@ +var deleteSavedFilterString = ""; +function validateForm( form ) +{ + 2 ) +{ +?> + var bracket_count = 0; + + var obr = form.elements['filter[terms][][obr]']; + var cbr = form.elements['filter[terms][][cbr]']; + bracket_count += parseInt(obr.options[obr.selectedIndex].value); + bracket_count -= parseInt(cbr.options[cbr.selectedIndex].value); + + if ( bracket_count ) + { + alert( "" ); + return( false ); + } + + + var val = form.elements['filter[terms][][val]']; + if ( val.value == '' ) + { + alert( "" ); + return( false ); + } + + return( true ); +} + + + + + + + + + + + + + + diff --git a/web/skins/bootstrap/views/optionhelp.php b/web/skins/bootstrap/views/optionhelp.php new file mode 100644 index 000000000..e02720b24 --- /dev/null +++ b/web/skins/bootstrap/views/optionhelp.php @@ -0,0 +1,44 @@ +", $optionHelpText ); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['OptionHelp'] ); +?> + +
+ +
+

+

+
+
+ + diff --git a/web/skins/bootstrap/views/options.php b/web/skins/bootstrap/views/options.php new file mode 100644 index 000000000..34f6fc6f1 --- /dev/null +++ b/web/skins/bootstrap/views/options.php @@ -0,0 +1,323 @@ + + +
+ +
+
    +$value ) +{ + if ( $tab == $name ) + { +?> +
  • + +
  • + +
+
+window.opener.location.reload();window.location.href=\"{$_SERVER['PHP_SELF']}?view={$view}&tab={$tab}\""; + } + +?> +
+ + + + + + + + +
ZM_SKIN +
+
+ /> + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
disabled="disabled"/>
+
+ disabled="disabled"/> +
+
+ +
+ + + + + + + + + + + + +$value ) + { + $shortName = preg_replace( '/^ZM_/', '', $name ); + $optionPromptText = !empty($OLANG[$shortName])?$OLANG[$shortName]['Prompt']:$value['Prompt']; +?> + + + + + + + + + + + + + + + + + + + + + +
 () checked="checked"/> + 3 ) + { +?> + + + checked="checked"/>  + + />/>/>/>
+
+ /> +
+
+ +
+
+ + diff --git a/web/skins/bootstrap/views/plugin.php b/web/skins/bootstrap/views/plugin.php new file mode 100644 index 000000000..ee8819dbd --- /dev/null +++ b/web/skins/bootstrap/views/plugin.php @@ -0,0 +1,167 @@ + 0 ) { + $newZone = dbFetchOne( 'SELECT * FROM Zones WHERE MonitorId = ? AND Id = ?', NULL, array( $mid, $zid) ); +} else { + $view = "error"; + return; +} +$monitor = dbFetchMonitor ( $mid ); +$plugin = $_REQUEST['pl']; + +$plugin_path = dirname(ZM_PLUGINS_CONFIG_PATH)."/".$plugin; + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Plugin'] ); + + +$pluginOptions=array( + 'Enabled'=>array( + 'Type'=>'select', + 'Name'=>'Enabled', + 'Choices'=>'yes,no', + 'Value'=>'no' + ) + ); + +$optionNames=array(); +if(file_exists($plugin_path."/config.php")) +{ + include_once($plugin_path."/config.php"); +} + +$sql='SELECT * FROM PluginsConfig WHERE MonitorId=? AND ZoneId=? AND pluginName=?'; +foreach( dbFetchAll( $sql, NULL, array( $mid, $zid, $plugin ) ) as $popt ) +{ + if(array_key_exists($popt['Name'], $pluginOptions) + && $popt['Type']==$pluginOptions[$popt['Name']]['Type'] + && $popt['Choices']==$pluginOptions[$popt['Name']]['Choices'] + ) + { + $pluginOptions[$popt['Name']]=$popt; + array_push($optionNames, $popt['Name']); + } else { + dbQuery('DELETE FROM PluginsConfig WHERE Id=?', array( $popt['Id'] ) ); + } +} +foreach($pluginOptions as $name => $values) +{ + if(!in_array($name, $optionNames)) + { + $popt=$pluginOptions[$name]; + $sql="INSERT INTO PluginsConfig VALUES ('',?,?,?,?,?,?,?)"; + dbQuery($sql, array( $popt['Name'], $popt['Value'], $popt['Type'], $popt['Choices'], $mid, $zid, $plugin ) ); + } +} + +$PLANG=array(); +if(file_exists($plugin_path."/lang/".$user['Language'].".php")) { + include_once($plugin_path."/lang/".$user['Language'].".php"); +} + +function pLang($name) +{ + global $PLANG; + if(array_key_exists($name, $PLANG)) + return $PLANG[$name]; + else + return $name; +} + + +?> + +
+ +
+
+ + + + + + +
+ + + $popt) +{ + ?> + + + + + + + + +
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/postlogin.php b/web/skins/bootstrap/views/postlogin.php new file mode 100644 index 000000000..2ce1ff88f --- /dev/null +++ b/web/skins/bootstrap/views/postlogin.php @@ -0,0 +1,33 @@ + + +
+ +
+

+
+
+ + diff --git a/web/skins/bootstrap/views/settings.php b/web/skins/bootstrap/views/settings.php new file mode 100644 index 000000000..dcc0316f5 --- /dev/null +++ b/web/skins/bootstrap/views/settings.php @@ -0,0 +1,78 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + +
disabled="disabled"/>
disabled="disabled"/>
disabled="disabled"/>
disabled="disabled"/>
+
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/state.php b/web/skins/bootstrap/views/state.php new file mode 100644 index 000000000..4e8365d51 --- /dev/null +++ b/web/skins/bootstrap/views/state.php @@ -0,0 +1,106 @@ + + +
+ +
+
+ + + + +

+ +

+ + + + + + + +
+
+ + + + +
+ + + + +

+

+ +
+
+
+ + diff --git a/web/skins/bootstrap/views/stats.php b/web/skins/bootstrap/views/stats.php new file mode 100644 index 000000000..07b5e7088 --- /dev/null +++ b/web/skins/bootstrap/views/stats.php @@ -0,0 +1,111 @@ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + 1 ) +{ +?> + + + + + + + + + + + + + +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/status.php b/web/skins/bootstrap/views/status.php new file mode 100644 index 000000000..113c23d88 --- /dev/null +++ b/web/skins/bootstrap/views/status.php @@ -0,0 +1,85 @@ + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+
+
+ + diff --git a/web/skins/bootstrap/views/timeline.php b/web/skins/bootstrap/views/timeline.php new file mode 100644 index 000000000..22c61d638 --- /dev/null +++ b/web/skins/bootstrap/views/timeline.php @@ -0,0 +1,974 @@ +700, + "height"=>460, + "image" => array( + "width"=>264, + "height"=>220, + "topOffset"=>20, + ), + "imageText" => array( + "width"=>400, + "height"=>30, + "topOffset"=>20, + ), + "graph" => array( + "width"=>600, + "height"=>160, + "topOffset"=>30, + ), + "title" => array( + "topOffset"=>50 + ), + "key" => array( + "topOffset"=>50 + ), + "axes" => array( + "x" => array( + "height" => 20, + ), + "y" => array( + "width" => 30, + ), + ), + "grid" => array( + "x" => array( + "major" => array( + "max" => 12, + "min" => 4, + ), + "minor" => array( + "max" => 48, + "min" => 12, + ), + ), + "y" => array( + "major" => array( + "max" => 8, + "min" => 1, + ), + "minor" => array( + "max" => 0, + "min" => 0, + ), + ), + ), +); + +$monitors = array(); +$monitorsSql = "select * from Monitors order by Sequence asc"; +//srand( 97981 ); +foreach( dbFetchAll( $monitorsSql ) as $row ) +{ + //if ( empty($row['WebColour']) ) + //{ + //$row['WebColour'] = sprintf( "#%02x%02x%02x", rand( 0, 255 ), rand( 0, 255), rand( 0, 255 ) ); + //} + $monitors[$row['Id']] = $row; +} + +$rangeSql = "select min(E.StartTime) as MinTime, max(E.EndTime) as MaxTime from Events as E inner join Monitors as M on (E.MonitorId = M.Id) where not isnull(E.StartTime) and not isnull(E.EndTime)"; +$eventsSql = "select E.Id,E.Name,E.StartTime,E.EndTime,E.Length,E.Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId from Events as E inner join Monitors as M on (E.MonitorId = M.Id) where not isnull(StartTime)"; + +if ( !empty($user['MonitorIds']) ) +{ + $monFilterSql = " and M.Id in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")"; + + $rangeSql .= $monFilterSql; + $eventsSql .= $monFilterSql; +} + +if ( isset($_REQUEST['filter']) ) + $tree = parseFilterToTree( $_REQUEST['filter'] ); +else + $tree = false; + +if ( isset($_REQUEST['range']) ) + $range = validHtmlStr($_REQUEST['range']); +if ( isset($_REQUEST['minTime']) ) + $minTime = validHtmlStr($_REQUEST['minTime']); +if ( isset($_REQUEST['midTime']) ) + $midTime = validHtmlStr($_REQUEST['midTime']); +if ( isset($_REQUEST['maxTime']) ) + $maxTime = validHtmlStr($_REQUEST['maxTime']); + +if ( isset($range) ) +{ + $halfRange = (int)($range/2); + if ( isset($midTime) ) + { + $midTimeT = strtotime($midTime); + $minTimeT = $midTimeT-$halfRange; + $maxTimeT = $midTimeT+$halfRange; + if ( !($range%1) ) + { + $maxTimeT--; + } + $minTime = strftime( STRF_FMT_DATETIME_DB, $minTimeT ); + $maxTime = strftime( STRF_FMT_DATETIME_DB, $maxTimeT ); + } + elseif ( isset($minTime) ) + { + $minTimeT = strtotime($minTime); + $maxTimeT = $minTimeT + $range; + $midTimeT = $minTimeT + $halfRange; + $midTime = strftime( STRF_FMT_DATETIME_DB, $midTimeT ); + $maxTime = strftime( STRF_FMT_DATETIME_DB, $maxTimeT ); + } + elseif ( isset($maxTime) ) + { + $maxTimeT = strtotime($maxTime); + $minTimeT = $maxTimeT - $range; + $midTimeT = $minTimeT + $halfRange; + $minTime = strftime( STRF_FMT_DATETIME_DB, $minTimeT ); + $midTime = strftime( STRF_FMT_DATETIME_DB, $midTimeT ); + } +} +elseif ( isset($minTime) && isset($maxTime) ) +{ + $minTimeT = strtotime($minTime); + $maxTimeT = strtotime($maxTime); + $range = ($maxTimeT - $minTimeT) + 1; + $halfRange = (int)($range/2); + $midTimeT = $minTimeT + $halfRange; + $midTime = strftime( STRF_FMT_DATETIME_DB, $midTimeT ); +} + +if ( isset($minTime) && isset($maxTime) ) +{ + $tempMinTime = $tempMaxTime = $tempExpandable = false; + extractDatetimeRange( $tree, $tempMinTime, $tempMaxTime, $tempExpandable ); + $filterSql = parseTreeToSQL( $tree ); + + if ( $filterSql ) + { + $filterSql = " and $filterSql"; + $eventsSql .= $filterSql; + } +} +else +{ + $filterSql = parseTreeToSQL( $tree ); + $tempMinTime = $tempMaxTime = $tempExpandable = false; + extractDatetimeRange( $tree, $tempMinTime, $tempMaxTime, $tempExpandable ); + + if ( $filterSql ) + { + $filterSql = " and $filterSql"; + $rangeSql .= $filterSql; + $eventsSql .= $filterSql; + } + + if ( !isset($minTime) || !isset($maxTime) ) + { + // Dynamically determine range + $row = dbFetchOne( $rangeSql ); + + if ( !isset($minTime) ) + $minTime = $row['MinTime']; + if ( !isset($maxTime) ) + $maxTime = $row['MaxTime']; + } + + if ( empty($minTime) ) + $minTime = $tempMinTime; + if ( empty($maxTime) ) + $maxTime = $tempMaxTime; + if ( empty($maxTime) ) + $maxTime = "now"; + + $minTimeT = strtotime($minTime); + $maxTimeT = strtotime($maxTime); + $range = ($maxTimeT - $minTimeT) + 1; + $halfRange = (int)($range/2); + $midTimeT = $minTimeT + $halfRange; + $midTime = strftime( STRF_FMT_DATETIME_DB, $midTimeT ); +} + +//echo "MnT: $tempMinTime, MxT: $tempMaxTime, ExP: $tempExpandable
"; +if ( $tree ) +{ + appendDatetimeRange( $tree, $minTime, $maxTime ); + + $filterQuery = parseTreeToQuery( $tree ); +} +else +{ + $filterQuery = false; +} + +$scales = array( + array( "name"=>"year", "factor"=>60*60*24*365, "align"=>1, "zoomout"=>2, "label"=>STRF_TL_AXIS_LABEL_YEAR ), + array( "name"=>"month", "factor"=>60*60*24*30, "align"=>1, "zoomout"=>12, "label"=>STRF_TL_AXIS_LABEL_MONTH ), + array( "name"=>"week", "factor"=>60*60*24*7, "align"=>1, "zoomout"=>4.25, "label"=>STRF_TL_AXIS_LABEL_WEEK, "labelCheck"=>"%W" ), + array( "name"=>"day", "factor"=>60*60*24, "align"=>1, "zoomout"=>7, "label"=>STRF_TL_AXIS_LABEL_DAY ), + array( "name"=>"hour4", "factor"=>60*60, "align"=>4, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_4HOUR, "labelCheck"=>"%H" ), + array( "name"=>"hour", "factor"=>60*60, "align"=>1, "zoomout"=>4, "label"=>STRF_TL_AXIS_LABEL_HOUR, "labelCheck"=>"%H" ), + array( "name"=>"minute10", "factor"=>60, "align"=>10, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_10MINUTE, "labelCheck"=>"%M" ), + array( "name"=>"minute", "factor"=>60, "align"=>1, "zoomout"=>10, "label"=>STRF_TL_AXIS_LABEL_MINUTE, "labelCheck"=>"%M" ), + array( "name"=>"second10", "factor"=>1, "align"=>10, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_10SECOND ), + array( "name"=>"second", "factor"=>1, "align"=>1, "zoomout"=>10, "label"=>STRF_TL_AXIS_LABEL_SECOND ), +); + +$majXScale = getDateScale( $scales, $range, $chart['grid']['x']['major']['min'], $chart['grid']['x']['major']['max'] ); + +// Adjust the range etc for scale +$minTimeT -= $minTimeT%($majXScale['factor']*$majXScale['align']); +$minTime = strftime( STRF_FMT_DATETIME_DB, $minTimeT ); +$maxTimeT += (($majXScale['factor']*$majXScale['align'])-$maxTimeT%($majXScale['factor']*$majXScale['align']))-1; +if ( $maxTimeT > time() ) + $maxTimeT = time(); +$maxTime = strftime( STRF_FMT_DATETIME_DB, $maxTimeT ); +$range = ($maxTimeT - $minTimeT) + 1; +$halfRange = (int)($range/2); +$midTimeT = $minTimeT + $halfRange; +$midTime = strftime( STRF_FMT_DATETIME_DB, $midTimeT ); + +//echo "R:$range
"; +//echo "MnT:$minTime
"; +//echo "MnTt:$minTimeT
"; +//echo "MdT:$midTime
"; +//echo "MdTt:$midTimeT
"; +//echo "MxT:$maxTime
"; +//echo "MxTt:$maxTimeT
"; + +if ( isset($minTime) && isset($maxTime) ) +{ + $eventsSql .= " and E.EndTime >= '$minTime' and E.StartTime <= '$maxTime'"; +} + +$eventsSql .= " order by Id asc"; +//echo "ESQL: $eventsSql
"; + +$chart['data'] = array( + "x" => array( + "lo" => strtotime( $minTime ), + "hi" => strtotime( $maxTime ), + ), + "y" => array( + "lo" => 0, + "hi" => 0, + ) +); + +$chart['data']['x']['range'] = ($chart['data']['x']['hi'] - $chart['data']['x']['lo']) + 1; +$chart['data']['x']['density'] = $chart['data']['x']['range']/$chart['graph']['width']; + +$monEventSlots = array(); +$monFrameSlots = array(); +$monitorIds = array(); +foreach( dbFetchAll( $eventsSql ) as $event ) +{ + if ( !isset($monitorIds[$event['MonitorId']]) ) + $monitorIds[$event['MonitorId']] = true; + + if ( !isset($monEventSlots[$event['MonitorId']]) ) + $monEventSlots[$event['MonitorId']] = array(); + if ( !isset($monFrameSlots[$event['MonitorId']]) ) + $monFrameSlots[$event['MonitorId']] = array(); + + $currEventSlots = &$monEventSlots[$event['MonitorId']]; + $currFrameSlots = &$monFrameSlots[$event['MonitorId']]; + + $startTimeT = strtotime($event['StartTime']); + $startIndex = $rawStartIndex = (int)(($startTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']); + if ( $startIndex < 0 ) + $startIndex = 0; + + if ( isset($event['EndTime']) ) + $endTimeT = strtotime($event['EndTime']); + else + $endTimeT = time(); + $endIndex = $rawEndIndex = (int)(($endTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']); + + if ( $endIndex >= $chart['graph']['width'] ) + $endIndex = $chart['graph']['width'] - 1; + + for ( $i = $startIndex; $i <= $endIndex; $i++ ) + { + if ( !isset($currEventSlots[$i]) ) + { + if ( $rawStartIndex == $rawEndIndex ) + { + $offset = 1; + } + else + { + $offset = 1 + ($event['Frames']?((int)(($event['Frames']-1)*(($i-$rawStartIndex)/($rawEndIndex-$rawStartIndex)))):0); + } + $currEventSlots[$i] = array( "count"=>0, "width"=>1, "offset"=>$offset, "event"=>$event ); + } + else + { + $currEventSlots[$i]['count']++; + } + } + if ( $event['MaxScore'] > 0 ) + { + if ( $startIndex == $endIndex ) + { + $framesSql = "select FrameId,Score from Frames where EventId = ? and Score > 0 order by Score desc limit 1"; + $frame = dbFetchOne( $framesSql, NULL, array($event['Id']) ); + + $i = $startIndex; + if ( !isset($currFrameSlots[$i]) ) + { + $currFrameSlots[$i] = array( "count"=>1, "value"=>$event['MaxScore'], "event"=>$event, "frame"=>$frame ); + } + else + { + $currFrameSlots[$i]['count']++; + if ( $event['MaxScore'] > $currFrameSlots[$i]['value'] ) + { + $currFrameSlots[$i]['value'] = $event['MaxScore']; + $currFrameSlots[$i]['event'] = $event; + $currFrameSlots[$i]['frame'] = $frame; + } + } + if ( $event['MaxScore'] > $chart['data']['y']['hi'] ) + { + $chart['data']['y']['hi'] = $event['MaxScore']; + } + } + else + { + $framesSql = "select FrameId,Delta,unix_timestamp(TimeStamp) as TimeT,Score from Frames where EventId = ? and Score > 0"; + $result = dbQuery( $framesSql, array( $event['Id'] ) ); + while( $frame = dbFetchNext( $result ) ) + { + if ( $frame['Score'] == 0 ) + continue; + $frameTimeT = $frame['TimeT']; + $frameTimeT = $startTimeT + $frame['Delta']; + $frameIndex = (int)(($frameTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']); + if ( $frameIndex < 0 ) + continue; + if ( $frameIndex >= $chart['graph']['width'] ) + continue; + + if ( !isset($currFrameSlots[$frameIndex]) ) + { + $currFrameSlots[$frameIndex] = array( "count"=>1, "value"=>$frame['Score'], "event"=>$event, "frame"=>$frame ); + } + else + { + $currFrameSlots[$frameIndex]['count']++; + if ( $frame['Score'] > $currFrameSlots[$frameIndex]['value'] ) + { + $currFrameSlots[$frameIndex]['value'] = $frame['Score']; + $currFrameSlots[$frameIndex]['event'] = $event; + $currFrameSlots[$frameIndex]['frame'] = $frame; + } + } + if ( $frame['Score'] > $chart['data']['y']['hi'] ) + { + $chart['data']['y']['hi'] = $frame['Score']; + } + } + } + } +} + +ksort( $monitorIds, SORT_NUMERIC ); +ksort( $monEventSlots, SORT_NUMERIC ); +ksort( $monFrameSlots, SORT_NUMERIC ); + +// No longer needed? +if ( false ) +{ + // Add on missing frames + foreach( array_keys($monFrameSlots) as $monitorId ) + { + unset( $currFrameSlots ); + $currFrameSlots = &$monFrameSlots[$monitorId]; + for ( $i = 0; $i < $chart['graph']['width']; $i++ ) + { + if ( isset($currFrameSlots[$i]) ) + { + if ( !isset($currFrameSlots[$i]['frame']) ) + { + $framesSql = "select FrameId,Score from Frames where EventId = ? and Score > 0 order by FrameId limit 1"; + $currFrameSlots[$i]['frame'] = dbFetchOne( $framesSql, NULL, array( $currFrameSlots[$i]['event']['Id'] ) ); + } + } + } + } +} + +$chart['data']['y']['range'] = ($chart['data']['y']['hi'] - $chart['data']['y']['lo']) + 1; +$chart['data']['y']['density'] = $chart['data']['y']['range']/$chart['graph']['height']; + +$majYScale = getYScale( $chart['data']['y']['range'], $chart['grid']['y']['major']['min'], $chart['grid']['y']['major']['max'] ); + +$maxWidth = 0; +$maxHeight = 0; + +foreach ( array_keys($monitorIds) as $monitorId ) +{ + if ( $maxWidth < $monitors[$monitorId]['Width'] ) + $maxWidth = $monitors[$monitorId]['Width']; + if ( $maxHeight < $monitors[$monitorId]['Height'] ) + $maxHeight = $monitors[$monitorId]['Height']; +} + +//print_r( $monEventSlots ); +// Optimise boxes +foreach( array_keys($monEventSlots) as $monitorId ) +{ + unset( $currEventSlots ); + $currEventSlots = &$monEventSlots[$monitorId]; + for ( $i = 0; $i < $chart['graph']['width']; $i++ ) + { + if ( isset($currEventSlots[$i]) ) + { + if ( isset($currSlot) ) + { + if ( $currSlot['event']['Id'] == $currEventSlots[$i]['event']['Id'] ) + { + if ( $currSlot['width'] < $maxEventWidth ) + { + // Merge slots for the same long event + $currSlot['width']++; + unset( $currEventSlots[$i] ); + continue; + } + elseif ( $currSlot['offset'] < $currEventSlots[$i]['offset'] ) + { + // Split very long events + $currEventSlots[$i]['frame'] = array( 'FrameId'=>$currEventSlots[$i]['offset'] ); + } + } + elseif ( $currSlot['width'] < $minEventWidth ) + { + // Merge multiple small events + $currSlot['width']++; + unset( $currEventSlots[$i] ); + continue; + } + } + $currSlot = &$currEventSlots[$i]; + } + else + { + unset( $currSlot ); + } + } + if ( isset( $currSlot ) ) + unset( $currSlot ); +} +//print_r( $monEventSlots ); + +// Stack events +$frameSlots = array(); +$frameMonitorIds = array_keys($monFrameSlots); +for ( $i = 0; $i < $chart['graph']['width']; $i++ ) +{ + foreach ( $frameMonitorIds as $frameMonitorId ) + { + unset( $currFrameSlots ); + $currFrameSlots = &$monFrameSlots[$frameMonitorId]; + if ( isset($currFrameSlots[$i]) ) + { + if ( !isset($frameSlots[$i]) ) + { + $frameSlots[$i] = array(); + $frameSlots[$i][] = &$currFrameSlots[$i]; + } + else + { + $slotCount = count($frameSlots[$i]); + for ( $j = 0; $j < $slotCount; $j++ ) + { + if ( $currFrameSlots[$i]['value'] > $frameSlots[$i][$j]['value'] ) + { + for ( $k = $slotCount; $k > $j; $k-- ) + { + $frameSlots[$i][$k] = $frameSlots[$i][$k-1]; + } + $frameSlots[$i][$j] = &$currFrameSlots[$i]; + break 2; + } + } + $frameSlots[$i][] = &$currFrameSlots[$i]; + } + } + } +} + +//print_r( $monEventSlots ); +//print_r( $monFrameSlots ); +//print_r( $chart ); + +$graphHeight = $chart['graph']['height']; + +if ( $mode == "overlay" ) +{ + $minEventBarHeight = 10; + $maxEventBarHeight = 40; + + if ( count($monitorIds) ) + { + $chart['graph']['eventBarHeight'] = $minEventBarHeight; + while ( ($chart['graph']['eventsHeight'] = (($chart['graph']['eventBarHeight'] * count($monitorIds)) + (count($monitorIds)-1))) < $maxEventBarHeight ) + { + $chart['graph']['eventBarHeight']++; + } + } + else + { + $chart['graph']['eventBarHeight'] = $maxEventBarHeight; + $chart['graph']['eventsHeight'] = $maxEventBarHeight; + } + $chart['graph']['activityHeight'] = ($graphHeight - $chart['graph']['eventsHeight']); + $chart['data']['y']['density'] = $chart['data']['y']['range']/$chart['graph']['activityHeight']; + + $chart['eventBars'] = array(); + $top = $chart['graph']['activityHeight']; + foreach ( array_keys($monitorIds) as $monitorId ) + { + $chart['eventBars'][$monitorId] = array( 'top' => $top ); + $top += $chart['graph']['eventBarHeight']+1; + } +} +elseif ( $mode == "split" ) +{ + $minActivityBarHeight = 30; + $minEventBarHeight = 10; + $maxEventBarHeight = 40; + + if ( count($monitorIds) ) + { + $chart['graph']['eventBarHeight'] = $minEventBarHeight; + $chart['graph']['activityBarHeight'] = $minActivityBarHeight; + while ( ((($chart['graph']['eventBarHeight']+$chart['graph']['activityBarHeight']) * count($monitorIds)) + ((2*count($monitorIds))-1)) < $graphHeight ) + { + $chart['graph']['activityBarHeight']++; + if ( $chart['graph']['eventBarHeight'] < $maxEventBarHeight ) + { + $chart['graph']['eventBarHeight']++; + } + } + } + else + { + $chart['graph']['eventBarHeight'] = $maxEventBarHeight; + $chart['graph']['activityBarHeight'] = $graphHeight - $chart['graph']['eventBarHeight']; + } + $chart['data']['y']['density'] = $chart['data']['y']['range']/$chart['graph']['activityBarHeight']; + +?> + $top ); + $chart['eventBars'][$monitorId] = array( 'top' => $top+$chart['graph']['activityBarHeight']+1 ); + $top += $chart['graph']['activityBarHeight']+1+$chart['graph']['eventBarHeight']+1; + } +} + +preg_match( '/^(\d+)-(\d+)-(\d+) (\d+):(\d+)/', $minTime, $startMatches ); +preg_match( '/^(\d+)-(\d+)-(\d+) (\d+):(\d+)/', $maxTime, $endMatches ); + +if ( $startMatches[1] != $endMatches[1] ) +{ + // Different years + $title = strftime( STRF_TL_AXIS_RANGE_YEAR1, $chart['data']['x']['lo'] )." - ".strftime( STRF_TL_AXIS_RANGE_YEAR2, $chart['data']['x']['hi'] ); +} +elseif ( $startMatches[2] != $endMatches[2] ) +{ + // Different months + $title = strftime( STRF_TL_AXIS_RANGE_MONTH1, $chart['data']['x']['lo'] )." - ".strftime( STRF_TL_AXIS_RANGE_MONTH2, $chart['data']['x']['hi'] ); +} +elseif ( $startMatches[3] != $endMatches[3] ) +{ + // Different dates + $title = strftime( STRF_TL_AXIS_RANGE_DAY1, $chart['data']['x']['lo'] )." - ".strftime( STRF_TL_AXIS_RANGE_DAY2, $chart['data']['x']['hi'] ); +} +else +{ + // Different times + $title = strftime( STRF_TL_AXIS_RANGE_TIME1, $chart['data']['x']['lo'] )." - ".strftime( STRF_TL_AXIS_RANGE_TIME2, $chart['data']['x']['hi'] ); +} + +function drawXGrid( $chart, $scale, $labelClass, $tickClass, $gridClass, $zoomClass=false ) +{ + global $SLANG; + + ob_start(); + $labelCount = 0; + $lastTick = 0; + unset( $lastLabel ); + $labelCheck = isset($scale['labelCheck'])?$scale['labelCheck']:$scale['label']; +?> +
+ 1 ) + { + $label = (int)(strftime( $labelCheck, $timeOffset )/$scale['align']); + } + else + { + $label = strftime( $labelCheck, $timeOffset ); + } + if ( !isset($lastLabel) || ($lastLabel != $label) ) + { + $labelCount++; + } + if ( $labelCount >= $scale['divisor'] ) + { + $labelCount = 0; + if ( isset($lastLabel) ) + { + if ( $labelClass ) + { +?> +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+
+
+
<?= $SLANG['ViewEvent'] ?>
+
+
+
+
+

+

+

+

+
+
+
+
+ +
+
+
+
+ +
+$slots ) + { + foreach ( $slots as $slot ) + { + $slotHeight = (int)($slot['value']/$chart['data']['y']['density']); + + if ( $slotHeight <= 0 ) + continue; + + if ( $mouseover ) + { + $behaviours = array( + 'onclick="'.getSlotShowEventBehaviour( $slot ).'"', + 'onmouseover="'.getSlotPreviewEventBehaviour( $slot ).'"' + ); + } + else + { + $behaviours = array( + 'onclick="'.getSlotPreviewEventBehaviour( $slot ).'"' + ); + } +?> +
>
+ +
+ +
+$slot ) + { + $slotHeight = (int)($slot['value']/$chart['data']['y']['density']); + + if ( $slotHeight <= 0 ) + continue; + + if ( $mouseover ) + { + $behaviours = array( + 'onclick="'.getSlotShowEventBehaviour( $slot ).'"', + 'onmouseover="'.getSlotPreviewEventBehaviour( $slot ).'"' + ); + } + else + { + $behaviours = array( + 'onclick="'.getSlotPreviewEventBehaviour( $slot ).'"' + ); + } + ?> +
>
+ +
+ +
+ +
>
+ +
+ +
+
+
+
+ + <?= $monitors[$monitorId]['Name'] ?> + +
+
+
+
+
+ + diff --git a/web/skins/bootstrap/views/user.php b/web/skins/bootstrap/views/user.php new file mode 100644 index 000000000..da42a2f25 --- /dev/null +++ b/web/skins/bootstrap/views/user.php @@ -0,0 +1,158 @@ +$SLANG['No'], 1=>$SLANG['Yes'] ); +$nv = array( 'None'=>$SLANG['None'], 'View'=>$SLANG['View'] ); +$nve = array( 'None'=>$SLANG['None'], 'View'=>$SLANG['View'], 'Edit'=>$SLANG['Edit'] ); +$bandwidths = array_merge( array( ""=>"" ), $bwArray ); +$langs = array_merge( array( ""=>"" ), getLanguages() ); + +$sql = "select Id,Name from Monitors order by Sequence asc"; +$monitors = array(); +foreach( dbFetchAll( $sql ) as $monitor ) +{ + $monitors[] = $monitor; +} + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['User']." - ".$newUser['Username'] ); +?> + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/version.php b/web/skins/bootstrap/views/version.php new file mode 100644 index 000000000..2feacbbbe --- /dev/null +++ b/web/skins/bootstrap/views/version.php @@ -0,0 +1,93 @@ + $SLANG['GoToZoneMinder'] +); + +if ( verNum( ZM_DYN_CURR_VERSION ) != verNum( ZM_DYN_LAST_VERSION ) ) +{ + $options = array_merge( $options, array( + "ignore" => $SLANG['VersionIgnore'], + "hour" => $SLANG['VersionRemindHour'], + "day" => $SLANG['VersionRemindDay'], + "week" => $SLANG['VersionRemindWeek'], + "never" => $SLANG['VersionRemindNever'] + ) ); +} + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Version'] ); +?> + +
+ +
+ +

+

+
+ +
+ +

+

+

+
+ +
+ +
+ + +

+

+

+
+ + +
+
+ +
+
+ + diff --git a/web/skins/bootstrap/views/video.php b/web/skins/bootstrap/views/video.php new file mode 100644 index 000000000..9ff0e6a5e --- /dev/null +++ b/web/skins/bootstrap/views/video.php @@ -0,0 +1,241 @@ + + +
+ +
+ +

+
+ +
+ + + + + + + + + + + + + + + + + + + + +
checked="checked"/>
+ disabled="disabled"/> +
+ +

+ + + +

+ +

+ + + + + + + + + + + + + 0 ) + { + preg_match( '/^(.+)-((?:r[_\d]+)|(?:F[_\d]+))-((?:s[_\d]+)|(?:S[0-9a-z]+))\.([^.]+)$/', $file, $matches ); + if ( preg_match( '/^r(.+)$/', $matches[2], $temp_matches ) ) + { + $rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) ); + $rateText = isset($rates[$rate])?$rates[$rate]:($rate."x"); + } + elseif ( preg_match( '/^F(.+)$/', $matches[2], $temp_matches ) ) + { + $rateText = $temp_matches[1]."fps"; + } + if ( preg_match( '/^s(.+)$/', $matches[3], $temp_matches ) ) + { + $scale = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) ); + $scaleText = isset($scales[$scale])?$scales[$scale]:($scale."x"); + } + elseif ( preg_match( '/^S(.+)$/', $matches[3], $temp_matches ) ) + { + $scaleText = $temp_matches[1]; + } + $width = $scale?reScale( $event['Width'], $scale ):$event['Width']; + $height = $scale?reScale( $event['Height'], $scale ):$event['Height']; +?> + + + + + + + + + +
 /  / 
+ +
+
+ + diff --git a/web/skins/bootstrap/views/watch.php b/web/skins/bootstrap/views/watch.php new file mode 100644 index 000000000..0e54b8fd7 --- /dev/null +++ b/web/skins/bootstrap/views/watch.php @@ -0,0 +1,231 @@ + + +
+
+ +
+ +
+
+ +
+ +
+ +
 -  fps
+
+ + + +
+ +
+ + + + + +
+
+ + diff --git a/web/skins/bootstrap/views/zone.php b/web/skins/bootstrap/views/zone.php new file mode 100644 index 000000000..822e1b315 --- /dev/null +++ b/web/skins/bootstrap/views/zone.php @@ -0,0 +1,278 @@ + 0 ) + { + $zone = dbFetchOne( 'SELECT * FROM Zones WHERE MonitorId = ? AND Id=?', NULL, array( $monitor['Id'], $zid ) ); + } + else + { + $zone = array( + 'Name' => $SLANG['New'], + 'Id' => 0, + 'MonitorId' => $monitor['Id'], + 'NumCoords' => 4, + 'Coords' => sprintf( "%d,%d %d,%d, %d,%d %d,%d", $minX, $minY, $maxX, $minY, $maxX, $maxY, $minX, $maxY ), + 'Area' => $monitor['Width'] * $monitor['Height'], + 'AlarmRGB' => 0xff0000, + 'CheckMethod' => 'Blobs', + 'MinPixelThreshold' => '', + 'MaxPixelThreshold' => '', + 'MinAlarmPixels' => '', + 'MaxAlarmPixels' => '', + 'FilterX' => '', + 'FilterY' => '', + 'MinFilterPixels' => '', + 'MaxFilterPixels' => '', + 'MinBlobPixels' => '', + 'MaxBlobPixels' => '', + 'MinBlobs' => '', + 'MaxBlobs' => '', + 'OverloadFrames' => '', + 'ExtendAlarmFrames' => '', + ); + } + $zone['Points'] = coordsToPoints( $zone['Coords'] ); + + $newZone = $zone; +} + +//if ( !$points ) +//{ + //$points = $zone['Points']; +//} + +ksort( $newZone['Points'], SORT_NUMERIC ); + +$newZone['Coords'] = pointsToCoords( $newZone['Points'] ); +$newZone['Area'] = getPolyArea( $newZone['Points'] ); +$selfIntersecting = isSelfIntersecting( $newZone['Points'] ); + +$wd = getcwd(); +chdir( ZM_DIR_IMAGES ); +$command = getZmuCommand( " -m ".$mid." -z" ); +$command .= '"'.$zid.' '.$hicolor.' '.$newZone['Coords'].'"'; +$status = exec( escapeshellcmd( $command ) ); +chdir( $wd ); + +$zoneImage = ZM_DIR_IMAGES.'/Zones'.$monitor['Id'].'.jpg?'.time(); + +$focusWindow = true; + +xhtmlHeaders(__FILE__, $SLANG['Zone'] ); +?> + +
+ +
+
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"applyPreset()", "onblur"=>"this.selectedIndex=0" ) ) ?>
 /  / 
+
+
+
+
+ Zone Image +
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
disabled="disabled"/> disabled="disabled"/>+ 3 ) { ?>  X
+
 
+ disabled="disabled"/> +
+
+
+
+ + diff --git a/web/skins/bootstrap/views/zones.php b/web/skins/bootstrap/views/zones.php new file mode 100644 index 000000000..76d249b61 --- /dev/null +++ b/web/skins/bootstrap/views/zones.php @@ -0,0 +1,105 @@ + + +
+ +
+ + + <?= htmlspecialchars($zone['Name']) ?> + + + + zones +
+ + + + + + + + + + + + + + + + + + + + + + +
 /  disabled="disabled"/>
+
+ disabled="disabled"/> + +
+
+
+
+ +