<?xml version="1.0" encoding="UTF-8"?>
<otherdata xmlns="http://linux.duke.edu/metadata/other" packages="3">
<package pkgid="375c338914da07fc50a7062ca83b4ca84a9a409f97959540c70821b69e4d3950cee0828815441ba5bdfb30b35756aaf3acb7a8539e2f347767e8f0a01930b04e" name="ZoneMinder" arch="src">
  <version epoch="0" ver="1.39.11+git175.c103c403" rel="153.9"/>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1749470400">- update to latest github master zoneminder-1.36.15+git4939.g5406c6b72
  - unsure why version changed in source but is correct from git describe --tags
-Added iproute2 to Requires for ip command</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1751112000">- update to latest github master zoneminder-1.36.15+git4989.g19018e132
  - fix for fix-ZM_VERSION-already-defined-error.patch</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752235200">- update to latest gihub master 1.37.63+git1081.g42a8e38c8
  - unsure why version changed in source but is correct from git describe --tags</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752840000">- update to latest github master zoneminder-1.37.63+git1136.g06636d58f</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1761220800">- update to latest github master zoneminder-1.37.63+git1635.g8636cf14d</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1764072000">- update to latest github master zoneminder-1.37.63+git1799.g2cfed3d8f
- Added pam-config to BuildRequires clear build warning
- Added (but could be optional) mosquitoo &amp; mosquitto-devel for MQTT Broker support
- Added requirement for newer gcc - OBS uses gcc 7 but we need 11+
  Using different version for 15.x and 16.x
- Added -DCMAKE COMPILER flags to use gcc/g++ version 11/15 instead of 7
- Renamed README.SuSE to README.SUSE
- Added if/else for ffmpeg for easier building MP version
- added %global _lto_cflags %{?_lto_cflags} -ffat-lto-objects to fix TW Build</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765281600">- update to latest github master 1.37.63+git1831.g24cdd2dfa
  - Possible Security issue: Only output file if the path is under a storage area.
  Fixes #4472. Also use storage_area-&gt;DiskSpace instead of calculating directory
  space for a speedup.</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765368000">- update to latest github master 1.37.63+git1840.gf0daaaba5</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491200">- update to latest github master 1.37.65+git1450.gf0e5f8cb6</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491201">- revert to 1.37.65+git1422.gfbde89c33 to test onvif problem</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1767096000">- update to latest github master 1.37.65+git1454.g4c2f988aa
  - Adds back ONVIF code for cameras that do not send Off</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1768478400">- update to latest github master 1.37.65+1743.g95f1463a5
- Disabled fix-ZM_VERSION-already-defined-error.patch as
  web/includes/config.php.ini works differently now.
- Update to RTSP-Server-ec9035e</changelog>
  <changelog author="obs@mtlfab.com" date="1771416000">- Update to version 1.38.1+git5.3bb76ff0c:
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316800">- Update to RtspServer a071599
- Update .spec file to remove CxxUrl -devel files no longer present.
- Update to version 1.38.1+git427.6aa39892f:
  * Remove pointless view_ variable
  * Fix width=&gt;Width
  * Handle event having no width or height
  * Remove General header
  * Fixup, more footer to bottom of sidebar
  * fix: add missing global declaration for menu icon override in Options
  * fix: correct stats percentage calculations for percentage-space zone area
  * Move user self edit to auth category
  * Fix Eslint (MonitorStream.js)
  * Code optimization (MonitorStream.js)
  * Code formatting improvements (video-stream.js)
  * Update web/js/MonitorStream.js
  * fix: use text input for menu item image icon path instead of file upload
  * fix: use flex layout for zone edit and fix SVG point index error
  * feat: show both percentage and pixel values in zone edit UI
  * fix: add icons to Save and Reset buttons on options menu tab
  * feat: replace console CSV export with JSON monitor export
  * fix: add missing btn classes to sort button on options menu page
  * Update MonitorStream.js
  * fix: fix import modal FormData error and ensure all menu items exist
  * Put back missing Watch view
  * feat: add Profile column to Notifications table
  * The listener assignment has been moved above the noUiSlider check (MonitorStream.js).
  * Using "manageEventListener" for the 'volumechange' event (MonitorStream.js)
  * fix: use DECIMAL(10,2) for zone threshold columns to hold legacy pixel counts
  * fix: store zone thresholds as percentages and convert to pixels at runtime
  * Bump version to 1.39.3
  * feat: add 'none' icon type, show icons in navbar, fix console column dropdown
  * Fix: Eslint (MonitorStream.js)
  * We'll also try receiving tracks from the stream when playback starts for Go2rtc. (video-stream.js)
  * We use manageEventListener to set and remove listeners for the stream's "play" event. (MonitorStream.js)
  * fix: resolve role-based group permissions not granting stream access
  * feat: add custom icon support to menu items (material, font-awesome, image upload)
  * feat: add customizable navbar/sidebar menu via Options &gt; Menu tab
  * fix: add -- end-of-options marker before filename operands in tar/zip/gzip commands
  * fix: clarify warning message field vs file wording
  * fix: validate getimagesize() return value before accessing width/height
  * fix: add -- to cp -as commands to prevent path/flag confusion
  * Initial plan
  * Initial plan
  * Initial plan
  * Fix: Set the bottom margin for the #events table to 10px (watch.css)
  * feat: add ZM_WEB_FILTER_SETTINGS_POSITION config to control filter panel placement
  * fix: close SQL injection, command injection, and shell escaping gaps
  * Fix: Set color for &lt;pre&gt; tag in dark theme (skin.css)
  * fix: harden web interface against injection and SSRF vulnerabilities
  * fix: escape URL in wget() to prevent command injection in camera probe (GHSA-745h-vg7c-73cg)
  * fix: sync analysis button state with zms-reported analysis image status
  * feat: add player selection dropdown to zone edit view
  * feat: add analysis_image field to stream status for client-side verification
  * fix: auto-detect zone coordinate format instead of trusting Units field
  * fix: sanitize monitor Device path to prevent command injection (GHSA-g66m-77fq-79v9)
  * Instead of "useCapture" we use the extended version "options" (skin.js)
  * Instead of "useCapture" we use the extended version "options" MonitorStream.js
  * fix: sanitize exportFile and connkey params in event export to prevent command injection
  * Try out recommended options for debuild when doing binary
  * sync up RtsPServer
  * Add assets to gitignore
  * fix: silence cmake deprecation and policy warnings in deps
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/log.js
  * Update web/skins/classic/views/log.php
  * Update web/skins/classic/views/js/log.js
  * Rename zm_update-1.37.81.sql zm_update-1.39.2.sql so it actually gets run.
  * Fix: Do not assign mediaStream to the video stream if the video stream has already stopped. (skin.js)
  * fix: refresh auth hash before restarting streams in montage view
  * feat: add reset sort button to console view bootstrap-table toolbar
  * Upgrade bootstrap-table to 1.27.0
  * fix: use +1 instead of +last_duration for equal DTS fixup
  * fix: include alarm_frame_count in ready_count calculation
  * fix: add credential fallback chain in ONVIF control module
  * fix: include port in Server URL methods for port-forwarded setups
  * fix: add_monitors table no longer overflows inaccessibly off-screen
  * feat: add Remember Me checkbox to login page
  * feat(log): Add selection to logs and delete for selected logs.
  * Change warn to debug to prevent log spamming
  * fix: Handle incomplete.mp4 in cpp file.
  * fix(lint): Add spaces before comment
  * feat(logs): New button to clear logs
  * fix: Change ffmpeg errors to warnings for incomplete.mp4
  * Use const for Janus onremotetrack locals
  * Instead of handlerEventListener, we use this.handlerEventListener (MonitorStream.js).
  * fix: address Copilot review feedback on Notifications API refs #4684
  * chore: remove plan docs from repo refs #4684
  * fix: change Notifications FK to ON DELETE CASCADE refs #4684
  * fix: make UserId nullable for no-auth mode refs #4684
  * fix: add FK constraint, auth guard, and belongsTo for Notifications refs #4684
  * Update web/skins/classic/views/options.php
  * Update web/skins/classic/views/options.php
  * feat: add Notification model, controller, and route refs #4684
  * feat: add Notifications table for push token registration refs #4684
  * docs: add implementation plan for notifications API refs #4684
  * docs: add design doc for notifications API refs #4684
  * Fix ReferenceError in Janus onremotetrack handler
  * Removed extra space (skin.js)
  * To assign the 'beforeunload' listener and remove the listener, we now use the ManageEventListener class (MonitorStream.js)
  * Added the ManageEventListener class, which allows for more flexible event listener assignment and removal. (skin.js)
  * No additional check for "this.video" is required; simply adding "this.visibilityCheck = false;" (video-stream.js)
  * Update web/skins/classic/views/js/watch.js
  * Use play() on the VIDEO tag, but not from MonitorStream to avoid recursion (MonitorStream.js)
  * refactor: move HAVE_LIBCURL guards inside class definitions as stubs
  * Apply suggestion from @Copilot
  * fix: prevent segfault when MPEG stream codec fails to open
  * fix: add HAVE_LIBCURL preprocessor guards to fix ZM_NO_CURL=ON build
  * fix: remove conflicting minTime/maxTime fields from montage review download
  * Initial plan
  * Initial plan
  * Initial plan
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/watch.js
  * Update web/skins/classic/views/js/watch.js
  * Fix missing _
  * Fix eslint
  * fix: guard ModelId access with property_exists in Monitor::Model()
  * fix: Replace uppercase cyrillic С with latin C
  * fix: Replace Cyrillic с with a Latin c
  * Correction as recommended by "copilot" (index.php)
  * docs: add zma event re-analysis utility documentation
  * fix: add missing unistd.h include in zma.cpp for FreeBSD build
  * fix: remove unused catch parameter in logger.js to satisfy eslint
  * Update web/skins/classic/js/skin.js
  * When switching monitors, we first destroy the current VolumeSlider and only then change its ID, and not vice versa (watch.js)
  * Removed "waitUntil" since it's now in skin.js (MonitorStream.js)
  * Moved "waitUntil" from MonitorStream.js and now use "waitUntil" to wait until the stream becomes active (skin.js)
  * fix: address review feedback on training PR
  * fix: add SSL certificate verification fallback to base Control class
  * fix: restrict eslint 9 flat config to .js and .js.php files only
  * style: modernize Requires JS to use const/let and jQuery ($j)
  * fix: support arguments in ZM_TRAINING_DETECT_SCRIPT config
  * fix: rebuild data.yaml on annotation delete, code cleanup across training files
  * build(deps): bump crazy-max/ghaction-import-gpg from 6 to 7
  * build(deps): bump actions/upload-artifact from 6 to 7
  * build(deps): bump actions/download-artifact from 7 to 8
  * fix: sync training editor and browse panel on all mutations
  * feat: separate training view from event view with cross-event navigation
  * Update MonitorStream.js
  * feat: add virtual Objects folder to training data browser
  * feat: load saved annotations when editing from browse panel
  * Chore: Optimized saving of "navbar_type" in session and cookies (index.php)
  * feat: Shift+drag to draw box inside existing box, add hint text
  * fix: address Copilot review on Requires implementation
  * feat: implement Config Requires field for dependent option disable
  * fix: use content directory for training data fallback path
  * feat: add edit button in browse preview to navigate back to annotation
  * fix: address Copilot review — path traversal, temp leak, double undo, help text
  * Fix: Eslint (MonitorStream.js)
  * fix: nav guard for unsaved annotations, pending box warnings, UX polish
  * Fix: Receive audio and video tracks only for the active stream (skin.js)
  * Fix: When checking isJSON(), if it is not JSON, warn in the browser console (skin.js)
  * fix: improve TRAINING_DATA_DIR help text for empty path behavior
  * fix: code review fixes, version bump to 1.39.1, remove non-repo files
  * feat: two-panel training data file browser with preview and inline delete
  * feat: add annotate button to objdetect modal, compact stats, delete-all, UI polish
  * fix: remove newlines from BackgroundImageConfirm SLANG entry
  * fix: internationalize all hardcoded user-visible strings
  * fix: allow saving background images and delete pending boxes
  * fix: rename Cancel to Exit, smaller buttons, prevent status line wrap
  * fix: green for accepted boxes, remove label dropdown, leave caps
  * fix: use ZM_EVENT_IMAGE_DIGITS for frame filename padding
  * feat: add Detect button to run object detection on current frame
  * fix: annotation UI improvements and remove objdetect frame
  * fix: remove ZM_DIR_EVENTS derivation from migration
  * fix: guard migration against NULL ZM_DIR_EVENTS
  * feat: add custom model training annotation UI
  * fix: pin @eslint/js to &lt;10 to fix CI eslint dependency conflict
  * Fix: If an RTSP2Web type RTC error occurs, restart the stream instead of killing it (MonitorStream.js)
  * Update MonitorStream.js
  * Fix: Use lowercase when searching for the current go2rtc mode (MonitorStream.js)
  * Fix: Saving "navbar_type" in cookies (index.php)
  * Fix: Apply z-index=3 to the Event page as well (skin.css)
  * Fix: Don't assign "resize" listener when using Observer (zone.js)
  * fix: zmDbDo error logging now substitutes all SQL placeholders with values
  * fix: improve JS error logging for undefined messages and cross-origin errors
  * fix: use portable %jd format for chrono duration count
  * fix: auto-detect and convert pixel zone coordinates to percentages in web layer
  * Satisfy eslint, but also log the error
  * Put back .deb builds on master
  * Only .imageFeed will have the alarm/idle border. Not the img within it or video or anything else. Fixes extra borders and streams jumping around as borders appear/disappear
  * fix: use ResizeObserver for zone point positioning on initial load
  * In "src," use '_CameraDirectPrimary' instead of '_0' in "createGo2rtcStream" (skin.js).
  * The z-index for "svg.zones" cannot exceed the index value for ".zonePoint" (skin.css)
  * For ".imageFeed svg.zones" apply z-index: 100 (skin.css)
  * To determine the go2rtc stream type, use "currentMode" instead of "mode" (MonitorStream.js)
  * Support for getTracksFromStream() and getMonitorStream() for Zones &amp; Zone pages (skin.js)
  * Do not adjust MSE delay if streamStartTime is undefined. (MonitorStream.js)
  * feat: integrate EventStream into montagereview with zms recovery and fixes
  * fix: upgrade ESLint config to v9 flat config format
  * Fix: Check the "players" variable (MonitorStream.js).
  * fix: use DOM img element and rAF loop for MJPEG stream reception
  * feat: add EventStream.js for persistent MJPEG event playback
  * Fix RCE vulnerability via API config edit privilege escalation
  * fix: store speed value instead of index in montagereview cookie
  * fix: improve montage review playback smoothness and fix video seek overshoot
  * fix: calculate optimal thumbnail overlay scale from monitor dimensions
  * Automatically a2enmod rewrite
  * fix: link stdc++fs for std::filesystem on GCC 8 and add zma to RPM spec
  * Add Create to canEdit
  * Add Create to canEdit
  * Fix: PanZoom. When scale &gt; 1, prevent the player from responding to image clicks (panzoom.js)
  * fix: add zma binary to redhat zoneminder.spec file list
  * Fix: Assign toggleZones listener only after Event page loads (event.js)
  * fix: mobile layout for monitor and watch views
  * Hide the #delay block when the stream starts (MonitorStream.js)
  * Push to master repo
  * Push to master repo
  * Don't audit log logins
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Add intel-gpu-tools to recommended packages
  * Add intel_gpu_top view
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * feat: add AUDIT logging level for tracking administrative changes
  * feat: store zone coordinates as percentages for resolution independence
  * Bump to 1.39
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * feat: add pushState URL state management for events page filters
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Log commands used when updating db
  * Add ZoneMinder.spec from OBS project
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams
  * fix: use int instead of unsigned int for zone pixel coordinates in zm_zone.cpp
  * feat: expand ONVIF config_types with full device/media/imaging/PTZ queries
  * fix: clamp zone polygon extents to actual frame dimensions in CheckAlarms
  * Removed styles for GridStack, since in version 12 styles are now generated dynamically (montage.css)
  * I created some slightly rounded corners for the streams, tables, and navigation block: .imageFeed, .nav, .fixed-table-body, id='videoFeedStream*' (skin.css)
  * Fix: Eslint (skin.js)
  * Changed the style for ".monitor" a bit (watch.css)
  * Added styles for id=liveStream* (skin.css)
  * Merging and moving two identical functions monitorsSetScale from montage.js and watch.js to skin.js
  * Moving "monitorsSetScale" function from to skin.js (watch.js)
  * Wrap "#dvrControls" and "#extButton" in a single DIV "#bottomBlock" for correct scaling in scale=Auto mode (watch.php)
  * Moving "monitorsSetScale" function from montage.js to skin.js (montage.js)
  * feat: add --protocol mode to zmcontrol.pl for direct module testing
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Fix Eslint (MonitorStream.js)
  * Fix space (MonitorStream.js)
  * Calculate the playback start time (video-stream.js)
  * Fix: Don't clear the screen when animations are off
  * When executing "onmse" save "MediaSource" in a class variable (video-rtc.js)
  * Feat: Moved some code to the "manageMSESocket" function (MonitorStream.js)
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * Added an "onplay" event triggered when playback starts (video-rtc.js)
  * Add intel-gpu-tools to recommended packages
  * Fix space (video-rtc.js)
  * Code optimization (video-rtc.js)
  * RTSP2Web support (watch.js)
  * Fix; Eslint (watch.js)
  * Update video-stream.js
  * Fix: If you click “pause”, then hide the page and display it again after at least 15 seconds, the stream will still be paused and not start (as it was before) (watch.js)
  * Added "zmsState" and its processing (MonitorStream.js)
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Code optimization (MonitorStream.js)
  * Code optimization (watch.js)
  * Code optimization (watch.js)
  * Now we use destroyVolumeSlider() when changing the player and when changing the monitor. (watch.js)
  * Changed the destroy method for VolumeSlider (MonitorStream.js)
  * Start playback using a promise (video-rtc.js)
  * Revert MonitorStream.js
  * Update video-rtc.js
  * Add intel_gpu_top view
  * Fix: Display volumeSlider when switching monitors on the Watch page (MonitorStream.js)
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * #volumeControls always includes the monitor ID (MonitorStream.js)
  * Fix: Fix desync between audioStream.muted and MonitorStream.muted (MonitorStream.js)
  * Completely remove noUiSlider from volumeSlider, not just destroy it. (watch.js)
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Destroy the "VolumeSlider" when switching to another monitor. (watch.js)
  * Optimizing "VolumeSlider" (MonitorStream.js)
  * streamPause() in pauseClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('pause'... event is triggered. (event.js)
  * Log commands used when updating db
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Add ZoneMinder.spec from OBS project
  * streamPlay() in playClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('play'... event is triggered. (event.js)
  * feat: add pushState URL state management for events page filters
  * feat: add AUDIT logging level for tracking administrative changes
  * Fix: Event handling for VID (event.js)
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * build: add selective man3 generation for audited Perl modules
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * fix: update heartbeat during camera close and reconnect
  * Add 4px border-radius to thumbnail img
  * fix: correct App::uses package path in CameraModel
  * Fix: Stop executing "streamQuery" if "zmsBroke" (event.js)
  * Color input[type='checkbox'], input[type='radio'] on dark skin (skin.css)
  * Fix: Color of some buttons on a dark skin (skin.css)
  * fix: warn when zone coordinates extend beyond image dimensions
  * fix: skip V4L2 AutoSelectFormat in non-capture mode
  * fix: remove file_exists() gate on /dev/video in settings modal
  * perf: replace sleep polling with condition wait in Event::Run()
  * perf: reduce lock contention in PacketQueue
  * fix: preserve legacy execlp() behavior for commands without % tokens
  * fix: shell-escape %EC% token to prevent command injection
  * feat: support token substitution in EventStartCommand/EventEndCommand
  * Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * refactor: remove unused reuse_image_ member to keep changes minimal
  * refactor: use reusable reuse_filepath_ member in EventStream::sendFrame
  * Initial plan
  * feat: store zone coordinates as percentages for resolution independence
  * fix: resolve "no url in button" when adding detected cameras
  * refactor: move format_absolute_time_iso8601 from zm_monitor_onvif to zm_time
  * Remove fatal version check. Just error.
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * Bump to 1.39
  * feat: add option to use system-installed jwt-cpp</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316801">- Add intel-gpu-tools to recommended packages</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773835200">- spec file improvements:
  * Removing perl-Archive-Tar requires, as it's part of the perl package.
  * Using autopatch macro.
  * Reordering MP macros/sections
  * Better gcc handling for version &lt; 1600
  * Added ZoneMinder-rpmlintrc</changelog>
  <changelog author="obs@mtlfab.com" date="1776254400">- Update to version 1.38.1+git566.2a29e6318:
  * fix: HLS fragment tracking, live playback, and fallback handling
  * Don't pass null as first parameter to strtotime().
  * fix: convert zone threshold columns to DECIMAL before running conversion procedure
  * chore(deps): Bump softprops/action-gh-release from 2 to 3
  * feat: add HLS byte-range playback for event video
  * Fix: For "nouislider.min.css" we use "cache_bust", i.e. disabling caching when the file changes. (functions.php)
  * Update sidebar.css
  * Fix: More correct ".sidebar-footer" style (functions.php)
  * Force memory release of GDImage for PHP &gt;= 8.0.
  * Conditionally calls imagedestroy() as it was deprecated since PHP 8.0 doing nothing except logging errors.
  * Check for /proc/meminfo before reading its content. There is no such proc file system on FreeBSD, hence http server logs a lot of errors.
  * fix: guard MSE addSourceBuffer against detached MediaSource
  * Use qx() lc() and chomp() for command execution and result. Use eq in the if() statement, instead of '=='.
  * fix: prevent empty events in ONDEMAND mode and fix VideoStore fd/codec leaks
  * Change ::Config{uname} to ::Config{ZM_PATH_UNAME}
  * fix: scan-line polygon fill incorrectly filled non-convex polygon gaps
  * Use ZoneMinder::Config.
  * fix: exclude orig tarball from deb uploads to zmrepo
  * Fix "top" command parsing on FreeBSD (tested in FreeBSD 13.5 jail, running 1.38.1).
  * fix: show Device text input when no device is selected on load
  * fix: run form validation on Save button click
  * fix: only validate Device path for Local monitors
  * fix: limit filter Name input to 64 characters
  * fix: add missing dash separator in Content-Range header
  * fix: treat ENOTTY like EINVAL when querying V4L2 JPEG compression options
  * fix: call disconnect() in MonitorLink::connect() before reopening map_fd
  * Move the delay calculation code to after we run the filter so that the time taken running the filter is included
  * Rename last_action to last_reload as that is what it actually is
  * Include ExecuteInterval in warning
  * fix: free video_out_ctx after failed avcodec_open2 in new_extradata path
  * fix: fd leak in MonitorLink::disconnect() when connect() fails
  * Don't use Fatal when there is an error preparing the sql. handle PostSQLConditions being an empty array
  * Include ExecuteInterval in warning
  * Use now instead of 0 when no last_ran so that elapsesd=0 on initial run, and we don't log a warning.
  * fix: redirect stdin/stdout/stderr to /dev/null instead of closing them
  * Warn() -&gt; Warning().  Fixes #4724
  * fix: add Warn() as exported alias for Warning() in Logger
  * fix: reset last_write_index in Pause to restore DECODING_ONDEMAND bootstrap
  * Update options.css
  * Do not use the "form-control-sm" class for rows. (options.php)
  * fix: guard against empty auth_relay producing double &amp;&amp; in zms URLs
  * Fix missing quotes
  * Bump up ubuntu and python version for readthedocs
  * fix: guard against null websocket in VideoRTC.onopen
  * fix: use shoelace formula for zone threshold pixel-to-percent migration
  * fix: null-check StorageId column in Monitor::Load to prevent segfault
  * Upgrade bootstrap-table to 1.27.1
  * fix: add DTS backward jump detection in ffmpeg camera capture
  * Update MonitorStream.js
  * Update MonitorStream.js
  * Revert watch.php
  * fix: clamp user bandwidth before defining ZM_WEB_* constants
  * chore: remove obsolete ZM_FILTER_EXECUTE_INTERVAL config option
  * fix: use minimum per-filter delay instead of last filter's delay in zmfilter
  * fix: use prepare instead of prepare_cached in Filter::Execute
  * fix: clear accumulated state in Filter::Sql() before rebuilding
  * Set style for "div.volume" (skin.css)
  * SPAN tag replaced with DIV tag (watch.php)
  * SPAN tag replaced with DIV tag (functions.php)
  * Added missing UL tag (functions.php)
  * Remove extra space (functions.php)
  * Fix: Removed extra space and extra slash (functions.php)
  * Update web/skins/classic/views/watch.php
  * Include full path in warning when fail to cache bust
  * Log the value when event_close_mode is unkown
  * fix: handle HTTP-to-HTTPS redirect in Reolink_HTTP login
  * fix: prefer MJPEG over raw YUV in V4L2 AUTO palette selection
  * fix: add missing CLOSE_DURATION event close mode handling
  * Added a link to the PR (watch.php)
  * Prevent vertical shifting of #content on the Watch page when displaying the stream status overlay. (watch.php)
  * When executing monitorChangeStreamChannel(), always write the new channel to the cookie and to monitorStream.currentChannelStream (watch.js).
  * Don't use "scrollTo" because it doesn't work properly. (console.js)
  * Silent refresh bootstrapTable on Console page (console.js)
  * wip
  * wip
  * When starting a stream on the Watch page, don't execute controlMute() (watch.js)
  * If the system volume was set to 0, change the state of the "Mute" icon in the volume slider (MonitorStream.js)
  * fix: preserve fractional percentages in zone threshold migration
  * A finger-shaped pointer cursor for the hide/show password buttons (skin.css)
  * Read from 'zmWatchMuted' cookies instead of 'zmWatchMute' (watch.js)
  * fix: include username in auth relay and fix stale auth in stream restart
  * Add br after USE ONVIF events
  * fix: add event-id latch to linked monitor score detection
  * fix: reduce linked monitor reconnect throttle from 60s to 1s
  * Set "pointer-events: none" for "imgInfoBlock" and "infoBlock" to disable pointer events for them (MonitorStream.js)
  * When stopping a stream, execute writeTextInfoBlock after checking the existence of the stream (MonitorStream.js)
  * Normalizing text before assigning it to a DOM element
  * feat: add ZM_WEB_SHOW_SERVER_STATS config to toggle navbar stats
  * Instead of "setTextSizeOnInfoBlock," we now use the new "setTextSizeOnInfoBlocks" function, which sets the text size for all blocks. (skin.js)
  * Instead of explicitly specifying the text size, we use a call to the new function "setTextSizeOnInfoBlock" (MonitorStream.js)
  * feat: add ZM_WEB_SHOW_NAV_BUTTONS config to hide Back/Refresh buttons
  * feat: add ZM_WEB_BUTTON_STYLE config for icons+text, icons, or text buttons
  * Fix: Eslint (MonitorStream.js)
  * Remove extra space (skin.js)
  * When a stream is loaded, paused, or stopped, display a corresponding caption in the center of the stream player. (MonitorStream.js)
  * feat: make Remember Me a tri-state option (None/Yes/No)
  * Added styles for 3D text (skin.css)
  * Added calculation of the text size displayed in the information block (skin.js)
  * fix: strip &lt;br/&gt; from bootstrap-table column picker labels
  * fix: compact montage header layout and move Show Zones to settings row
  * Don't add postLoginQuery to url if it is empty
  * Move tag related commands to canView(Events) instead of canEdit(Events)
  * Updated .spec for OpenSUSE - Corrected
  * Updated .spec for OpenSUSE
  * Increase potential config line size. HTML snippets can easily be larger than 256</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1778760000">- Update to version 1.38.1+git876.2b1627e2:
  * fix: flush decoder_queue on decoder thread exit to avoid stale latency offset across reconnect
  * perf: index Sessions.access and rework session gc to two-phase delete
  * fix: derive event end time from Length when EndDateTime is missing
  * fix: align auth hash validation with generation and warn on user mismatch
  * fix: sanitize reflected user input in ajax error messages
  * fix: remove reflected user input from log ajax XSS sinks
  * fix: do not return SQL error text to client in events ajax
  * fix: remove reflected user input from events ajax XSS sinks
  * Update sidebar.css
  * fix: sanitize download params at event ajax boundary
  * Minor optimization of the sidebar footer box (sidebar.css)
  * fix: sanitize export filename and connkey at event ajax boundary
  * fix: remove reflected user input from event ajax XSS sink
  * fix: remove reflected user input from device ajax XSS sinks
  * fix: remove reflected user input from add_monitors XSS sink
  * feat: recalibrate ZonePresets for modern HD resolutions
  * fix: clamp percentage polygon to width-1/height-1
  * Potential fix for pull request finding
  * Potential fix for pull request finding
  * fix: QP-encode plain-text email body so URLs survive transit
  * Update log.php
  * Fix: Yesli v sessii byl sokhraneno znacheniye "Components", yavlyayushcheyesya pervym elementom massiva "$components", to ono ignorirovalos' pri formirovanii "$selected_component" (log.php) Privesti ZM_WEB_REFRESH_LOGS k tipu INT pered sravneniyem (log.php) YA ne ponimayu, pochemu tip znacheniya `ZM_WEB_REFRESH_LOGS` stanovitsya str, a ne int. Ved' `ZM_WEB_REFRESH_LOGS` poluchayetsya iz `ZM_WEB_*_REFRESH_LOGS`, kotoryye v baze dannykh khranyatsya kak integer. YA vnes ispravleniya v kod https://github.com/ZoneMinder/zoneminder/pull/4819/changes/06f1178a99f6985c9b9c625c3812a576e993de0e, no ya khochu razobrat'sya, pochemu i gde proiskhodit zamena tipov. Vot zapros i rezul'taty zamera. Pervyy zamer - obychnyy indeks. Vtoroy zamer pokryvayushchiy indeks Raznitsa v skorosti vypolneniya boleye 10 raz i eto pri smeshchenii vsego 250000 Dobavil podderzhku konstanty ZM_WEB_REFRESH_LOGS (log.php) Feat: Dobavil nastroyku dlya obnovleniya okna Log page (ConfigData.pm.in) Dobavil konstantu ZM_WEB_REFRESH_LOGS (config.php) Isaac, tebya chto-to ne ustraivayet? Ozhidayu tvoi kommentarii, zamechaniya. Schitayu dannyy PR zakonchennym Poprosi pozhaluysta Copilot proverit' dannyy PR Dobavit' v pervichnyy indeks Component, TimeKey, Level dlya uvelicheniya skorosti obrabotki zaprosov Ispol'zovaniye JOIN podzaprosa pozvolyayet uskorit' vypolneniye osnovnogo zaprosa v 10-20 raz bystreye. Tak-zhe sleduyet proizvodit' otbor po stolbtsu 'Level', a ne 'Code', t.k. imenno 'Level' u nas indeksiruyetsya Optimizatsiya medlennykh SQL zaprosov pri bol'shoy tablitse Optimizirovannyy zapros Dlya optimizitsii zaprosov s ispol'zovaniye podzaprosa Ne posylat' AJAX zaprosy obnovleniya tablitsy, yesli stranitsa skryta (log.js) Eto znachitel'no snizit nagruzku na server. T.k. seychas, yesli otkryt' mnogo Log page i svernut' ikh, to zaprosy postoyanno postupayut na server! Da, kak ya i dumal, rasshireniye mozhet byt' mp4 or mkv or webm (kak dlya zakonchennogo fayla, tak i dlya incomplete), po etomu ya izmenil shablon dlya poiska. YA ne stal perechislyat' vse vozmozhnyye rasshireniya, t.k. v budushchem oni mogut izmenit'sya. Izmenen shablon okhvatyvayushchiy fayly s lyubym rasshireniyem, t.k. ono mozhet byt' mp4 or mkv or webm (functions.php) Dopolnitel'naya proveka sushchestvovaniya fayla Chto by my ne vernuli ssylku na nesushchestvuyushchiy fayl Khotya.... Fayl ved' imeyet takoye imya: `incomplete.h264.mp4`, t.ye. shablon `/incomplete.*.mp4` yavlyayetsya korrektnym. Vozmozhno sleduyet ispol'zovat' shablon `/incomplete*.*`? @connortechnology Chto ty dumayesh' naschet etogo? Eto ne moya oshibka, ona poyavilas' v kode iz za kommita https://github.com/ZoneMinder/zoneminder/commit/3f8bc81760071f49bdce894c664cd507820dcfaa Pri kopirovanii koda ya ne proveril i eto plokho s moyey storony. Zdes' ya ispravlyu, no tak-zhe neobkhodimo ispravit' i v `web/views/view_video.php‎ ` Obrabatyvat' $Event-&gt;DefaultVideo() vsegda kak stroku Vozmozhno eto izlishnyaya proverka, no pust' budet tak... YA reshil proanalizirovat', iz za chego poyavlyayutsya tormoza v SQL i uzhasnoye potrebleniye pamyati. YA vklyuchil logirovaniye medlennykh zaprosov i uzhasnulsya.... YA nakhodilsya na 3y stranitse prosmotra logov (po 25 strok na stranitsu). YA pereshel na 75823 stranitsu (da, u menya 1674290 strok ) Pochemu-to ne verno rasschityvayetsya kol-vo stranits, no s etim pozzhe mozhno razobrat'sya.... I vot chto ya uvidel v medlennykh zaprosakh: U menya yest' mysl', kak uskorit' rabotu SQL s bol'shimi tablitsami. YA poprobuyu. Put' k faylu dlya sobytiya KHKHKH ne nayden Ne naydeno ni odnogo fayla sobytiya dlya eksporta sobytiy monitora s ID=18. Dobavil proverki 3 462 Fix: If the "Components" value, which is the first element of the "$components" array, was stored in the session, it was ignored when generating "$selected_component" (log.php)
  * Cast ZM_WEB_REFRESH_LOGS to INT before comparison (log.php)
  * build(deps): bump actions/dependency-review-action from 4 to 5
  * Fix: Save the selected "All" value in the "zmLogComponent" session (log.php)
  * Preventative loop protection ZM_WEB_REFRESH_LOGS=0 (log.php)
  * Added support for the ZM_WEB_REFRESH_LOGS constant (log.php)
  * Updated description (ConfigData.pm.in)
  * Added the ZM_WEB_REFRESH_LOGS constant (config.php)
  * Feat: Added a setting for refreshing the Log page window (ConfigData.pm.in)
  * Fix: Correct calculation of the total number of pages for pagination with filters (log.php)
  * Apply style only to "#pills-tab" (monitor.css)
  * FIx enmod rewrite
  * Potential fix for pull request finding
  * Pass the $encoding parameter to mb_strtolower/mb_strtoupper (functions.php)
  * Potential fix for pull request finding
  * Optimizing the menu style on the Monitor pagemonitor.css
  * Fix: Annoying error getting $file_path due to ".$file" (image.php)
  * fix: honor explicit port argument in urlToApi single-server case
  * fix: urlToApi falls back to location.host in single-server case
  * Update lang.php
  * Moved the "mb_ucfirst" function to \includes\functions.php (functions.php)
  * Moving the "mb_ucfirst" function from \skins\classic\includes\functions.php And adding a new "mb_lcfirst" function (functions.php)
  * Feat: Search for translations without regard to the case of the first letter (lang.php)
  * If the index.m3u8 file is missing, then MP4HLS is disabled in the select (event.php)
  * feat: encoder parameter templates with editor + REST API closes #4778 closes #4802
  * Feat: Added codec="MP4HLS" (event.php)
  * Update view_video.php
  * More correct assignment of the $path_info value (view_video.php)
  * Update ru_ru.php
  * Instead of "MP4" we will specify "video" (event.php)
  * Potential fix for pull request finding
  * feat: add Report::canEdit() and CreatedBy column
  * ci: skip CodeQL on changes that contain no scanned languages
  * ci: add scheduled workflow to prune old Actions caches
  * Avoid PHP Notice (view_video.php)
  * Fix: Pop-up file name on download button (event.php)
  * Fix: Loading incomplete.mp4 event file (view_video.php)
  * Fix: Display snapshot for incomplete event file (Update image.php)
  * Fix a2enmod cgi =&gt; a2enmod rewrite causing install to fail.
  * Add depenencies for resolute raccoon
  * Analyzing "space" and "," key presses for positioning in the tag input field (event.js)
  * fix: use HTTP_X_FORWARDED_FOR in auth hash validation to fix AUTH_HASH_IPS with reverse proxy
  * Initial plan
  * fix: ensure trigger_state written last in zmTriggerEventOn to fix 1/3 event trigger rate
  * Initial plan
  * Prevent the scrollbar from appearing when displaying table column visibility settings (options.css)
  * Added $CLANG (lang.php)
  * Potential fix for pull request finding
  * docs: document all ONVIF_Options key=value pairs
  * Initial plan
  * Revert "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"
  * fix: PR #4742 round 2 review feedback
  * fix: silence spurious Overlay subpixel-order warning post-AVPixelFormat
  * fix: PR #4742 review feedback + drop stray u_buffer assignments
  * Tag Management Optimization (event.js)
  * Update files.php
  * Added table styles (files.css)
  * Fix: .tags-container on Event page if screen is narrow and there are many tags (skin.css)
  * Fix: ESLint (audioMotionAnalyzer.js)
  * fix: parse HTTP Range header correctly in output_file() fixes #4777
  * build: add Profile CMAKE_BUILD_TYPE for perf/flamegraph
  * fix: bail from MonitorStream::runStream when monitor failed to load
  * To avoid overriding the zmVlang() function (en_gb.php)
  * Merge an array from a custom language file and en_gb.php (lang.php)
  * Update ru_ru.php
  * Correction of the Russian translation (ru_ru.php)
  * Chore: Minor UI optimization for ".tags-container" on the Event page (skin.css)
  * fix: parse audioMotionAnalyzer.js as module so ESLint succeeds
  * Change from translate('What display') to translate('Show') (event.php)
  * Fix: Eslint (skin.js)
  * In applyTemplateAudioMotionTranslation() , execute createClickableLink() &amp; replaceDoubleTildeToBR() (monitor.js)
  * Revert (lang.php)
  * Added replaceDoubleTildeToBR() &amp; createClickableLink() function (skin.js)
  * perf: skip clearPackets early-returns and allow drop-to-iterator-keyframe
  * Apply ".flex-col-2" and ".flex-col-3" to all pages, not just the User page (skin.css)
  * Added ".flex-col-3" for "#frames" (event.php)
  * Changed style for "#frames img" (event.css)
  * Chore: Minor improvements to statistics display on the Event page (event.css)
  * customElements.define moved after the class declaration (audioMotionAnalyzer.js)
  * Abort checkVerAudioMotion() if we couldn't get the CURRENT_AUDIO_MOTION_ANALYZER_VERSION value (monitor.js)
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Fix: https://github.com/ZoneMinder/zoneminder/pull/4752#discussion_r3158319612 (user.php)
  * For now, apply the "legend" style only to the User page (skin.css)
  * Update web/skins/classic/css/base/skin.css
  * Update web/lang/en_gb.php
  * Potential fix for pull request finding
  * Don't use "await" when calling "insertModalHtml()" (options.js)
  * fix: clean up ONVIF subscription before re-Subscribe to stop NotAuthorized loop
  * Update image.php
  * Update image.php
  * Prevent an error from being generated when processing the file "index.m3u8" (image.php)
  * We'll now pause audioMotion in MonitorStream.js. (MonitorStream.js)
  * Added the pauseAudioMotion() function. (skin.js)
  * Now we will pause audioMotion in MonitorStream.js (watch.js)
  * Avoid reinitializing audioMotion if the previous one has not yet finished. (audioMotionAnalyzer.js)
  * Remove  extra "&lt;" (event.php)
  * Instead of " use ' (console.js)
  * Added id="header" (event.php)
  * Apply "chosen" to the Event page (event.php)
  * Update console.php
  * When using ONVIF, the console page should not display simply "Use ONVIF Events", but should also indicate which event the trigger is configured for. (console.js)
  * Bump version to 1.39.5
  * The missing comma has been restored (zm_update-1.39.5.sql)
  * If WhatDisplay already exists, ensure it is the right enum
  * - Added support for "~~" =&gt; &lt;br/&gt; for translation - Now we only specify the supported analyzer version in one place in the audioMotionAnalyzer.js file - Added translations for three cases: when the analyzer is not installed, the wrong version is installed, or everything is fine.
  * Added `WhatDisplay` to the 'Monitors' table (zm_create.sql.in)
  * Upload audioMotionAnalyzer.js to the Monitor page (functions.php)
  * - Style optimization. - Added support for the "flex-col-X" class, where X can be 2 or 3. This is used in cases where, for example, we need to display a theoretical 3 columns, but 1 or 2 of them may not be displayed in certain cases. The remaining columns will then take up all available space. Can be used in conjunction with "col-md/lg-*", which will be placed inside "flex-col-X".
  * Fix: bootstrap legend (skin.css)
  * Adjusting the display of the "infoBlock" block (MonitorStream.js)
  * Create zm_update-1.39.5.sql
  * Safely using $_REQUEST['title'] and $_REQUEST['key'] (delconfirm.php)
  * Update options.js
  * Update version
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Update web/skins/classic/views/js/options.js
  * Set retention-days: 1
  * Added missing spaces. (options.js)
  * Added translations.
  * - Added the ability to specify a title for the window in the \ajax\modals\delconfirm.php file. - Added the "DeleteUser" function to be executed when the "Delete" button is clicked.
  * Display a modal window confirming the deletion of a user (options.js)
  * Align the thumbnail on the Console page horizontally to the center of the table cell (console.css )
  * Layout optimization
  * fix: restore getCycleHTML for Watch/Cycle navbar item refs #4745
  * Update skin.css
  * Layout optimization
  * Moved .button-block from options.css to skin.css
  * Layout optimization (_options_api.php)
  * Layout optimization (options.php)
  * Added style for ".button-block" (options.css)
  * Optimizing styles for the Options page (options.css)
  * Update ru_ru.php
  * Added Russian translation (ru_ru.php)
  * feat: add G.711 μ-law (PCMU) audio support to zm_rtsp_server
  * fix: coerce null ParentId to '' for array offsets in groups view
  * Added support for audioMotion-analyzer.js in various formats (audioMotionAnalyzer.js)
  * Update audioMotionAnalyzer.js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Analyzing AUDIO_MOTION_ENABLED and checking $whatDisplay using strtolower (Monitor.php)
  * Analysis of AUDIO_MOTION_ENABLED (montage.php)
  * fix: skip sws_scale for identity conversions in Image::Assign
  * Delete web/skins/classic/assets/audioMotion-analyzer/src/audioMotion-analyzer.js
  * Create help.txt
  * Added analysis of the AUDIO_MOTION_ENABLED constant (Monitor.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant for $htmlAudioControlPanel (montage.php)
  * Added analysis of the selectorWhatDisplay variable (montage.js)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (montage.php)
  * style: fix eslint errors in onvif probe js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (watch.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Added function checkAudioMotionEnabled() (audioMotionAnalyzer.js)
  * fix: YUV422P passthrough and libjpeg grayscale for planar YUV
  * Added translation for OPTIONS_WHATTODISPLAY (en_gb.php)
  * Added translation for OPTIONS_WHATTODISPLAY (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (en_gb.php)
  * Change requiresAudioMotionEnabled -&gt; RequiresAudioMotionEnabled (monitor.php)
  * Added handling of the AUDIO_MOTION_ENABLED constant to ensure correct operation in the absence of the "audioMotion-analyzer.js" file. "monitor.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" "functions.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" (skin.js.php)
  * Correct operation without the "audioMotion-analyzer.js" file
  * fix: use decoded frame's native pixel format instead of Monitor.Colours
  * fix: compute Camera linesize/imagesize from pixelFormat, not hardcoded YUV420P
  * fix: use zm_bytes_per_pixel for pixel-rendering dispatch instead of GRAY8-only
  * fix: handle YUVJ422P/YUV422P in zm_colours_from_pixformat
  * fix: sync imagePixFormat in WriteBuffer, Assign, and AssignDirect
  * fix: replace ZM_COLOUR_*/ZM_SUBPIX_ORDER_* with AVPixelFormat for format dispatch
  * feat: install SIGPIPE handler in zms for clean browser-disconnect shutdown
  * fix: guard changeFilters against invalid date input in montagereview
  * Update web/skins/classic/views/js/onvifprobe.js
  * Update web/skins/classic/views/js/onvifprobe.js
  * fix: use full codec profile strings in canPlayCodec feature detection
  * fix: strip SKIP LOCKED from EXPLAIN query in filter debug modal
  * fix: sort events by Tags column alias, not T.Name
  * fix: log bind params correctly when SQL contains literal % characters
  * perf: default ffmpeg decoder thread_count to 2
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (ru_ru.php)
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (en_gb.php)
  * Added a description of some possible value options for recognizing ONVIF events (monitor.php)
  * Apply suggestion from @Copilot
  * style: replace size attribute with CSS width on manual URL input
  * feat(onvif): add manual camera URL entry to ONVIF probe
  * Removed extra semicolons (watch.js)
  * Added translation for "OPTIONS_WHATTODISPLAY" en_gb.php
  * Load audioMotionAnalyzer.js only on Watch, Montage, and Event pages (functions.php)
  * We'll use $cspNonce (functions.php)
  * Update web/skins/classic/js/skin.js
  * Declare constants (skin.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/views/montage.php
  * Update web/skins/classic/views/watch.php
  * Instead of audioMotion.play(), use audioMotion.init() (MonitorStream.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/js/skin.js
  * Set maxFPS=30 instead of 50 (audioMotionAnalyzer.js)
  * Feat: Run changeWhatDisplay() without refreshing the page (watch.js)
  * Update skin.js
  * Fix: Eslint (MonitorStream.js)
  * skin.js - Clear IconMute when executing destroyVolumeSlider() - Added the ability to clear the icon state to changeStateIconMute()
  * Removed an unused constant
  * Fix: Eslint
  * Creating a volume slider on the Montage page to simultaneously control the volume of all monitors
  * Add changeWhatDisplay() (event.js)
  * Add $whatDisplay (event.php)
  * Add "#whatDisplayControl" (event.php)
  * Fix parent
  * If we don't display the video, then display the information block on "#monitorXX"
  * Style adjustments
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Added audio visualization
  * Update functions.php
  * Added &lt;audio-motion&gt; (Monitor.php)
  * Loading "nouislider" and "audioMotion-analyzer" (functions.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1780315200">- Update to version 1.38.1+git1083.97755a96:
  * If the requested Object isn't found in the database, generate a Warning instead of an Error. (Object.php)
  * Use hostname obtained via "parse_url", do not use regular expression to obtain IPv4 (onvifprobe.php)
  * Apply suggestions from code review
  * Now we don't need to return "$monitor-&gt;Id()" because we can get Monitor.Id after Id has become public. (monitor_probe.php)
  * We use Monitor.Id again instead of MonitorId, since Id is now publick
  * "Id" is now public, not protected.  (Monitor.php)
  * Update skin.js
  * When closing SIDEBAR_MAIN_EXTRUDER, reset its z-Index (skin.js)
  * Replaced "stream.Monitor.Id" with "stream.MonitorId" (add_monitors.js)
  * Use "parse_url" instead of "preg_match" when determining hosts (onvifprobe.php)
  * The added class must be escaped using htmlspecialchars() (functions.php)
  * I added ".chosen" in STEP 2. (onvifprobe.php)
  * Removed extra parentheses (monitor_probe.php)
  * fix: widen DefaultScale columns to preserve fit_to_width
  * Added the "controlHeader" class to the filter block on the Events page (Filter.php)
  * Fix Aligning input fields (sidebar.css)
  * Changed the style of the active button in "nav #pills-tab" for the dark theme (monitor.css)
  * Changed the style of the active button in "nav #pills-tab" (monitor.css)
  * Apply scrollbar style to all elements (skin.css)
  * Remove "Loading, please wait" if nothing is found (add_monitors.js)
  * Removed unused const "Monitor" (add_monitors.js)
  * Pass 'MonitorId' in the returned array, since the private method does not pass the monitor ID. (monitor_probe.php)
  * Correctly get Monotor.Id for editing a monitor (add_monitors.js)
  * More readable text color for the DBG level for the dark theme (log.css)
  * Added the ability to specify a class for &lt;select&gt;&lt;option&gt; in the htmlSelect() function (functions.php)
  * Added a style (onvifprobe.css)
  * Optimized the drop-down list of found monitors. (onvifprobe.php)
  * Apply suggestions from code review
  * Added style for .chosen-container
  * Use "Chosen" on Onvifprobe page (onvifprobe.php)
  * Fix: Correct reading of zmWatchMuted cookies
  * fix: avoid OOB read on negative gsoap error codes in ONVIF Subscribe fixes #4842
  * fix: keep DefaultVideo as mp4 name throughout event lifecycle refs #4839
  * fix: polyfill str_starts_with/str_ends_with/str_contains for PHP 7
  * fix: make zm_update-1.39.10.sql idempotent for reruns
  * More correctly retrieves Component from $_REQUEST and writes it to the session (log.php)
  * More correct retrieval of zmLogFilterLevel from session (log.php)
  * fix: keep console summary row aligned when toggling event columns
  * More correct parsing of $_REQUEST['level'] before assigning its value to $L (log.php)
  * fix: string-compare BIGINT counters in zmaudit CAS skip checks
  * Potential fix for pull request finding
  * Correctly save setCookie('zmWatchMuted') when "=false" (MonitorStream.js)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * feat: refresh auth hash and retry on MonitorStream image error
  * fix: enrich zms auth-failure warning with diagnostic fields
  * fix: only show 'Use ONVIF' badge on console when listener is enabled
  * Edited comment (log.js)
  * Potential fix for pull request finding
  * fix: CAS-guard Event_Summaries UPDATE in zmaudit to preserve concurrent writes
  * fix: chunk zmstats bucket-prune DELETE IN-list to avoid packet-size limits
  * fix: CAS-style Storage DiskSpace update in zmaudit to preserve concurrent adjustments
  * fix: use $dbh-&gt;do for SET TRANSACTION to preserve the next-TX isolation level
  * fix: skip zmDbDo success Debug when inside a caller-managed transaction
  * Prevent the "#clearLogsBtn" status from appearing active after clicking the "#clearLogsConfirmBtn" button. The issue was related to an unnecessary call to manageClearButtonAvailability() (log.js)
  * Potential fix for pull request finding
  * Open and close the session only once per page refresh. (log.php)
  * More accurate page navigation and statistics display (log.js)
  * refactor: simplify Event::delete bind-list to a plain SQL list
  * fix: track Event_Summaries enumerate failure as partial resync in zmaudit
  * perf: restrict zmstats ES resync to monitors with pruned buckets
  * fix: avoid DB-backed logging inside zmDbDo when caller manages the transaction
  * fix: reset step/send_twice in MonitorStream CMD_STOP; reset stopped in EventStream.js lifecycle
  * fix: address review feedback - endian decode, send_twice init, setLastViewed, curr_frame_id gating
  * fix: track per-row UPDATE failures in zmaudit ES and Storage resync
  * docs: clarify per-monitor UPDATE lock state in zmstats resync
  * docs: reference the actual Event::Event constructor in lock-order block
  * fix: log Error in Event::delete when deadlock retries are exhausted
  * docs: expand triggers.sql lock-order block with full writer list
  * docs: document atomicity tradeoff in zmstats/zmaudit ES resync
  * fix: don't log Error on deadlock inside a caller-managed transaction
  * refactor: route VideoStore destructor through finalize() refs #4757
  * fix: VideoStore filename use-after-free + null-oc destructor guard refs #4757
  * fix: drop DefaultVideo extension check from \$has_hls refs #4757
  * Avoid endless AJAX table update requests if the query returned 0 rows on the Log page. (log.js)
  * Renamed session 'ZM_LOG_FILTER_LEVEL' to 'zmLogFilterLevel' (log.php)
  * Save the selected filter level in the session (log.php)
  * Managing the availability of the clear logs button (log.js)
  * revert: stop forcing DefaultVideo='index.m3u8' for HLS events refs #4757
  * fix: drain VideoStore reorder_queues inside finalize() refs #4757
  * fix: don't force HLS when user explicitly picked MP4 codec refs #4757
  * fix: disable video.js liveui so HLS scrubbing works on in-progress events refs #4757
  * fix: report served mp4 filename in view_video.php Content-Disposition refs #4757
  * fix: stop view_hls.php emitting /zm/index.php?index.php?view=… refs #4757
  * fix: pick HLS player when index.m3u8 exists, not from DefaultVideo refs #4757
  * fix: keep DefaultVideo='index.m3u8' for events with an HLS manifest refs #4757
  * perf: scope Event neighbor queries to Id only
  * fix: stop warning on URL/session user mismatch in getAuthUser
  * fix: correct HLS fragment byte-range and duration tracking refs #4757
  * fix: use getSkinFile() for _monitor_filters.php include path in console.php
  * typo
  * fix: guard ZM_WEB_REFRESH_LOGS against missing Config row
  * Since kFreeBSD was amd64 and i386 archs only, remove unnecessary checks
  * Fix FreeBSD arm builds
  * Fix: ".chosen-drop" should always be in the foreground (sidebar.css)
  * Fix: Fixed overlapping ".eventStats" and dropdown tags (event.css)
  * fix: use getFilterSelection() and validCardinal() per reviewer feedback
  * Use ConfirmDeleteGroups instead of ConfirmDelete
  * Listen for the "click" event for #delConfirmBtn only once. (skin.js)
  * Potential fix for pull request finding
  * fix: use filter_var FILTER_VALIDATE_INT for stricter ID validation in queryRequest
  * fix: GroupId filter persists after browser refresh on Console view
  * Initial plan
  * fix: avoid HierarchyRequestError in submitThisForm on console view
  * Update ru_ru.php
  * Correction and addition of the Russian translation (ru_ru.php)
  * The column order in the component index has been changed, and Logs_Component_idx has been removed, as it's now redundant.
  * When the page is hidden, execute hideLoading() for the bootstrap table, then execute an empty return instead of executing the AJAX request.
  * Set $maxTime to the current time only if $endSecs is missing in the incomplete event or if $maxTime is empty after looping through all events. (download_functions.php)
  * Return false instead of return "" (download_functions.php)
  * Potential fix for pull request finding
  * Server -&gt; ServerId mapping for sorting in a SQL table (log.php)
  * Added composite secondary index (zm_create.sql.in)
  * Potential fix for pull request finding
  * Added a missing space.
  * Don't execute AJAX requests from bootstrap-table if the page is hidden.
  * For now, we'll only search for "mp4" files (download_functions.php)
  * The "findVideoEventFile()" function takes a file extension as an argument (functions.php)
  * Gjntdownload_functions.php
  * Fix: Missing space (log.js)
  * Update log.php
  * Potential fix for pull request finding
  * Fix: Search (log.php)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed. (zm_create.sql.in)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed.  zm_update-1.39.10.sql
  * Feat: Optimizing slow SQL queries for large tables (log.php)
  * Fix: space (log.js)
  * Don't send AJAX table update requests if the page is hidden (log.js)
  * The template has been changed to cover files with any extension, since it could be mp4, mkv, or webm (functions.php)
  * Additional file existence check (functions.php)
  * Always treat $Event-&gt;DefaultVideo() as a string (functions.php)
  * Added checks (download_functions.php)
  * Potential fix for pull request finding
  * Added findVideoEventFile ($Event) function (functions.php)
  * Code optimization (download_functions.php)
  * Fix: Correct end timestamp of events when exporting MP4 for multiple events (download_functions.php)
  * docs: identify the 1213 magic number as MariaDB ER_LOCK_DEADLOCK
  * fix: check SELECT errors in zmstats bucket-prune loop
  * fix: don't zero Event_Summaries counters on aggregate SELECT failure in zmaudit
  * docs: correct Event::delete lock-order comment to match triggers.sql
  * docs: document canonical Events lock acquisition order in triggers.sql
  * perf: snapshot bucket aggregates instead of joining in Event_Summaries resync
  * fix: rollback and retry Event::delete under deadlock at READ COMMITTED
  * feat: auto-retry zmDbDo on InnoDB deadlock errno 1213
  * Replacing $j('#eventTable') with tableControlCaps (controlcaps.js)
  * Replaced random Russian text with English Display a message when a report deletion error occurs instead of updating a non-existent '#reportsTable' (report.js)
  * Replaced casual Russian text with English (skin.js)
  * Update groups.js
  * Get the "form" for an element (groups.js)
  * Use $report-&gt;canEdit() instead of canEdit('Events') (reports.php)
  * Removed warning in the browser console if the manageDelConfirmModalBtns() function is not found (skin.js)
  * Lost "?" (ru_ru.php)
  * docs: document CMD_PLAY vs CMD_VARPLAY and CMD_STOP in MsgCommand enum
  * fix: improve stopped state handling in EventStream run loop
  * fix: add stopped state for CMD_STOP, fixing paused=true response bug
  * Initial plan
  * Fix: ESLint
  * - Moved the getDelConfirmModal() function from options.js to skin.js - Removed the getDelConfirmModal() function (and its call) from report.js, options.js, reports.js, devices.js, +++controlcaps.js(?view=options&amp;tab=control), and snapshots.js. This is because it's now a single function in skin.js, which is called when the "Delete" button is pressed, rather than during page initialization. - Slightly modified the local functions of manageDelConfirmModalBtns(). Removed the listener, so the code is executed immediately. - You can now call local functions from the global getDelConfirmModal() function (instead of just executing submitThisForm() ). Applies to report.js, reports.js, devices.js, controlcaps.js, snapshots.js - Changed the style of the "Delete" button on the Groups page - Added deletion confirmation to the Storage, Roles, and Groups pages - On the Event page, deletion permissions were broken. Deletes were allowed for those who did NOT have edit permissions, but deletions were blocked for those who did. ! - On the Report page, deletion didn't work and still doesn't work. This needs to be addressed, or maybe it's possible to delete reports only on the Reports page. (FIXED...) - On the Devices page, the "canEdit.Device" permissions check was being performed, but it should be performed like this: "canEdit.Devices" - The $action variable was not defined in \ajax\devices.php - Added translations. - Added a style for the disabled "Delete" button - Minor fixes
  * - Added the DeleteServer() function - Pass the "formName" argument when calling getDelConfirmModal() - Added a translation
  * Changed the "Delete" button to confirm deletion of selected servers (_options_servers.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1781265600">- Update to version 1.39.11+git175.c103c403:
  * fix: delete FifoSources before RemoveSession on reconnect failure
  * fix: bound ONVIF SOAP timeouts below zmdc 30s kill window
  * fix: correct stale SharedData and TriggerData offsets in PHP shm map
  * fix: probe mp4 duration for events with no capture jpgs in zmrecover
  * chore: remove dead statusCmd code and debug logging from watch.js
  * Attempt to fix case where a console bootstrap table query gets cancelled and so you get no results
  * feat: add LTS CMIP3CD42WI-28AISP white-light control row refs #4895
  * fix: re-auth retry on supplementLight GET for long-lived control daemons
  * feat: add white-light (CanLight) control to HikVision/LTS module refs #4895
  * fix: align positional Controls seed rows with CanLight/CanIndicatorLight columns
  * When getting the value for "form.elements['newMonitor[RTSPStreamName]']" and "form.elements['newMonitor[Recording]']", check for the presence of the elements themselves. (monitor.js.php)
  * Fix: The absence of "#zones-tab" should not result in errors on the Monitor page. (monitor.js)
  * Fix ESLint (skin.js)
  * Added $data['getLogStatusHTML'] = logState() (status.php)
  * Feat: When updating the status panel, also update the status logs (skin.js)
  * Optimizing the waitUntil() function (skin.js)
  * Insert the file name as "text" and not "html" (export.js)
  * Apply suggestions from code review
  * Fixed a regression in retrieving tracks from a stream. (skin.js)
  * When looping through players, check if it's enabled for the monitor. (MonitorStream.js)
  * refactor: remove dead FfmpegCamera::imagePixFormat field
  * fix: include &lt;libavutil/pixdesc.h&gt; in zm_pixformat.h (PR #4788)
  * feat: refresh auth hash on tab resume, redirect to login on dead session refs #4748
  * fix: nullptr-safe pix fmt name in Colourise/Deinterlace_4Field error paths (PR #4788)
  * Delete jquery.panzoom.min.js as unused and without bug fixes
  * Update version jquery.panzoom - Release 4.6.2 (2026-04-02)
  * Update Panzoom 4.6.2 (jquery.panzoom.js)
  * Recovered the spaces lost by Copilot (MonitorStream.js)
  * Potential fix for pull request finding
  * Returned container.appendChild(stream) for createGo2rtcStream() (skin.js)
  * Write "is not" instead of "has not" (view_hls.php)
  * Fix: ESLint (export.js)
  * Don't perform a new AJAX request to check for file existence if the previous one hasn't yet completed.  (export.js)
  * We'll limit ourselves to transferring no more than 100 links and additional file name validation. (event.php)
  * Added a missing space. (MonitorStream.js)
  * Fix: Iterating over players for Player=Auto mode (MonitorStream.js)
  * Potential fix for pull request finding
  * fix: pass delta8_* fn ptrs directly; zm_get_pix_fmt_name in Delta panic (PR #4788)
  * fix: Deinterlace_Discard OOB write on odd heights (PR #4788)
  * Prevent pointless setInterval(this.statusCmdQuery) calls for "frozen" objects. (MonitorStream.js)
  * Interrupt getTracksFromStream() if the stream has been stopped. (skin.js)
  * Restored the missing &lt;canvas&gt; for audioVisualization (Monitor.php)
  * Fix: ESLint (MonitorStream.js)
  * Added error handling. (video-rtc.js)
  * Added error handling. (video-stream.js)
  * Correctly iterates through players when the Player = "Auto" mode is selected. (MonitorStream.js)
  * Deleted the unnecessary line (Event.php)
  * Check the response of file_get_contents() for "false" (view_hls.php)
  * Remove extra space (skin.js)
  * Do not execute checkM3u8File() for live viewing. (skin.js)
  * Allow overflow for "#contentForm" (monitor.css)
  * fix: preserve port and decode url-encoded passwords in parse_ControlAddress
  * Changed the cursor style for &lt;textarea&gt; (skin.css)
  * We will prohibit the use of the ../ combination in paths. (event.php)
  * Apply suggestions from code review
  * fix: more actionable error messages in GetImage/getSnapshot/WriteBuffer (PR #4788)
  * docs: correct epoch-to-UTC time in test comment refs #4870
  * fix: Image(AVFrame*) ctor delegates to default ctor before AssignDirect (PR #4788)
  * chore: bump redhat spec version to 1.39.11
  * chore: bump version to 1.39.11
  * fix: Image::Assign(Image&amp;) handle smaller-source linesize; explicit pixdesc.h (PR #4788)
  * feat: add Indicator LED control capability with session keepalive refs #4875
  * feat: add status-aware Light control capability and control-command response path refs #4869
  * feat: add HiSilicon Hi3510 CGI PTZ control module
  * feat: add Dahua/Amcrest RPC PTZ control module with per-model Controls refs #120
  * feat: re-assert zm.pid in zmdc main loop so systemd keeps tracking refs #4874
  * Fix: Correct state of the "Delete" button if we have only one file in the directory (files.js)
  * fix: Image::Assign(uint8_t*) handle packed source -&gt; aligned dest (PR #4788)
  * fix: apply filter result limit when an empty Tags term is present
  * fix: stop pinning libcurl4-gnutls-dev, fixing curl -dev conflict
  * fix: enforce per-event ACL on direct media endpoints (GHSA-vj5r-pc2v-gfwv)
  * fix: store event StartDateTime with second precision to match disk path refs #4870
  * fix: handle "no frames yet" sentinel before bounds check (PR #4788)
  * fix: use canonical imagePixFormat in Image::Assign(AVFrame*) (PR #4788)
  * fix: free previously-owned buffer in AssignDirect(AVFrame); nullptr-safe logs (PR #4788)
  * Removed "action" parameter from streamCmdStop() as deprecated (watch.js)
  * Apply suggestions from code review
  * When executing the streamCmdStop() command, always stop the stream regardless of the passed "action" parameter.  (watch.js)
  * fix: keep linked event open while source monitor is in ALERT state
  * fix: retain keyframe images so snapshot.jpg is written for pre-event frames refs #4843
  * fix(packetqueue): destroy packets after releasing mutex; drop dead code
  * fix: guard SHM pixformat publish on assign failure (PR #4788)
  * - Optimized setButtonStates() - Added a hidden &lt;INPUT&gt; element to correctly submit the form via JS - Added Russian and English translations for ConfirmDeleteFiles
  * - DIR_EXPORTS_DOWNLOAD is not passed to JS, but is used only in PHP. - When making an AJAX request, we pass an array of file paths relative to DIR_EXPORTS_DOWNLOAD , not absolute ones. - Check $fileName for a non-empty string. - Clear fileExistencePollingInterval if it exists before calling again. - More correctly retrieve parameters from the "el.href" string using "new URL(el.href)". - Disabled the cursor for "a.disabled".
  * Update skin.js
  * Added deleteFiles() (files.js)
  * Confirming file deletion on the Files page (files.php)
  * fix: switch remaining av_get_pix_fmt_name calls in zm_ffmpeg_camera.cpp to zm_ wrapper
  * - Correct HLS playback on the Watch page - When executing Event-&gt;Length() , get the duration of the recorded event file if the duration in the database table is 0 - If native HLS playback fails in Safari, we first try playing MP4, and only if MP4 playback fails do we switch to MJPEG playback
  * fix: nullptr-safe pixfmt name; route GetImage/getSnapshot through ReadShmFrame (PR #4788)
  * fix: SHM padding covers both alignment adjustments (PR #4788)
  * Fix error (export.js)
  * Replaced "let" with "const" (export.js)
  * Added AJAX action='file_existence_check' Added the DIR_EXPORTS_DOWNLOAD constant from PHP to JS Added a style for "#downloadModal a.disabled" on the Events page
  * Removed unnecessary debug information (export.js)
  * If the download file was deleted after downloading, we make the download link for the file inactive. (export.js)
  * fix: per-row Overlay; align image_pixelformats SHM pointer (PR #4788)
  * perf: emit sargable range queries for Date/StartDate/EndDate filter terms
  * fix: stride-aware Delta and Deinterlace_4Field (PR #4788)
  * fix: PopulateFrame error handling + canonical pix fmt in Scale (PR #4788)
  * fix: keep DeColourise/AssignDirect(AVFrame) state self-consistent (PR #4788)
  * fix: Camera::linesize/imagesize back to tightly-packed (PR #4788)
  * fix: ceiling chroma dims in Rotate/Flip; clearer Assign error (PR #4788)
  * fix: dest linesize in HighlightEdges, ceiling chroma dims in MaskPrivacy (PR #4788)
  * Switch to MP4 playback instead of HLS only if a fatal HLS error occurs.
  * Apply suggestions from code review
  * fix: report AVPixelFormat in Panic messages for actionable diagnosis (PR #4788)
  * fix: linesize/planar correctness for Overlay, Rotate, Flip, AssignDirect(AVFrame) (PR #4788)
  * If a defective MP4 video stops or freezes (checking the current time every 1 second), execute fallbackToMjpeg(). (skin.js)
  * Added the data-event-start attribute to the img on the Watch page (watch.php).
  * Before getting infoStatusBar, check for the presence of a statusBar (skin.js)
  * Add a 250ms delay to all thumbnail_onmouseover() code. (skin.js)
  * - Do not check the M3u8 file if currentView === 'frames' - When executing Length() and Duration() , do not write the result to the database. - When assigning a value to the "data-video-duration-secs" attribute, first check the Length in $row['Length'] and, if it is 0, only then check the file's Duration. - If the M3u8 file is missing or invalid, do not cache the server response.
  * Apply suggestions from code review
  * fix: address remaining width-vs-linesize and planar chroma issues (PR #4788)
  * fix: fully invalidate Image on AssignDirect(AVFrame) format failure (PR #4788)
  * fix: use linesize for row stride in pixel ops (PR #4788)
  * Update skin.js
  * fix: cross-process AVPixelFormat sync for alarm_image (PR #4788)
  * Added comment (Event.php)
  * Duration is only saved to the database if it's greater than zero. (Event.php)
  * Added a private Duration() method as a synonym for the Length() method. (Event.php)
  * Use $event-&gt;Duration() instead of "($event-&gt;EndDateTimeSecs() - $event-&gt;StartDateTimeSecs())" (events.php)
  * fix: address PR #4788 review comments on planar sizing and SHM bounds
  * fix: address PR #4788 review comments on SHM publish ordering and overlay bounds
  * fix: only emit HLS/duration attrs for events with video (events.php)
  * fix: address PR #4788 review comments on AVPixelFormat migration
  * Added the m3u8Exists constant, which is used to decide how to play the video. (skin.js)
  * If the m3u8 manifest doesn't contain fragments, then instead of outputting to the page body, save the message in the logs as Warning, since we're passing status code 204.  (view_hls.php)
  * Update skin.js
  * Picky ESLint (skin.js)
  * Before raising statusBar.innerHTML, we check for the presence of a statusBar. (skin.js)
  * Before loading the "index.m3u8" manifest in hls.js, always check the server response status and load the manifest only if the response status is 200. (skin.js)
  * The "data-video-hls-src" attribute should always reference the "index.m3u8" manifest file, even if the physical file is missing. (events.php)
  * If the "index.m3u8" manifest file is missing or if the manifest is invalid, the return status code is 204 instead of 404. (view_hls.php)
  * Removed extra semicolons (skin.js)
  * Fixed cookie reading and video launch for native HLS. (skin.js)
  * Fixed the value assignment for "$args['view']" (Event.php)
  * Fix: ESLint (skin.js)
  * Added support for HLS playback when hovering over the thumbs.(skin.js)
  * Added the "data-video-duration-secs" attribute to VIDEO (events.php)
  * Option to generate 'view=view_hls' (Event.php)
  * Add a link to playback the recorded event using HLS to the IMG tag if there is an index.m3u8 file. (events.php)
  * feat: SHM cross-process format consistency via per-slot AVPixelFormat
  * fix: planar YUV correctness + alignment in Image methods
  * Reapply "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"</changelog>
</package>
<package pkgid="f5386e7223e49a50090429042c4c8dd2a657fcb8db0b03d0fccb20e09bdcf1bd54d11973a3f85caa6b1115add60a23ca3072ad2b01c477f01d422f88630bcf5a" name="ZoneMinder" arch="x86_64">
  <version epoch="0" ver="1.39.11+git175.c103c403" rel="153.9"/>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1749470400">- update to latest github master zoneminder-1.36.15+git4939.g5406c6b72
  - unsure why version changed in source but is correct from git describe --tags
-Added iproute2 to Requires for ip command</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1751112000">- update to latest github master zoneminder-1.36.15+git4989.g19018e132
  - fix for fix-ZM_VERSION-already-defined-error.patch</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752235200">- update to latest gihub master 1.37.63+git1081.g42a8e38c8
  - unsure why version changed in source but is correct from git describe --tags</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752840000">- update to latest github master zoneminder-1.37.63+git1136.g06636d58f</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1761220800">- update to latest github master zoneminder-1.37.63+git1635.g8636cf14d</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1764072000">- update to latest github master zoneminder-1.37.63+git1799.g2cfed3d8f
- Added pam-config to BuildRequires clear build warning
- Added (but could be optional) mosquitoo &amp; mosquitto-devel for MQTT Broker support
- Added requirement for newer gcc - OBS uses gcc 7 but we need 11+
  Using different version for 15.x and 16.x
- Added -DCMAKE COMPILER flags to use gcc/g++ version 11/15 instead of 7
- Renamed README.SuSE to README.SUSE
- Added if/else for ffmpeg for easier building MP version
- added %global _lto_cflags %{?_lto_cflags} -ffat-lto-objects to fix TW Build</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765281600">- update to latest github master 1.37.63+git1831.g24cdd2dfa
  - Possible Security issue: Only output file if the path is under a storage area.
  Fixes #4472. Also use storage_area-&gt;DiskSpace instead of calculating directory
  space for a speedup.</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765368000">- update to latest github master 1.37.63+git1840.gf0daaaba5</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491200">- update to latest github master 1.37.65+git1450.gf0e5f8cb6</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491201">- revert to 1.37.65+git1422.gfbde89c33 to test onvif problem</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1767096000">- update to latest github master 1.37.65+git1454.g4c2f988aa
  - Adds back ONVIF code for cameras that do not send Off</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1768478400">- update to latest github master 1.37.65+1743.g95f1463a5
- Disabled fix-ZM_VERSION-already-defined-error.patch as
  web/includes/config.php.ini works differently now.
- Update to RTSP-Server-ec9035e</changelog>
  <changelog author="obs@mtlfab.com" date="1771416000">- Update to version 1.38.1+git5.3bb76ff0c:
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316800">- Update to RtspServer a071599
- Update .spec file to remove CxxUrl -devel files no longer present.
- Update to version 1.38.1+git427.6aa39892f:
  * Remove pointless view_ variable
  * Fix width=&gt;Width
  * Handle event having no width or height
  * Remove General header
  * Fixup, more footer to bottom of sidebar
  * fix: add missing global declaration for menu icon override in Options
  * fix: correct stats percentage calculations for percentage-space zone area
  * Move user self edit to auth category
  * Fix Eslint (MonitorStream.js)
  * Code optimization (MonitorStream.js)
  * Code formatting improvements (video-stream.js)
  * Update web/js/MonitorStream.js
  * fix: use text input for menu item image icon path instead of file upload
  * fix: use flex layout for zone edit and fix SVG point index error
  * feat: show both percentage and pixel values in zone edit UI
  * fix: add icons to Save and Reset buttons on options menu tab
  * feat: replace console CSV export with JSON monitor export
  * fix: add missing btn classes to sort button on options menu page
  * Update MonitorStream.js
  * fix: fix import modal FormData error and ensure all menu items exist
  * Put back missing Watch view
  * feat: add Profile column to Notifications table
  * The listener assignment has been moved above the noUiSlider check (MonitorStream.js).
  * Using "manageEventListener" for the 'volumechange' event (MonitorStream.js)
  * fix: use DECIMAL(10,2) for zone threshold columns to hold legacy pixel counts
  * fix: store zone thresholds as percentages and convert to pixels at runtime
  * Bump version to 1.39.3
  * feat: add 'none' icon type, show icons in navbar, fix console column dropdown
  * Fix: Eslint (MonitorStream.js)
  * We'll also try receiving tracks from the stream when playback starts for Go2rtc. (video-stream.js)
  * We use manageEventListener to set and remove listeners for the stream's "play" event. (MonitorStream.js)
  * fix: resolve role-based group permissions not granting stream access
  * feat: add custom icon support to menu items (material, font-awesome, image upload)
  * feat: add customizable navbar/sidebar menu via Options &gt; Menu tab
  * fix: add -- end-of-options marker before filename operands in tar/zip/gzip commands
  * fix: clarify warning message field vs file wording
  * fix: validate getimagesize() return value before accessing width/height
  * fix: add -- to cp -as commands to prevent path/flag confusion
  * Initial plan
  * Initial plan
  * Initial plan
  * Fix: Set the bottom margin for the #events table to 10px (watch.css)
  * feat: add ZM_WEB_FILTER_SETTINGS_POSITION config to control filter panel placement
  * fix: close SQL injection, command injection, and shell escaping gaps
  * Fix: Set color for &lt;pre&gt; tag in dark theme (skin.css)
  * fix: harden web interface against injection and SSRF vulnerabilities
  * fix: escape URL in wget() to prevent command injection in camera probe (GHSA-745h-vg7c-73cg)
  * fix: sync analysis button state with zms-reported analysis image status
  * feat: add player selection dropdown to zone edit view
  * feat: add analysis_image field to stream status for client-side verification
  * fix: auto-detect zone coordinate format instead of trusting Units field
  * fix: sanitize monitor Device path to prevent command injection (GHSA-g66m-77fq-79v9)
  * Instead of "useCapture" we use the extended version "options" (skin.js)
  * Instead of "useCapture" we use the extended version "options" MonitorStream.js
  * fix: sanitize exportFile and connkey params in event export to prevent command injection
  * Try out recommended options for debuild when doing binary
  * sync up RtsPServer
  * Add assets to gitignore
  * fix: silence cmake deprecation and policy warnings in deps
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/log.js
  * Update web/skins/classic/views/log.php
  * Update web/skins/classic/views/js/log.js
  * Rename zm_update-1.37.81.sql zm_update-1.39.2.sql so it actually gets run.
  * Fix: Do not assign mediaStream to the video stream if the video stream has already stopped. (skin.js)
  * fix: refresh auth hash before restarting streams in montage view
  * feat: add reset sort button to console view bootstrap-table toolbar
  * Upgrade bootstrap-table to 1.27.0
  * fix: use +1 instead of +last_duration for equal DTS fixup
  * fix: include alarm_frame_count in ready_count calculation
  * fix: add credential fallback chain in ONVIF control module
  * fix: include port in Server URL methods for port-forwarded setups
  * fix: add_monitors table no longer overflows inaccessibly off-screen
  * feat: add Remember Me checkbox to login page
  * feat(log): Add selection to logs and delete for selected logs.
  * Change warn to debug to prevent log spamming
  * fix: Handle incomplete.mp4 in cpp file.
  * fix(lint): Add spaces before comment
  * feat(logs): New button to clear logs
  * fix: Change ffmpeg errors to warnings for incomplete.mp4
  * Use const for Janus onremotetrack locals
  * Instead of handlerEventListener, we use this.handlerEventListener (MonitorStream.js).
  * fix: address Copilot review feedback on Notifications API refs #4684
  * chore: remove plan docs from repo refs #4684
  * fix: change Notifications FK to ON DELETE CASCADE refs #4684
  * fix: make UserId nullable for no-auth mode refs #4684
  * fix: add FK constraint, auth guard, and belongsTo for Notifications refs #4684
  * Update web/skins/classic/views/options.php
  * Update web/skins/classic/views/options.php
  * feat: add Notification model, controller, and route refs #4684
  * feat: add Notifications table for push token registration refs #4684
  * docs: add implementation plan for notifications API refs #4684
  * docs: add design doc for notifications API refs #4684
  * Fix ReferenceError in Janus onremotetrack handler
  * Removed extra space (skin.js)
  * To assign the 'beforeunload' listener and remove the listener, we now use the ManageEventListener class (MonitorStream.js)
  * Added the ManageEventListener class, which allows for more flexible event listener assignment and removal. (skin.js)
  * No additional check for "this.video" is required; simply adding "this.visibilityCheck = false;" (video-stream.js)
  * Update web/skins/classic/views/js/watch.js
  * Use play() on the VIDEO tag, but not from MonitorStream to avoid recursion (MonitorStream.js)
  * refactor: move HAVE_LIBCURL guards inside class definitions as stubs
  * Apply suggestion from @Copilot
  * fix: prevent segfault when MPEG stream codec fails to open
  * fix: add HAVE_LIBCURL preprocessor guards to fix ZM_NO_CURL=ON build
  * fix: remove conflicting minTime/maxTime fields from montage review download
  * Initial plan
  * Initial plan
  * Initial plan
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/watch.js
  * Update web/skins/classic/views/js/watch.js
  * Fix missing _
  * Fix eslint
  * fix: guard ModelId access with property_exists in Monitor::Model()
  * fix: Replace uppercase cyrillic С with latin C
  * fix: Replace Cyrillic с with a Latin c
  * Correction as recommended by "copilot" (index.php)
  * docs: add zma event re-analysis utility documentation
  * fix: add missing unistd.h include in zma.cpp for FreeBSD build
  * fix: remove unused catch parameter in logger.js to satisfy eslint
  * Update web/skins/classic/js/skin.js
  * When switching monitors, we first destroy the current VolumeSlider and only then change its ID, and not vice versa (watch.js)
  * Removed "waitUntil" since it's now in skin.js (MonitorStream.js)
  * Moved "waitUntil" from MonitorStream.js and now use "waitUntil" to wait until the stream becomes active (skin.js)
  * fix: address review feedback on training PR
  * fix: add SSL certificate verification fallback to base Control class
  * fix: restrict eslint 9 flat config to .js and .js.php files only
  * style: modernize Requires JS to use const/let and jQuery ($j)
  * fix: support arguments in ZM_TRAINING_DETECT_SCRIPT config
  * fix: rebuild data.yaml on annotation delete, code cleanup across training files
  * build(deps): bump crazy-max/ghaction-import-gpg from 6 to 7
  * build(deps): bump actions/upload-artifact from 6 to 7
  * build(deps): bump actions/download-artifact from 7 to 8
  * fix: sync training editor and browse panel on all mutations
  * feat: separate training view from event view with cross-event navigation
  * Update MonitorStream.js
  * feat: add virtual Objects folder to training data browser
  * feat: load saved annotations when editing from browse panel
  * Chore: Optimized saving of "navbar_type" in session and cookies (index.php)
  * feat: Shift+drag to draw box inside existing box, add hint text
  * fix: address Copilot review on Requires implementation
  * feat: implement Config Requires field for dependent option disable
  * fix: use content directory for training data fallback path
  * feat: add edit button in browse preview to navigate back to annotation
  * fix: address Copilot review — path traversal, temp leak, double undo, help text
  * Fix: Eslint (MonitorStream.js)
  * fix: nav guard for unsaved annotations, pending box warnings, UX polish
  * Fix: Receive audio and video tracks only for the active stream (skin.js)
  * Fix: When checking isJSON(), if it is not JSON, warn in the browser console (skin.js)
  * fix: improve TRAINING_DATA_DIR help text for empty path behavior
  * fix: code review fixes, version bump to 1.39.1, remove non-repo files
  * feat: two-panel training data file browser with preview and inline delete
  * feat: add annotate button to objdetect modal, compact stats, delete-all, UI polish
  * fix: remove newlines from BackgroundImageConfirm SLANG entry
  * fix: internationalize all hardcoded user-visible strings
  * fix: allow saving background images and delete pending boxes
  * fix: rename Cancel to Exit, smaller buttons, prevent status line wrap
  * fix: green for accepted boxes, remove label dropdown, leave caps
  * fix: use ZM_EVENT_IMAGE_DIGITS for frame filename padding
  * feat: add Detect button to run object detection on current frame
  * fix: annotation UI improvements and remove objdetect frame
  * fix: remove ZM_DIR_EVENTS derivation from migration
  * fix: guard migration against NULL ZM_DIR_EVENTS
  * feat: add custom model training annotation UI
  * fix: pin @eslint/js to &lt;10 to fix CI eslint dependency conflict
  * Fix: If an RTSP2Web type RTC error occurs, restart the stream instead of killing it (MonitorStream.js)
  * Update MonitorStream.js
  * Fix: Use lowercase when searching for the current go2rtc mode (MonitorStream.js)
  * Fix: Saving "navbar_type" in cookies (index.php)
  * Fix: Apply z-index=3 to the Event page as well (skin.css)
  * Fix: Don't assign "resize" listener when using Observer (zone.js)
  * fix: zmDbDo error logging now substitutes all SQL placeholders with values
  * fix: improve JS error logging for undefined messages and cross-origin errors
  * fix: use portable %jd format for chrono duration count
  * fix: auto-detect and convert pixel zone coordinates to percentages in web layer
  * Satisfy eslint, but also log the error
  * Put back .deb builds on master
  * Only .imageFeed will have the alarm/idle border. Not the img within it or video or anything else. Fixes extra borders and streams jumping around as borders appear/disappear
  * fix: use ResizeObserver for zone point positioning on initial load
  * In "src," use '_CameraDirectPrimary' instead of '_0' in "createGo2rtcStream" (skin.js).
  * The z-index for "svg.zones" cannot exceed the index value for ".zonePoint" (skin.css)
  * For ".imageFeed svg.zones" apply z-index: 100 (skin.css)
  * To determine the go2rtc stream type, use "currentMode" instead of "mode" (MonitorStream.js)
  * Support for getTracksFromStream() and getMonitorStream() for Zones &amp; Zone pages (skin.js)
  * Do not adjust MSE delay if streamStartTime is undefined. (MonitorStream.js)
  * feat: integrate EventStream into montagereview with zms recovery and fixes
  * fix: upgrade ESLint config to v9 flat config format
  * Fix: Check the "players" variable (MonitorStream.js).
  * fix: use DOM img element and rAF loop for MJPEG stream reception
  * feat: add EventStream.js for persistent MJPEG event playback
  * Fix RCE vulnerability via API config edit privilege escalation
  * fix: store speed value instead of index in montagereview cookie
  * fix: improve montage review playback smoothness and fix video seek overshoot
  * fix: calculate optimal thumbnail overlay scale from monitor dimensions
  * Automatically a2enmod rewrite
  * fix: link stdc++fs for std::filesystem on GCC 8 and add zma to RPM spec
  * Add Create to canEdit
  * Add Create to canEdit
  * Fix: PanZoom. When scale &gt; 1, prevent the player from responding to image clicks (panzoom.js)
  * fix: add zma binary to redhat zoneminder.spec file list
  * Fix: Assign toggleZones listener only after Event page loads (event.js)
  * fix: mobile layout for monitor and watch views
  * Hide the #delay block when the stream starts (MonitorStream.js)
  * Push to master repo
  * Push to master repo
  * Don't audit log logins
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Add intel-gpu-tools to recommended packages
  * Add intel_gpu_top view
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * feat: add AUDIT logging level for tracking administrative changes
  * feat: store zone coordinates as percentages for resolution independence
  * Bump to 1.39
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * feat: add pushState URL state management for events page filters
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Log commands used when updating db
  * Add ZoneMinder.spec from OBS project
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams
  * fix: use int instead of unsigned int for zone pixel coordinates in zm_zone.cpp
  * feat: expand ONVIF config_types with full device/media/imaging/PTZ queries
  * fix: clamp zone polygon extents to actual frame dimensions in CheckAlarms
  * Removed styles for GridStack, since in version 12 styles are now generated dynamically (montage.css)
  * I created some slightly rounded corners for the streams, tables, and navigation block: .imageFeed, .nav, .fixed-table-body, id='videoFeedStream*' (skin.css)
  * Fix: Eslint (skin.js)
  * Changed the style for ".monitor" a bit (watch.css)
  * Added styles for id=liveStream* (skin.css)
  * Merging and moving two identical functions monitorsSetScale from montage.js and watch.js to skin.js
  * Moving "monitorsSetScale" function from to skin.js (watch.js)
  * Wrap "#dvrControls" and "#extButton" in a single DIV "#bottomBlock" for correct scaling in scale=Auto mode (watch.php)
  * Moving "monitorsSetScale" function from montage.js to skin.js (montage.js)
  * feat: add --protocol mode to zmcontrol.pl for direct module testing
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Fix Eslint (MonitorStream.js)
  * Fix space (MonitorStream.js)
  * Calculate the playback start time (video-stream.js)
  * Fix: Don't clear the screen when animations are off
  * When executing "onmse" save "MediaSource" in a class variable (video-rtc.js)
  * Feat: Moved some code to the "manageMSESocket" function (MonitorStream.js)
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * Added an "onplay" event triggered when playback starts (video-rtc.js)
  * Add intel-gpu-tools to recommended packages
  * Fix space (video-rtc.js)
  * Code optimization (video-rtc.js)
  * RTSP2Web support (watch.js)
  * Fix; Eslint (watch.js)
  * Update video-stream.js
  * Fix: If you click “pause”, then hide the page and display it again after at least 15 seconds, the stream will still be paused and not start (as it was before) (watch.js)
  * Added "zmsState" and its processing (MonitorStream.js)
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Code optimization (MonitorStream.js)
  * Code optimization (watch.js)
  * Code optimization (watch.js)
  * Now we use destroyVolumeSlider() when changing the player and when changing the monitor. (watch.js)
  * Changed the destroy method for VolumeSlider (MonitorStream.js)
  * Start playback using a promise (video-rtc.js)
  * Revert MonitorStream.js
  * Update video-rtc.js
  * Add intel_gpu_top view
  * Fix: Display volumeSlider when switching monitors on the Watch page (MonitorStream.js)
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * #volumeControls always includes the monitor ID (MonitorStream.js)
  * Fix: Fix desync between audioStream.muted and MonitorStream.muted (MonitorStream.js)
  * Completely remove noUiSlider from volumeSlider, not just destroy it. (watch.js)
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Destroy the "VolumeSlider" when switching to another monitor. (watch.js)
  * Optimizing "VolumeSlider" (MonitorStream.js)
  * streamPause() in pauseClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('pause'... event is triggered. (event.js)
  * Log commands used when updating db
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Add ZoneMinder.spec from OBS project
  * streamPlay() in playClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('play'... event is triggered. (event.js)
  * feat: add pushState URL state management for events page filters
  * feat: add AUDIT logging level for tracking administrative changes
  * Fix: Event handling for VID (event.js)
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * build: add selective man3 generation for audited Perl modules
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * fix: update heartbeat during camera close and reconnect
  * Add 4px border-radius to thumbnail img
  * fix: correct App::uses package path in CameraModel
  * Fix: Stop executing "streamQuery" if "zmsBroke" (event.js)
  * Color input[type='checkbox'], input[type='radio'] on dark skin (skin.css)
  * Fix: Color of some buttons on a dark skin (skin.css)
  * fix: warn when zone coordinates extend beyond image dimensions
  * fix: skip V4L2 AutoSelectFormat in non-capture mode
  * fix: remove file_exists() gate on /dev/video in settings modal
  * perf: replace sleep polling with condition wait in Event::Run()
  * perf: reduce lock contention in PacketQueue
  * fix: preserve legacy execlp() behavior for commands without % tokens
  * fix: shell-escape %EC% token to prevent command injection
  * feat: support token substitution in EventStartCommand/EventEndCommand
  * Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * refactor: remove unused reuse_image_ member to keep changes minimal
  * refactor: use reusable reuse_filepath_ member in EventStream::sendFrame
  * Initial plan
  * feat: store zone coordinates as percentages for resolution independence
  * fix: resolve "no url in button" when adding detected cameras
  * refactor: move format_absolute_time_iso8601 from zm_monitor_onvif to zm_time
  * Remove fatal version check. Just error.
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * Bump to 1.39
  * feat: add option to use system-installed jwt-cpp</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316801">- Add intel-gpu-tools to recommended packages</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773835200">- spec file improvements:
  * Removing perl-Archive-Tar requires, as it's part of the perl package.
  * Using autopatch macro.
  * Reordering MP macros/sections
  * Better gcc handling for version &lt; 1600
  * Added ZoneMinder-rpmlintrc</changelog>
  <changelog author="obs@mtlfab.com" date="1776254400">- Update to version 1.38.1+git566.2a29e6318:
  * fix: HLS fragment tracking, live playback, and fallback handling
  * Don't pass null as first parameter to strtotime().
  * fix: convert zone threshold columns to DECIMAL before running conversion procedure
  * chore(deps): Bump softprops/action-gh-release from 2 to 3
  * feat: add HLS byte-range playback for event video
  * Fix: For "nouislider.min.css" we use "cache_bust", i.e. disabling caching when the file changes. (functions.php)
  * Update sidebar.css
  * Fix: More correct ".sidebar-footer" style (functions.php)
  * Force memory release of GDImage for PHP &gt;= 8.0.
  * Conditionally calls imagedestroy() as it was deprecated since PHP 8.0 doing nothing except logging errors.
  * Check for /proc/meminfo before reading its content. There is no such proc file system on FreeBSD, hence http server logs a lot of errors.
  * fix: guard MSE addSourceBuffer against detached MediaSource
  * Use qx() lc() and chomp() for command execution and result. Use eq in the if() statement, instead of '=='.
  * fix: prevent empty events in ONDEMAND mode and fix VideoStore fd/codec leaks
  * Change ::Config{uname} to ::Config{ZM_PATH_UNAME}
  * fix: scan-line polygon fill incorrectly filled non-convex polygon gaps
  * Use ZoneMinder::Config.
  * fix: exclude orig tarball from deb uploads to zmrepo
  * Fix "top" command parsing on FreeBSD (tested in FreeBSD 13.5 jail, running 1.38.1).
  * fix: show Device text input when no device is selected on load
  * fix: run form validation on Save button click
  * fix: only validate Device path for Local monitors
  * fix: limit filter Name input to 64 characters
  * fix: add missing dash separator in Content-Range header
  * fix: treat ENOTTY like EINVAL when querying V4L2 JPEG compression options
  * fix: call disconnect() in MonitorLink::connect() before reopening map_fd
  * Move the delay calculation code to after we run the filter so that the time taken running the filter is included
  * Rename last_action to last_reload as that is what it actually is
  * Include ExecuteInterval in warning
  * fix: free video_out_ctx after failed avcodec_open2 in new_extradata path
  * fix: fd leak in MonitorLink::disconnect() when connect() fails
  * Don't use Fatal when there is an error preparing the sql. handle PostSQLConditions being an empty array
  * Include ExecuteInterval in warning
  * Use now instead of 0 when no last_ran so that elapsesd=0 on initial run, and we don't log a warning.
  * fix: redirect stdin/stdout/stderr to /dev/null instead of closing them
  * Warn() -&gt; Warning().  Fixes #4724
  * fix: add Warn() as exported alias for Warning() in Logger
  * fix: reset last_write_index in Pause to restore DECODING_ONDEMAND bootstrap
  * Update options.css
  * Do not use the "form-control-sm" class for rows. (options.php)
  * fix: guard against empty auth_relay producing double &amp;&amp; in zms URLs
  * Fix missing quotes
  * Bump up ubuntu and python version for readthedocs
  * fix: guard against null websocket in VideoRTC.onopen
  * fix: use shoelace formula for zone threshold pixel-to-percent migration
  * fix: null-check StorageId column in Monitor::Load to prevent segfault
  * Upgrade bootstrap-table to 1.27.1
  * fix: add DTS backward jump detection in ffmpeg camera capture
  * Update MonitorStream.js
  * Update MonitorStream.js
  * Revert watch.php
  * fix: clamp user bandwidth before defining ZM_WEB_* constants
  * chore: remove obsolete ZM_FILTER_EXECUTE_INTERVAL config option
  * fix: use minimum per-filter delay instead of last filter's delay in zmfilter
  * fix: use prepare instead of prepare_cached in Filter::Execute
  * fix: clear accumulated state in Filter::Sql() before rebuilding
  * Set style for "div.volume" (skin.css)
  * SPAN tag replaced with DIV tag (watch.php)
  * SPAN tag replaced with DIV tag (functions.php)
  * Added missing UL tag (functions.php)
  * Remove extra space (functions.php)
  * Fix: Removed extra space and extra slash (functions.php)
  * Update web/skins/classic/views/watch.php
  * Include full path in warning when fail to cache bust
  * Log the value when event_close_mode is unkown
  * fix: handle HTTP-to-HTTPS redirect in Reolink_HTTP login
  * fix: prefer MJPEG over raw YUV in V4L2 AUTO palette selection
  * fix: add missing CLOSE_DURATION event close mode handling
  * Added a link to the PR (watch.php)
  * Prevent vertical shifting of #content on the Watch page when displaying the stream status overlay. (watch.php)
  * When executing monitorChangeStreamChannel(), always write the new channel to the cookie and to monitorStream.currentChannelStream (watch.js).
  * Don't use "scrollTo" because it doesn't work properly. (console.js)
  * Silent refresh bootstrapTable on Console page (console.js)
  * wip
  * wip
  * When starting a stream on the Watch page, don't execute controlMute() (watch.js)
  * If the system volume was set to 0, change the state of the "Mute" icon in the volume slider (MonitorStream.js)
  * fix: preserve fractional percentages in zone threshold migration
  * A finger-shaped pointer cursor for the hide/show password buttons (skin.css)
  * Read from 'zmWatchMuted' cookies instead of 'zmWatchMute' (watch.js)
  * fix: include username in auth relay and fix stale auth in stream restart
  * Add br after USE ONVIF events
  * fix: add event-id latch to linked monitor score detection
  * fix: reduce linked monitor reconnect throttle from 60s to 1s
  * Set "pointer-events: none" for "imgInfoBlock" and "infoBlock" to disable pointer events for them (MonitorStream.js)
  * When stopping a stream, execute writeTextInfoBlock after checking the existence of the stream (MonitorStream.js)
  * Normalizing text before assigning it to a DOM element
  * feat: add ZM_WEB_SHOW_SERVER_STATS config to toggle navbar stats
  * Instead of "setTextSizeOnInfoBlock," we now use the new "setTextSizeOnInfoBlocks" function, which sets the text size for all blocks. (skin.js)
  * Instead of explicitly specifying the text size, we use a call to the new function "setTextSizeOnInfoBlock" (MonitorStream.js)
  * feat: add ZM_WEB_SHOW_NAV_BUTTONS config to hide Back/Refresh buttons
  * feat: add ZM_WEB_BUTTON_STYLE config for icons+text, icons, or text buttons
  * Fix: Eslint (MonitorStream.js)
  * Remove extra space (skin.js)
  * When a stream is loaded, paused, or stopped, display a corresponding caption in the center of the stream player. (MonitorStream.js)
  * feat: make Remember Me a tri-state option (None/Yes/No)
  * Added styles for 3D text (skin.css)
  * Added calculation of the text size displayed in the information block (skin.js)
  * fix: strip &lt;br/&gt; from bootstrap-table column picker labels
  * fix: compact montage header layout and move Show Zones to settings row
  * Don't add postLoginQuery to url if it is empty
  * Move tag related commands to canView(Events) instead of canEdit(Events)
  * Updated .spec for OpenSUSE - Corrected
  * Updated .spec for OpenSUSE
  * Increase potential config line size. HTML snippets can easily be larger than 256</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1778760000">- Update to version 1.38.1+git876.2b1627e2:
  * fix: flush decoder_queue on decoder thread exit to avoid stale latency offset across reconnect
  * perf: index Sessions.access and rework session gc to two-phase delete
  * fix: derive event end time from Length when EndDateTime is missing
  * fix: align auth hash validation with generation and warn on user mismatch
  * fix: sanitize reflected user input in ajax error messages
  * fix: remove reflected user input from log ajax XSS sinks
  * fix: do not return SQL error text to client in events ajax
  * fix: remove reflected user input from events ajax XSS sinks
  * Update sidebar.css
  * fix: sanitize download params at event ajax boundary
  * Minor optimization of the sidebar footer box (sidebar.css)
  * fix: sanitize export filename and connkey at event ajax boundary
  * fix: remove reflected user input from event ajax XSS sink
  * fix: remove reflected user input from device ajax XSS sinks
  * fix: remove reflected user input from add_monitors XSS sink
  * feat: recalibrate ZonePresets for modern HD resolutions
  * fix: clamp percentage polygon to width-1/height-1
  * Potential fix for pull request finding
  * Potential fix for pull request finding
  * fix: QP-encode plain-text email body so URLs survive transit
  * Update log.php
  * Fix: Yesli v sessii byl sokhraneno znacheniye "Components", yavlyayushcheyesya pervym elementom massiva "$components", to ono ignorirovalos' pri formirovanii "$selected_component" (log.php) Privesti ZM_WEB_REFRESH_LOGS k tipu INT pered sravneniyem (log.php) YA ne ponimayu, pochemu tip znacheniya `ZM_WEB_REFRESH_LOGS` stanovitsya str, a ne int. Ved' `ZM_WEB_REFRESH_LOGS` poluchayetsya iz `ZM_WEB_*_REFRESH_LOGS`, kotoryye v baze dannykh khranyatsya kak integer. YA vnes ispravleniya v kod https://github.com/ZoneMinder/zoneminder/pull/4819/changes/06f1178a99f6985c9b9c625c3812a576e993de0e, no ya khochu razobrat'sya, pochemu i gde proiskhodit zamena tipov. Vot zapros i rezul'taty zamera. Pervyy zamer - obychnyy indeks. Vtoroy zamer pokryvayushchiy indeks Raznitsa v skorosti vypolneniya boleye 10 raz i eto pri smeshchenii vsego 250000 Dobavil podderzhku konstanty ZM_WEB_REFRESH_LOGS (log.php) Feat: Dobavil nastroyku dlya obnovleniya okna Log page (ConfigData.pm.in) Dobavil konstantu ZM_WEB_REFRESH_LOGS (config.php) Isaac, tebya chto-to ne ustraivayet? Ozhidayu tvoi kommentarii, zamechaniya. Schitayu dannyy PR zakonchennym Poprosi pozhaluysta Copilot proverit' dannyy PR Dobavit' v pervichnyy indeks Component, TimeKey, Level dlya uvelicheniya skorosti obrabotki zaprosov Ispol'zovaniye JOIN podzaprosa pozvolyayet uskorit' vypolneniye osnovnogo zaprosa v 10-20 raz bystreye. Tak-zhe sleduyet proizvodit' otbor po stolbtsu 'Level', a ne 'Code', t.k. imenno 'Level' u nas indeksiruyetsya Optimizatsiya medlennykh SQL zaprosov pri bol'shoy tablitse Optimizirovannyy zapros Dlya optimizitsii zaprosov s ispol'zovaniye podzaprosa Ne posylat' AJAX zaprosy obnovleniya tablitsy, yesli stranitsa skryta (log.js) Eto znachitel'no snizit nagruzku na server. T.k. seychas, yesli otkryt' mnogo Log page i svernut' ikh, to zaprosy postoyanno postupayut na server! Da, kak ya i dumal, rasshireniye mozhet byt' mp4 or mkv or webm (kak dlya zakonchennogo fayla, tak i dlya incomplete), po etomu ya izmenil shablon dlya poiska. YA ne stal perechislyat' vse vozmozhnyye rasshireniya, t.k. v budushchem oni mogut izmenit'sya. Izmenen shablon okhvatyvayushchiy fayly s lyubym rasshireniyem, t.k. ono mozhet byt' mp4 or mkv or webm (functions.php) Dopolnitel'naya proveka sushchestvovaniya fayla Chto by my ne vernuli ssylku na nesushchestvuyushchiy fayl Khotya.... Fayl ved' imeyet takoye imya: `incomplete.h264.mp4`, t.ye. shablon `/incomplete.*.mp4` yavlyayetsya korrektnym. Vozmozhno sleduyet ispol'zovat' shablon `/incomplete*.*`? @connortechnology Chto ty dumayesh' naschet etogo? Eto ne moya oshibka, ona poyavilas' v kode iz za kommita https://github.com/ZoneMinder/zoneminder/commit/3f8bc81760071f49bdce894c664cd507820dcfaa Pri kopirovanii koda ya ne proveril i eto plokho s moyey storony. Zdes' ya ispravlyu, no tak-zhe neobkhodimo ispravit' i v `web/views/view_video.php‎ ` Obrabatyvat' $Event-&gt;DefaultVideo() vsegda kak stroku Vozmozhno eto izlishnyaya proverka, no pust' budet tak... YA reshil proanalizirovat', iz za chego poyavlyayutsya tormoza v SQL i uzhasnoye potrebleniye pamyati. YA vklyuchil logirovaniye medlennykh zaprosov i uzhasnulsya.... YA nakhodilsya na 3y stranitse prosmotra logov (po 25 strok na stranitsu). YA pereshel na 75823 stranitsu (da, u menya 1674290 strok ) Pochemu-to ne verno rasschityvayetsya kol-vo stranits, no s etim pozzhe mozhno razobrat'sya.... I vot chto ya uvidel v medlennykh zaprosakh: U menya yest' mysl', kak uskorit' rabotu SQL s bol'shimi tablitsami. YA poprobuyu. Put' k faylu dlya sobytiya KHKHKH ne nayden Ne naydeno ni odnogo fayla sobytiya dlya eksporta sobytiy monitora s ID=18. Dobavil proverki 3 462 Fix: If the "Components" value, which is the first element of the "$components" array, was stored in the session, it was ignored when generating "$selected_component" (log.php)
  * Cast ZM_WEB_REFRESH_LOGS to INT before comparison (log.php)
  * build(deps): bump actions/dependency-review-action from 4 to 5
  * Fix: Save the selected "All" value in the "zmLogComponent" session (log.php)
  * Preventative loop protection ZM_WEB_REFRESH_LOGS=0 (log.php)
  * Added support for the ZM_WEB_REFRESH_LOGS constant (log.php)
  * Updated description (ConfigData.pm.in)
  * Added the ZM_WEB_REFRESH_LOGS constant (config.php)
  * Feat: Added a setting for refreshing the Log page window (ConfigData.pm.in)
  * Fix: Correct calculation of the total number of pages for pagination with filters (log.php)
  * Apply style only to "#pills-tab" (monitor.css)
  * FIx enmod rewrite
  * Potential fix for pull request finding
  * Pass the $encoding parameter to mb_strtolower/mb_strtoupper (functions.php)
  * Potential fix for pull request finding
  * Optimizing the menu style on the Monitor pagemonitor.css
  * Fix: Annoying error getting $file_path due to ".$file" (image.php)
  * fix: honor explicit port argument in urlToApi single-server case
  * fix: urlToApi falls back to location.host in single-server case
  * Update lang.php
  * Moved the "mb_ucfirst" function to \includes\functions.php (functions.php)
  * Moving the "mb_ucfirst" function from \skins\classic\includes\functions.php And adding a new "mb_lcfirst" function (functions.php)
  * Feat: Search for translations without regard to the case of the first letter (lang.php)
  * If the index.m3u8 file is missing, then MP4HLS is disabled in the select (event.php)
  * feat: encoder parameter templates with editor + REST API closes #4778 closes #4802
  * Feat: Added codec="MP4HLS" (event.php)
  * Update view_video.php
  * More correct assignment of the $path_info value (view_video.php)
  * Update ru_ru.php
  * Instead of "MP4" we will specify "video" (event.php)
  * Potential fix for pull request finding
  * feat: add Report::canEdit() and CreatedBy column
  * ci: skip CodeQL on changes that contain no scanned languages
  * ci: add scheduled workflow to prune old Actions caches
  * Avoid PHP Notice (view_video.php)
  * Fix: Pop-up file name on download button (event.php)
  * Fix: Loading incomplete.mp4 event file (view_video.php)
  * Fix: Display snapshot for incomplete event file (Update image.php)
  * Fix a2enmod cgi =&gt; a2enmod rewrite causing install to fail.
  * Add depenencies for resolute raccoon
  * Analyzing "space" and "," key presses for positioning in the tag input field (event.js)
  * fix: use HTTP_X_FORWARDED_FOR in auth hash validation to fix AUTH_HASH_IPS with reverse proxy
  * Initial plan
  * fix: ensure trigger_state written last in zmTriggerEventOn to fix 1/3 event trigger rate
  * Initial plan
  * Prevent the scrollbar from appearing when displaying table column visibility settings (options.css)
  * Added $CLANG (lang.php)
  * Potential fix for pull request finding
  * docs: document all ONVIF_Options key=value pairs
  * Initial plan
  * Revert "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"
  * fix: PR #4742 round 2 review feedback
  * fix: silence spurious Overlay subpixel-order warning post-AVPixelFormat
  * fix: PR #4742 review feedback + drop stray u_buffer assignments
  * Tag Management Optimization (event.js)
  * Update files.php
  * Added table styles (files.css)
  * Fix: .tags-container on Event page if screen is narrow and there are many tags (skin.css)
  * Fix: ESLint (audioMotionAnalyzer.js)
  * fix: parse HTTP Range header correctly in output_file() fixes #4777
  * build: add Profile CMAKE_BUILD_TYPE for perf/flamegraph
  * fix: bail from MonitorStream::runStream when monitor failed to load
  * To avoid overriding the zmVlang() function (en_gb.php)
  * Merge an array from a custom language file and en_gb.php (lang.php)
  * Update ru_ru.php
  * Correction of the Russian translation (ru_ru.php)
  * Chore: Minor UI optimization for ".tags-container" on the Event page (skin.css)
  * fix: parse audioMotionAnalyzer.js as module so ESLint succeeds
  * Change from translate('What display') to translate('Show') (event.php)
  * Fix: Eslint (skin.js)
  * In applyTemplateAudioMotionTranslation() , execute createClickableLink() &amp; replaceDoubleTildeToBR() (monitor.js)
  * Revert (lang.php)
  * Added replaceDoubleTildeToBR() &amp; createClickableLink() function (skin.js)
  * perf: skip clearPackets early-returns and allow drop-to-iterator-keyframe
  * Apply ".flex-col-2" and ".flex-col-3" to all pages, not just the User page (skin.css)
  * Added ".flex-col-3" for "#frames" (event.php)
  * Changed style for "#frames img" (event.css)
  * Chore: Minor improvements to statistics display on the Event page (event.css)
  * customElements.define moved after the class declaration (audioMotionAnalyzer.js)
  * Abort checkVerAudioMotion() if we couldn't get the CURRENT_AUDIO_MOTION_ANALYZER_VERSION value (monitor.js)
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Fix: https://github.com/ZoneMinder/zoneminder/pull/4752#discussion_r3158319612 (user.php)
  * For now, apply the "legend" style only to the User page (skin.css)
  * Update web/skins/classic/css/base/skin.css
  * Update web/lang/en_gb.php
  * Potential fix for pull request finding
  * Don't use "await" when calling "insertModalHtml()" (options.js)
  * fix: clean up ONVIF subscription before re-Subscribe to stop NotAuthorized loop
  * Update image.php
  * Update image.php
  * Prevent an error from being generated when processing the file "index.m3u8" (image.php)
  * We'll now pause audioMotion in MonitorStream.js. (MonitorStream.js)
  * Added the pauseAudioMotion() function. (skin.js)
  * Now we will pause audioMotion in MonitorStream.js (watch.js)
  * Avoid reinitializing audioMotion if the previous one has not yet finished. (audioMotionAnalyzer.js)
  * Remove  extra "&lt;" (event.php)
  * Instead of " use ' (console.js)
  * Added id="header" (event.php)
  * Apply "chosen" to the Event page (event.php)
  * Update console.php
  * When using ONVIF, the console page should not display simply "Use ONVIF Events", but should also indicate which event the trigger is configured for. (console.js)
  * Bump version to 1.39.5
  * The missing comma has been restored (zm_update-1.39.5.sql)
  * If WhatDisplay already exists, ensure it is the right enum
  * - Added support for "~~" =&gt; &lt;br/&gt; for translation - Now we only specify the supported analyzer version in one place in the audioMotionAnalyzer.js file - Added translations for three cases: when the analyzer is not installed, the wrong version is installed, or everything is fine.
  * Added `WhatDisplay` to the 'Monitors' table (zm_create.sql.in)
  * Upload audioMotionAnalyzer.js to the Monitor page (functions.php)
  * - Style optimization. - Added support for the "flex-col-X" class, where X can be 2 or 3. This is used in cases where, for example, we need to display a theoretical 3 columns, but 1 or 2 of them may not be displayed in certain cases. The remaining columns will then take up all available space. Can be used in conjunction with "col-md/lg-*", which will be placed inside "flex-col-X".
  * Fix: bootstrap legend (skin.css)
  * Adjusting the display of the "infoBlock" block (MonitorStream.js)
  * Create zm_update-1.39.5.sql
  * Safely using $_REQUEST['title'] and $_REQUEST['key'] (delconfirm.php)
  * Update options.js
  * Update version
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Update web/skins/classic/views/js/options.js
  * Set retention-days: 1
  * Added missing spaces. (options.js)
  * Added translations.
  * - Added the ability to specify a title for the window in the \ajax\modals\delconfirm.php file. - Added the "DeleteUser" function to be executed when the "Delete" button is clicked.
  * Display a modal window confirming the deletion of a user (options.js)
  * Align the thumbnail on the Console page horizontally to the center of the table cell (console.css )
  * Layout optimization
  * fix: restore getCycleHTML for Watch/Cycle navbar item refs #4745
  * Update skin.css
  * Layout optimization
  * Moved .button-block from options.css to skin.css
  * Layout optimization (_options_api.php)
  * Layout optimization (options.php)
  * Added style for ".button-block" (options.css)
  * Optimizing styles for the Options page (options.css)
  * Update ru_ru.php
  * Added Russian translation (ru_ru.php)
  * feat: add G.711 μ-law (PCMU) audio support to zm_rtsp_server
  * fix: coerce null ParentId to '' for array offsets in groups view
  * Added support for audioMotion-analyzer.js in various formats (audioMotionAnalyzer.js)
  * Update audioMotionAnalyzer.js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Analyzing AUDIO_MOTION_ENABLED and checking $whatDisplay using strtolower (Monitor.php)
  * Analysis of AUDIO_MOTION_ENABLED (montage.php)
  * fix: skip sws_scale for identity conversions in Image::Assign
  * Delete web/skins/classic/assets/audioMotion-analyzer/src/audioMotion-analyzer.js
  * Create help.txt
  * Added analysis of the AUDIO_MOTION_ENABLED constant (Monitor.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant for $htmlAudioControlPanel (montage.php)
  * Added analysis of the selectorWhatDisplay variable (montage.js)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (montage.php)
  * style: fix eslint errors in onvif probe js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (watch.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Added function checkAudioMotionEnabled() (audioMotionAnalyzer.js)
  * fix: YUV422P passthrough and libjpeg grayscale for planar YUV
  * Added translation for OPTIONS_WHATTODISPLAY (en_gb.php)
  * Added translation for OPTIONS_WHATTODISPLAY (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (en_gb.php)
  * Change requiresAudioMotionEnabled -&gt; RequiresAudioMotionEnabled (monitor.php)
  * Added handling of the AUDIO_MOTION_ENABLED constant to ensure correct operation in the absence of the "audioMotion-analyzer.js" file. "monitor.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" "functions.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" (skin.js.php)
  * Correct operation without the "audioMotion-analyzer.js" file
  * fix: use decoded frame's native pixel format instead of Monitor.Colours
  * fix: compute Camera linesize/imagesize from pixelFormat, not hardcoded YUV420P
  * fix: use zm_bytes_per_pixel for pixel-rendering dispatch instead of GRAY8-only
  * fix: handle YUVJ422P/YUV422P in zm_colours_from_pixformat
  * fix: sync imagePixFormat in WriteBuffer, Assign, and AssignDirect
  * fix: replace ZM_COLOUR_*/ZM_SUBPIX_ORDER_* with AVPixelFormat for format dispatch
  * feat: install SIGPIPE handler in zms for clean browser-disconnect shutdown
  * fix: guard changeFilters against invalid date input in montagereview
  * Update web/skins/classic/views/js/onvifprobe.js
  * Update web/skins/classic/views/js/onvifprobe.js
  * fix: use full codec profile strings in canPlayCodec feature detection
  * fix: strip SKIP LOCKED from EXPLAIN query in filter debug modal
  * fix: sort events by Tags column alias, not T.Name
  * fix: log bind params correctly when SQL contains literal % characters
  * perf: default ffmpeg decoder thread_count to 2
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (ru_ru.php)
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (en_gb.php)
  * Added a description of some possible value options for recognizing ONVIF events (monitor.php)
  * Apply suggestion from @Copilot
  * style: replace size attribute with CSS width on manual URL input
  * feat(onvif): add manual camera URL entry to ONVIF probe
  * Removed extra semicolons (watch.js)
  * Added translation for "OPTIONS_WHATTODISPLAY" en_gb.php
  * Load audioMotionAnalyzer.js only on Watch, Montage, and Event pages (functions.php)
  * We'll use $cspNonce (functions.php)
  * Update web/skins/classic/js/skin.js
  * Declare constants (skin.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/views/montage.php
  * Update web/skins/classic/views/watch.php
  * Instead of audioMotion.play(), use audioMotion.init() (MonitorStream.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/js/skin.js
  * Set maxFPS=30 instead of 50 (audioMotionAnalyzer.js)
  * Feat: Run changeWhatDisplay() without refreshing the page (watch.js)
  * Update skin.js
  * Fix: Eslint (MonitorStream.js)
  * skin.js - Clear IconMute when executing destroyVolumeSlider() - Added the ability to clear the icon state to changeStateIconMute()
  * Removed an unused constant
  * Fix: Eslint
  * Creating a volume slider on the Montage page to simultaneously control the volume of all monitors
  * Add changeWhatDisplay() (event.js)
  * Add $whatDisplay (event.php)
  * Add "#whatDisplayControl" (event.php)
  * Fix parent
  * If we don't display the video, then display the information block on "#monitorXX"
  * Style adjustments
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Added audio visualization
  * Update functions.php
  * Added &lt;audio-motion&gt; (Monitor.php)
  * Loading "nouislider" and "audioMotion-analyzer" (functions.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1780315200">- Update to version 1.38.1+git1083.97755a96:
  * If the requested Object isn't found in the database, generate a Warning instead of an Error. (Object.php)
  * Use hostname obtained via "parse_url", do not use regular expression to obtain IPv4 (onvifprobe.php)
  * Apply suggestions from code review
  * Now we don't need to return "$monitor-&gt;Id()" because we can get Monitor.Id after Id has become public. (monitor_probe.php)
  * We use Monitor.Id again instead of MonitorId, since Id is now publick
  * "Id" is now public, not protected.  (Monitor.php)
  * Update skin.js
  * When closing SIDEBAR_MAIN_EXTRUDER, reset its z-Index (skin.js)
  * Replaced "stream.Monitor.Id" with "stream.MonitorId" (add_monitors.js)
  * Use "parse_url" instead of "preg_match" when determining hosts (onvifprobe.php)
  * The added class must be escaped using htmlspecialchars() (functions.php)
  * I added ".chosen" in STEP 2. (onvifprobe.php)
  * Removed extra parentheses (monitor_probe.php)
  * fix: widen DefaultScale columns to preserve fit_to_width
  * Added the "controlHeader" class to the filter block on the Events page (Filter.php)
  * Fix Aligning input fields (sidebar.css)
  * Changed the style of the active button in "nav #pills-tab" for the dark theme (monitor.css)
  * Changed the style of the active button in "nav #pills-tab" (monitor.css)
  * Apply scrollbar style to all elements (skin.css)
  * Remove "Loading, please wait" if nothing is found (add_monitors.js)
  * Removed unused const "Monitor" (add_monitors.js)
  * Pass 'MonitorId' in the returned array, since the private method does not pass the monitor ID. (monitor_probe.php)
  * Correctly get Monotor.Id for editing a monitor (add_monitors.js)
  * More readable text color for the DBG level for the dark theme (log.css)
  * Added the ability to specify a class for &lt;select&gt;&lt;option&gt; in the htmlSelect() function (functions.php)
  * Added a style (onvifprobe.css)
  * Optimized the drop-down list of found monitors. (onvifprobe.php)
  * Apply suggestions from code review
  * Added style for .chosen-container
  * Use "Chosen" on Onvifprobe page (onvifprobe.php)
  * Fix: Correct reading of zmWatchMuted cookies
  * fix: avoid OOB read on negative gsoap error codes in ONVIF Subscribe fixes #4842
  * fix: keep DefaultVideo as mp4 name throughout event lifecycle refs #4839
  * fix: polyfill str_starts_with/str_ends_with/str_contains for PHP 7
  * fix: make zm_update-1.39.10.sql idempotent for reruns
  * More correctly retrieves Component from $_REQUEST and writes it to the session (log.php)
  * More correct retrieval of zmLogFilterLevel from session (log.php)
  * fix: keep console summary row aligned when toggling event columns
  * More correct parsing of $_REQUEST['level'] before assigning its value to $L (log.php)
  * fix: string-compare BIGINT counters in zmaudit CAS skip checks
  * Potential fix for pull request finding
  * Correctly save setCookie('zmWatchMuted') when "=false" (MonitorStream.js)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * feat: refresh auth hash and retry on MonitorStream image error
  * fix: enrich zms auth-failure warning with diagnostic fields
  * fix: only show 'Use ONVIF' badge on console when listener is enabled
  * Edited comment (log.js)
  * Potential fix for pull request finding
  * fix: CAS-guard Event_Summaries UPDATE in zmaudit to preserve concurrent writes
  * fix: chunk zmstats bucket-prune DELETE IN-list to avoid packet-size limits
  * fix: CAS-style Storage DiskSpace update in zmaudit to preserve concurrent adjustments
  * fix: use $dbh-&gt;do for SET TRANSACTION to preserve the next-TX isolation level
  * fix: skip zmDbDo success Debug when inside a caller-managed transaction
  * Prevent the "#clearLogsBtn" status from appearing active after clicking the "#clearLogsConfirmBtn" button. The issue was related to an unnecessary call to manageClearButtonAvailability() (log.js)
  * Potential fix for pull request finding
  * Open and close the session only once per page refresh. (log.php)
  * More accurate page navigation and statistics display (log.js)
  * refactor: simplify Event::delete bind-list to a plain SQL list
  * fix: track Event_Summaries enumerate failure as partial resync in zmaudit
  * perf: restrict zmstats ES resync to monitors with pruned buckets
  * fix: avoid DB-backed logging inside zmDbDo when caller manages the transaction
  * fix: reset step/send_twice in MonitorStream CMD_STOP; reset stopped in EventStream.js lifecycle
  * fix: address review feedback - endian decode, send_twice init, setLastViewed, curr_frame_id gating
  * fix: track per-row UPDATE failures in zmaudit ES and Storage resync
  * docs: clarify per-monitor UPDATE lock state in zmstats resync
  * docs: reference the actual Event::Event constructor in lock-order block
  * fix: log Error in Event::delete when deadlock retries are exhausted
  * docs: expand triggers.sql lock-order block with full writer list
  * docs: document atomicity tradeoff in zmstats/zmaudit ES resync
  * fix: don't log Error on deadlock inside a caller-managed transaction
  * refactor: route VideoStore destructor through finalize() refs #4757
  * fix: VideoStore filename use-after-free + null-oc destructor guard refs #4757
  * fix: drop DefaultVideo extension check from \$has_hls refs #4757
  * Avoid endless AJAX table update requests if the query returned 0 rows on the Log page. (log.js)
  * Renamed session 'ZM_LOG_FILTER_LEVEL' to 'zmLogFilterLevel' (log.php)
  * Save the selected filter level in the session (log.php)
  * Managing the availability of the clear logs button (log.js)
  * revert: stop forcing DefaultVideo='index.m3u8' for HLS events refs #4757
  * fix: drain VideoStore reorder_queues inside finalize() refs #4757
  * fix: don't force HLS when user explicitly picked MP4 codec refs #4757
  * fix: disable video.js liveui so HLS scrubbing works on in-progress events refs #4757
  * fix: report served mp4 filename in view_video.php Content-Disposition refs #4757
  * fix: stop view_hls.php emitting /zm/index.php?index.php?view=… refs #4757
  * fix: pick HLS player when index.m3u8 exists, not from DefaultVideo refs #4757
  * fix: keep DefaultVideo='index.m3u8' for events with an HLS manifest refs #4757
  * perf: scope Event neighbor queries to Id only
  * fix: stop warning on URL/session user mismatch in getAuthUser
  * fix: correct HLS fragment byte-range and duration tracking refs #4757
  * fix: use getSkinFile() for _monitor_filters.php include path in console.php
  * typo
  * fix: guard ZM_WEB_REFRESH_LOGS against missing Config row
  * Since kFreeBSD was amd64 and i386 archs only, remove unnecessary checks
  * Fix FreeBSD arm builds
  * Fix: ".chosen-drop" should always be in the foreground (sidebar.css)
  * Fix: Fixed overlapping ".eventStats" and dropdown tags (event.css)
  * fix: use getFilterSelection() and validCardinal() per reviewer feedback
  * Use ConfirmDeleteGroups instead of ConfirmDelete
  * Listen for the "click" event for #delConfirmBtn only once. (skin.js)
  * Potential fix for pull request finding
  * fix: use filter_var FILTER_VALIDATE_INT for stricter ID validation in queryRequest
  * fix: GroupId filter persists after browser refresh on Console view
  * Initial plan
  * fix: avoid HierarchyRequestError in submitThisForm on console view
  * Update ru_ru.php
  * Correction and addition of the Russian translation (ru_ru.php)
  * The column order in the component index has been changed, and Logs_Component_idx has been removed, as it's now redundant.
  * When the page is hidden, execute hideLoading() for the bootstrap table, then execute an empty return instead of executing the AJAX request.
  * Set $maxTime to the current time only if $endSecs is missing in the incomplete event or if $maxTime is empty after looping through all events. (download_functions.php)
  * Return false instead of return "" (download_functions.php)
  * Potential fix for pull request finding
  * Server -&gt; ServerId mapping for sorting in a SQL table (log.php)
  * Added composite secondary index (zm_create.sql.in)
  * Potential fix for pull request finding
  * Added a missing space.
  * Don't execute AJAX requests from bootstrap-table if the page is hidden.
  * For now, we'll only search for "mp4" files (download_functions.php)
  * The "findVideoEventFile()" function takes a file extension as an argument (functions.php)
  * Gjntdownload_functions.php
  * Fix: Missing space (log.js)
  * Update log.php
  * Potential fix for pull request finding
  * Fix: Search (log.php)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed. (zm_create.sql.in)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed.  zm_update-1.39.10.sql
  * Feat: Optimizing slow SQL queries for large tables (log.php)
  * Fix: space (log.js)
  * Don't send AJAX table update requests if the page is hidden (log.js)
  * The template has been changed to cover files with any extension, since it could be mp4, mkv, or webm (functions.php)
  * Additional file existence check (functions.php)
  * Always treat $Event-&gt;DefaultVideo() as a string (functions.php)
  * Added checks (download_functions.php)
  * Potential fix for pull request finding
  * Added findVideoEventFile ($Event) function (functions.php)
  * Code optimization (download_functions.php)
  * Fix: Correct end timestamp of events when exporting MP4 for multiple events (download_functions.php)
  * docs: identify the 1213 magic number as MariaDB ER_LOCK_DEADLOCK
  * fix: check SELECT errors in zmstats bucket-prune loop
  * fix: don't zero Event_Summaries counters on aggregate SELECT failure in zmaudit
  * docs: correct Event::delete lock-order comment to match triggers.sql
  * docs: document canonical Events lock acquisition order in triggers.sql
  * perf: snapshot bucket aggregates instead of joining in Event_Summaries resync
  * fix: rollback and retry Event::delete under deadlock at READ COMMITTED
  * feat: auto-retry zmDbDo on InnoDB deadlock errno 1213
  * Replacing $j('#eventTable') with tableControlCaps (controlcaps.js)
  * Replaced random Russian text with English Display a message when a report deletion error occurs instead of updating a non-existent '#reportsTable' (report.js)
  * Replaced casual Russian text with English (skin.js)
  * Update groups.js
  * Get the "form" for an element (groups.js)
  * Use $report-&gt;canEdit() instead of canEdit('Events') (reports.php)
  * Removed warning in the browser console if the manageDelConfirmModalBtns() function is not found (skin.js)
  * Lost "?" (ru_ru.php)
  * docs: document CMD_PLAY vs CMD_VARPLAY and CMD_STOP in MsgCommand enum
  * fix: improve stopped state handling in EventStream run loop
  * fix: add stopped state for CMD_STOP, fixing paused=true response bug
  * Initial plan
  * Fix: ESLint
  * - Moved the getDelConfirmModal() function from options.js to skin.js - Removed the getDelConfirmModal() function (and its call) from report.js, options.js, reports.js, devices.js, +++controlcaps.js(?view=options&amp;tab=control), and snapshots.js. This is because it's now a single function in skin.js, which is called when the "Delete" button is pressed, rather than during page initialization. - Slightly modified the local functions of manageDelConfirmModalBtns(). Removed the listener, so the code is executed immediately. - You can now call local functions from the global getDelConfirmModal() function (instead of just executing submitThisForm() ). Applies to report.js, reports.js, devices.js, controlcaps.js, snapshots.js - Changed the style of the "Delete" button on the Groups page - Added deletion confirmation to the Storage, Roles, and Groups pages - On the Event page, deletion permissions were broken. Deletes were allowed for those who did NOT have edit permissions, but deletions were blocked for those who did. ! - On the Report page, deletion didn't work and still doesn't work. This needs to be addressed, or maybe it's possible to delete reports only on the Reports page. (FIXED...) - On the Devices page, the "canEdit.Device" permissions check was being performed, but it should be performed like this: "canEdit.Devices" - The $action variable was not defined in \ajax\devices.php - Added translations. - Added a style for the disabled "Delete" button - Minor fixes
  * - Added the DeleteServer() function - Pass the "formName" argument when calling getDelConfirmModal() - Added a translation
  * Changed the "Delete" button to confirm deletion of selected servers (_options_servers.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1781265600">- Update to version 1.39.11+git175.c103c403:
  * fix: delete FifoSources before RemoveSession on reconnect failure
  * fix: bound ONVIF SOAP timeouts below zmdc 30s kill window
  * fix: correct stale SharedData and TriggerData offsets in PHP shm map
  * fix: probe mp4 duration for events with no capture jpgs in zmrecover
  * chore: remove dead statusCmd code and debug logging from watch.js
  * Attempt to fix case where a console bootstrap table query gets cancelled and so you get no results
  * feat: add LTS CMIP3CD42WI-28AISP white-light control row refs #4895
  * fix: re-auth retry on supplementLight GET for long-lived control daemons
  * feat: add white-light (CanLight) control to HikVision/LTS module refs #4895
  * fix: align positional Controls seed rows with CanLight/CanIndicatorLight columns
  * When getting the value for "form.elements['newMonitor[RTSPStreamName]']" and "form.elements['newMonitor[Recording]']", check for the presence of the elements themselves. (monitor.js.php)
  * Fix: The absence of "#zones-tab" should not result in errors on the Monitor page. (monitor.js)
  * Fix ESLint (skin.js)
  * Added $data['getLogStatusHTML'] = logState() (status.php)
  * Feat: When updating the status panel, also update the status logs (skin.js)
  * Optimizing the waitUntil() function (skin.js)
  * Insert the file name as "text" and not "html" (export.js)
  * Apply suggestions from code review
  * Fixed a regression in retrieving tracks from a stream. (skin.js)
  * When looping through players, check if it's enabled for the monitor. (MonitorStream.js)
  * refactor: remove dead FfmpegCamera::imagePixFormat field
  * fix: include &lt;libavutil/pixdesc.h&gt; in zm_pixformat.h (PR #4788)
  * feat: refresh auth hash on tab resume, redirect to login on dead session refs #4748
  * fix: nullptr-safe pix fmt name in Colourise/Deinterlace_4Field error paths (PR #4788)
  * Delete jquery.panzoom.min.js as unused and without bug fixes
  * Update version jquery.panzoom - Release 4.6.2 (2026-04-02)
  * Update Panzoom 4.6.2 (jquery.panzoom.js)
  * Recovered the spaces lost by Copilot (MonitorStream.js)
  * Potential fix for pull request finding
  * Returned container.appendChild(stream) for createGo2rtcStream() (skin.js)
  * Write "is not" instead of "has not" (view_hls.php)
  * Fix: ESLint (export.js)
  * Don't perform a new AJAX request to check for file existence if the previous one hasn't yet completed.  (export.js)
  * We'll limit ourselves to transferring no more than 100 links and additional file name validation. (event.php)
  * Added a missing space. (MonitorStream.js)
  * Fix: Iterating over players for Player=Auto mode (MonitorStream.js)
  * Potential fix for pull request finding
  * fix: pass delta8_* fn ptrs directly; zm_get_pix_fmt_name in Delta panic (PR #4788)
  * fix: Deinterlace_Discard OOB write on odd heights (PR #4788)
  * Prevent pointless setInterval(this.statusCmdQuery) calls for "frozen" objects. (MonitorStream.js)
  * Interrupt getTracksFromStream() if the stream has been stopped. (skin.js)
  * Restored the missing &lt;canvas&gt; for audioVisualization (Monitor.php)
  * Fix: ESLint (MonitorStream.js)
  * Added error handling. (video-rtc.js)
  * Added error handling. (video-stream.js)
  * Correctly iterates through players when the Player = "Auto" mode is selected. (MonitorStream.js)
  * Deleted the unnecessary line (Event.php)
  * Check the response of file_get_contents() for "false" (view_hls.php)
  * Remove extra space (skin.js)
  * Do not execute checkM3u8File() for live viewing. (skin.js)
  * Allow overflow for "#contentForm" (monitor.css)
  * fix: preserve port and decode url-encoded passwords in parse_ControlAddress
  * Changed the cursor style for &lt;textarea&gt; (skin.css)
  * We will prohibit the use of the ../ combination in paths. (event.php)
  * Apply suggestions from code review
  * fix: more actionable error messages in GetImage/getSnapshot/WriteBuffer (PR #4788)
  * docs: correct epoch-to-UTC time in test comment refs #4870
  * fix: Image(AVFrame*) ctor delegates to default ctor before AssignDirect (PR #4788)
  * chore: bump redhat spec version to 1.39.11
  * chore: bump version to 1.39.11
  * fix: Image::Assign(Image&amp;) handle smaller-source linesize; explicit pixdesc.h (PR #4788)
  * feat: add Indicator LED control capability with session keepalive refs #4875
  * feat: add status-aware Light control capability and control-command response path refs #4869
  * feat: add HiSilicon Hi3510 CGI PTZ control module
  * feat: add Dahua/Amcrest RPC PTZ control module with per-model Controls refs #120
  * feat: re-assert zm.pid in zmdc main loop so systemd keeps tracking refs #4874
  * Fix: Correct state of the "Delete" button if we have only one file in the directory (files.js)
  * fix: Image::Assign(uint8_t*) handle packed source -&gt; aligned dest (PR #4788)
  * fix: apply filter result limit when an empty Tags term is present
  * fix: stop pinning libcurl4-gnutls-dev, fixing curl -dev conflict
  * fix: enforce per-event ACL on direct media endpoints (GHSA-vj5r-pc2v-gfwv)
  * fix: store event StartDateTime with second precision to match disk path refs #4870
  * fix: handle "no frames yet" sentinel before bounds check (PR #4788)
  * fix: use canonical imagePixFormat in Image::Assign(AVFrame*) (PR #4788)
  * fix: free previously-owned buffer in AssignDirect(AVFrame); nullptr-safe logs (PR #4788)
  * Removed "action" parameter from streamCmdStop() as deprecated (watch.js)
  * Apply suggestions from code review
  * When executing the streamCmdStop() command, always stop the stream regardless of the passed "action" parameter.  (watch.js)
  * fix: keep linked event open while source monitor is in ALERT state
  * fix: retain keyframe images so snapshot.jpg is written for pre-event frames refs #4843
  * fix(packetqueue): destroy packets after releasing mutex; drop dead code
  * fix: guard SHM pixformat publish on assign failure (PR #4788)
  * - Optimized setButtonStates() - Added a hidden &lt;INPUT&gt; element to correctly submit the form via JS - Added Russian and English translations for ConfirmDeleteFiles
  * - DIR_EXPORTS_DOWNLOAD is not passed to JS, but is used only in PHP. - When making an AJAX request, we pass an array of file paths relative to DIR_EXPORTS_DOWNLOAD , not absolute ones. - Check $fileName for a non-empty string. - Clear fileExistencePollingInterval if it exists before calling again. - More correctly retrieve parameters from the "el.href" string using "new URL(el.href)". - Disabled the cursor for "a.disabled".
  * Update skin.js
  * Added deleteFiles() (files.js)
  * Confirming file deletion on the Files page (files.php)
  * fix: switch remaining av_get_pix_fmt_name calls in zm_ffmpeg_camera.cpp to zm_ wrapper
  * - Correct HLS playback on the Watch page - When executing Event-&gt;Length() , get the duration of the recorded event file if the duration in the database table is 0 - If native HLS playback fails in Safari, we first try playing MP4, and only if MP4 playback fails do we switch to MJPEG playback
  * fix: nullptr-safe pixfmt name; route GetImage/getSnapshot through ReadShmFrame (PR #4788)
  * fix: SHM padding covers both alignment adjustments (PR #4788)
  * Fix error (export.js)
  * Replaced "let" with "const" (export.js)
  * Added AJAX action='file_existence_check' Added the DIR_EXPORTS_DOWNLOAD constant from PHP to JS Added a style for "#downloadModal a.disabled" on the Events page
  * Removed unnecessary debug information (export.js)
  * If the download file was deleted after downloading, we make the download link for the file inactive. (export.js)
  * fix: per-row Overlay; align image_pixelformats SHM pointer (PR #4788)
  * perf: emit sargable range queries for Date/StartDate/EndDate filter terms
  * fix: stride-aware Delta and Deinterlace_4Field (PR #4788)
  * fix: PopulateFrame error handling + canonical pix fmt in Scale (PR #4788)
  * fix: keep DeColourise/AssignDirect(AVFrame) state self-consistent (PR #4788)
  * fix: Camera::linesize/imagesize back to tightly-packed (PR #4788)
  * fix: ceiling chroma dims in Rotate/Flip; clearer Assign error (PR #4788)
  * fix: dest linesize in HighlightEdges, ceiling chroma dims in MaskPrivacy (PR #4788)
  * Switch to MP4 playback instead of HLS only if a fatal HLS error occurs.
  * Apply suggestions from code review
  * fix: report AVPixelFormat in Panic messages for actionable diagnosis (PR #4788)
  * fix: linesize/planar correctness for Overlay, Rotate, Flip, AssignDirect(AVFrame) (PR #4788)
  * If a defective MP4 video stops or freezes (checking the current time every 1 second), execute fallbackToMjpeg(). (skin.js)
  * Added the data-event-start attribute to the img on the Watch page (watch.php).
  * Before getting infoStatusBar, check for the presence of a statusBar (skin.js)
  * Add a 250ms delay to all thumbnail_onmouseover() code. (skin.js)
  * - Do not check the M3u8 file if currentView === 'frames' - When executing Length() and Duration() , do not write the result to the database. - When assigning a value to the "data-video-duration-secs" attribute, first check the Length in $row['Length'] and, if it is 0, only then check the file's Duration. - If the M3u8 file is missing or invalid, do not cache the server response.
  * Apply suggestions from code review
  * fix: address remaining width-vs-linesize and planar chroma issues (PR #4788)
  * fix: fully invalidate Image on AssignDirect(AVFrame) format failure (PR #4788)
  * fix: use linesize for row stride in pixel ops (PR #4788)
  * Update skin.js
  * fix: cross-process AVPixelFormat sync for alarm_image (PR #4788)
  * Added comment (Event.php)
  * Duration is only saved to the database if it's greater than zero. (Event.php)
  * Added a private Duration() method as a synonym for the Length() method. (Event.php)
  * Use $event-&gt;Duration() instead of "($event-&gt;EndDateTimeSecs() - $event-&gt;StartDateTimeSecs())" (events.php)
  * fix: address PR #4788 review comments on planar sizing and SHM bounds
  * fix: address PR #4788 review comments on SHM publish ordering and overlay bounds
  * fix: only emit HLS/duration attrs for events with video (events.php)
  * fix: address PR #4788 review comments on AVPixelFormat migration
  * Added the m3u8Exists constant, which is used to decide how to play the video. (skin.js)
  * If the m3u8 manifest doesn't contain fragments, then instead of outputting to the page body, save the message in the logs as Warning, since we're passing status code 204.  (view_hls.php)
  * Update skin.js
  * Picky ESLint (skin.js)
  * Before raising statusBar.innerHTML, we check for the presence of a statusBar. (skin.js)
  * Before loading the "index.m3u8" manifest in hls.js, always check the server response status and load the manifest only if the response status is 200. (skin.js)
  * The "data-video-hls-src" attribute should always reference the "index.m3u8" manifest file, even if the physical file is missing. (events.php)
  * If the "index.m3u8" manifest file is missing or if the manifest is invalid, the return status code is 204 instead of 404. (view_hls.php)
  * Removed extra semicolons (skin.js)
  * Fixed cookie reading and video launch for native HLS. (skin.js)
  * Fixed the value assignment for "$args['view']" (Event.php)
  * Fix: ESLint (skin.js)
  * Added support for HLS playback when hovering over the thumbs.(skin.js)
  * Added the "data-video-duration-secs" attribute to VIDEO (events.php)
  * Option to generate 'view=view_hls' (Event.php)
  * Add a link to playback the recorded event using HLS to the IMG tag if there is an index.m3u8 file. (events.php)
  * feat: SHM cross-process format consistency via per-slot AVPixelFormat
  * fix: planar YUV correctness + alignment in Image methods
  * Reapply "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"</changelog>
</package>
<package pkgid="7716c378b8d6644d439af1744c52d4a273f33291088f4cf27ad97c45e2bc42b0125a229ee77310df3c9700d2647f9cca43237044c6379698ee61e167106c4645" name="ZoneMinder-devel" arch="x86_64">
  <version epoch="0" ver="1.39.11+git175.c103c403" rel="153.9"/>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1749470400">- update to latest github master zoneminder-1.36.15+git4939.g5406c6b72
  - unsure why version changed in source but is correct from git describe --tags
-Added iproute2 to Requires for ip command</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1751112000">- update to latest github master zoneminder-1.36.15+git4989.g19018e132
  - fix for fix-ZM_VERSION-already-defined-error.patch</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752235200">- update to latest gihub master 1.37.63+git1081.g42a8e38c8
  - unsure why version changed in source but is correct from git describe --tags</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1752840000">- update to latest github master zoneminder-1.37.63+git1136.g06636d58f</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1761220800">- update to latest github master zoneminder-1.37.63+git1635.g8636cf14d</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1764072000">- update to latest github master zoneminder-1.37.63+git1799.g2cfed3d8f
- Added pam-config to BuildRequires clear build warning
- Added (but could be optional) mosquitoo &amp; mosquitto-devel for MQTT Broker support
- Added requirement for newer gcc - OBS uses gcc 7 but we need 11+
  Using different version for 15.x and 16.x
- Added -DCMAKE COMPILER flags to use gcc/g++ version 11/15 instead of 7
- Renamed README.SuSE to README.SUSE
- Added if/else for ffmpeg for easier building MP version
- added %global _lto_cflags %{?_lto_cflags} -ffat-lto-objects to fix TW Build</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765281600">- update to latest github master 1.37.63+git1831.g24cdd2dfa
  - Possible Security issue: Only output file if the path is under a storage area.
  Fixes #4472. Also use storage_area-&gt;DiskSpace instead of calculating directory
  space for a speedup.</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1765368000">- update to latest github master 1.37.63+git1840.gf0daaaba5</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491200">- update to latest github master 1.37.65+git1450.gf0e5f8cb6</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1766491201">- revert to 1.37.65+git1422.gfbde89c33 to test onvif problem</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1767096000">- update to latest github master 1.37.65+git1454.g4c2f988aa
  - Adds back ONVIF code for cameras that do not send Off</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1768478400">- update to latest github master 1.37.65+1743.g95f1463a5
- Disabled fix-ZM_VERSION-already-defined-error.patch as
  web/includes/config.php.ini works differently now.
- Update to RTSP-Server-ec9035e</changelog>
  <changelog author="obs@mtlfab.com" date="1771416000">- Update to version 1.38.1+git5.3bb76ff0c:
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316800">- Update to RtspServer a071599
- Update .spec file to remove CxxUrl -devel files no longer present.
- Update to version 1.38.1+git427.6aa39892f:
  * Remove pointless view_ variable
  * Fix width=&gt;Width
  * Handle event having no width or height
  * Remove General header
  * Fixup, more footer to bottom of sidebar
  * fix: add missing global declaration for menu icon override in Options
  * fix: correct stats percentage calculations for percentage-space zone area
  * Move user self edit to auth category
  * Fix Eslint (MonitorStream.js)
  * Code optimization (MonitorStream.js)
  * Code formatting improvements (video-stream.js)
  * Update web/js/MonitorStream.js
  * fix: use text input for menu item image icon path instead of file upload
  * fix: use flex layout for zone edit and fix SVG point index error
  * feat: show both percentage and pixel values in zone edit UI
  * fix: add icons to Save and Reset buttons on options menu tab
  * feat: replace console CSV export with JSON monitor export
  * fix: add missing btn classes to sort button on options menu page
  * Update MonitorStream.js
  * fix: fix import modal FormData error and ensure all menu items exist
  * Put back missing Watch view
  * feat: add Profile column to Notifications table
  * The listener assignment has been moved above the noUiSlider check (MonitorStream.js).
  * Using "manageEventListener" for the 'volumechange' event (MonitorStream.js)
  * fix: use DECIMAL(10,2) for zone threshold columns to hold legacy pixel counts
  * fix: store zone thresholds as percentages and convert to pixels at runtime
  * Bump version to 1.39.3
  * feat: add 'none' icon type, show icons in navbar, fix console column dropdown
  * Fix: Eslint (MonitorStream.js)
  * We'll also try receiving tracks from the stream when playback starts for Go2rtc. (video-stream.js)
  * We use manageEventListener to set and remove listeners for the stream's "play" event. (MonitorStream.js)
  * fix: resolve role-based group permissions not granting stream access
  * feat: add custom icon support to menu items (material, font-awesome, image upload)
  * feat: add customizable navbar/sidebar menu via Options &gt; Menu tab
  * fix: add -- end-of-options marker before filename operands in tar/zip/gzip commands
  * fix: clarify warning message field vs file wording
  * fix: validate getimagesize() return value before accessing width/height
  * fix: add -- to cp -as commands to prevent path/flag confusion
  * Initial plan
  * Initial plan
  * Initial plan
  * Fix: Set the bottom margin for the #events table to 10px (watch.css)
  * feat: add ZM_WEB_FILTER_SETTINGS_POSITION config to control filter panel placement
  * fix: close SQL injection, command injection, and shell escaping gaps
  * Fix: Set color for &lt;pre&gt; tag in dark theme (skin.css)
  * fix: harden web interface against injection and SSRF vulnerabilities
  * fix: escape URL in wget() to prevent command injection in camera probe (GHSA-745h-vg7c-73cg)
  * fix: sync analysis button state with zms-reported analysis image status
  * feat: add player selection dropdown to zone edit view
  * feat: add analysis_image field to stream status for client-side verification
  * fix: auto-detect zone coordinate format instead of trusting Units field
  * fix: sanitize monitor Device path to prevent command injection (GHSA-g66m-77fq-79v9)
  * Instead of "useCapture" we use the extended version "options" (skin.js)
  * Instead of "useCapture" we use the extended version "options" MonitorStream.js
  * fix: sanitize exportFile and connkey params in event export to prevent command injection
  * Try out recommended options for debuild when doing binary
  * sync up RtsPServer
  * Add assets to gitignore
  * fix: silence cmake deprecation and policy warnings in deps
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/log.js
  * Update web/skins/classic/views/log.php
  * Update web/skins/classic/views/js/log.js
  * Rename zm_update-1.37.81.sql zm_update-1.39.2.sql so it actually gets run.
  * Fix: Do not assign mediaStream to the video stream if the video stream has already stopped. (skin.js)
  * fix: refresh auth hash before restarting streams in montage view
  * feat: add reset sort button to console view bootstrap-table toolbar
  * Upgrade bootstrap-table to 1.27.0
  * fix: use +1 instead of +last_duration for equal DTS fixup
  * fix: include alarm_frame_count in ready_count calculation
  * fix: add credential fallback chain in ONVIF control module
  * fix: include port in Server URL methods for port-forwarded setups
  * fix: add_monitors table no longer overflows inaccessibly off-screen
  * feat: add Remember Me checkbox to login page
  * feat(log): Add selection to logs and delete for selected logs.
  * Change warn to debug to prevent log spamming
  * fix: Handle incomplete.mp4 in cpp file.
  * fix(lint): Add spaces before comment
  * feat(logs): New button to clear logs
  * fix: Change ffmpeg errors to warnings for incomplete.mp4
  * Use const for Janus onremotetrack locals
  * Instead of handlerEventListener, we use this.handlerEventListener (MonitorStream.js).
  * fix: address Copilot review feedback on Notifications API refs #4684
  * chore: remove plan docs from repo refs #4684
  * fix: change Notifications FK to ON DELETE CASCADE refs #4684
  * fix: make UserId nullable for no-auth mode refs #4684
  * fix: add FK constraint, auth guard, and belongsTo for Notifications refs #4684
  * Update web/skins/classic/views/options.php
  * Update web/skins/classic/views/options.php
  * feat: add Notification model, controller, and route refs #4684
  * feat: add Notifications table for push token registration refs #4684
  * docs: add implementation plan for notifications API refs #4684
  * docs: add design doc for notifications API refs #4684
  * Fix ReferenceError in Janus onremotetrack handler
  * Removed extra space (skin.js)
  * To assign the 'beforeunload' listener and remove the listener, we now use the ManageEventListener class (MonitorStream.js)
  * Added the ManageEventListener class, which allows for more flexible event listener assignment and removal. (skin.js)
  * No additional check for "this.video" is required; simply adding "this.visibilityCheck = false;" (video-stream.js)
  * Update web/skins/classic/views/js/watch.js
  * Use play() on the VIDEO tag, but not from MonitorStream to avoid recursion (MonitorStream.js)
  * refactor: move HAVE_LIBCURL guards inside class definitions as stubs
  * Apply suggestion from @Copilot
  * fix: prevent segfault when MPEG stream codec fails to open
  * fix: add HAVE_LIBCURL preprocessor guards to fix ZM_NO_CURL=ON build
  * fix: remove conflicting minTime/maxTime fields from montage review download
  * Initial plan
  * Initial plan
  * Initial plan
  * Update web/js/MonitorStream.js
  * Update web/skins/classic/views/js/watch.js
  * Update web/skins/classic/views/js/watch.js
  * Fix missing _
  * Fix eslint
  * fix: guard ModelId access with property_exists in Monitor::Model()
  * fix: Replace uppercase cyrillic С with latin C
  * fix: Replace Cyrillic с with a Latin c
  * Correction as recommended by "copilot" (index.php)
  * docs: add zma event re-analysis utility documentation
  * fix: add missing unistd.h include in zma.cpp for FreeBSD build
  * fix: remove unused catch parameter in logger.js to satisfy eslint
  * Update web/skins/classic/js/skin.js
  * When switching monitors, we first destroy the current VolumeSlider and only then change its ID, and not vice versa (watch.js)
  * Removed "waitUntil" since it's now in skin.js (MonitorStream.js)
  * Moved "waitUntil" from MonitorStream.js and now use "waitUntil" to wait until the stream becomes active (skin.js)
  * fix: address review feedback on training PR
  * fix: add SSL certificate verification fallback to base Control class
  * fix: restrict eslint 9 flat config to .js and .js.php files only
  * style: modernize Requires JS to use const/let and jQuery ($j)
  * fix: support arguments in ZM_TRAINING_DETECT_SCRIPT config
  * fix: rebuild data.yaml on annotation delete, code cleanup across training files
  * build(deps): bump crazy-max/ghaction-import-gpg from 6 to 7
  * build(deps): bump actions/upload-artifact from 6 to 7
  * build(deps): bump actions/download-artifact from 7 to 8
  * fix: sync training editor and browse panel on all mutations
  * feat: separate training view from event view with cross-event navigation
  * Update MonitorStream.js
  * feat: add virtual Objects folder to training data browser
  * feat: load saved annotations when editing from browse panel
  * Chore: Optimized saving of "navbar_type" in session and cookies (index.php)
  * feat: Shift+drag to draw box inside existing box, add hint text
  * fix: address Copilot review on Requires implementation
  * feat: implement Config Requires field for dependent option disable
  * fix: use content directory for training data fallback path
  * feat: add edit button in browse preview to navigate back to annotation
  * fix: address Copilot review — path traversal, temp leak, double undo, help text
  * Fix: Eslint (MonitorStream.js)
  * fix: nav guard for unsaved annotations, pending box warnings, UX polish
  * Fix: Receive audio and video tracks only for the active stream (skin.js)
  * Fix: When checking isJSON(), if it is not JSON, warn in the browser console (skin.js)
  * fix: improve TRAINING_DATA_DIR help text for empty path behavior
  * fix: code review fixes, version bump to 1.39.1, remove non-repo files
  * feat: two-panel training data file browser with preview and inline delete
  * feat: add annotate button to objdetect modal, compact stats, delete-all, UI polish
  * fix: remove newlines from BackgroundImageConfirm SLANG entry
  * fix: internationalize all hardcoded user-visible strings
  * fix: allow saving background images and delete pending boxes
  * fix: rename Cancel to Exit, smaller buttons, prevent status line wrap
  * fix: green for accepted boxes, remove label dropdown, leave caps
  * fix: use ZM_EVENT_IMAGE_DIGITS for frame filename padding
  * feat: add Detect button to run object detection on current frame
  * fix: annotation UI improvements and remove objdetect frame
  * fix: remove ZM_DIR_EVENTS derivation from migration
  * fix: guard migration against NULL ZM_DIR_EVENTS
  * feat: add custom model training annotation UI
  * fix: pin @eslint/js to &lt;10 to fix CI eslint dependency conflict
  * Fix: If an RTSP2Web type RTC error occurs, restart the stream instead of killing it (MonitorStream.js)
  * Update MonitorStream.js
  * Fix: Use lowercase when searching for the current go2rtc mode (MonitorStream.js)
  * Fix: Saving "navbar_type" in cookies (index.php)
  * Fix: Apply z-index=3 to the Event page as well (skin.css)
  * Fix: Don't assign "resize" listener when using Observer (zone.js)
  * fix: zmDbDo error logging now substitutes all SQL placeholders with values
  * fix: improve JS error logging for undefined messages and cross-origin errors
  * fix: use portable %jd format for chrono duration count
  * fix: auto-detect and convert pixel zone coordinates to percentages in web layer
  * Satisfy eslint, but also log the error
  * Put back .deb builds on master
  * Only .imageFeed will have the alarm/idle border. Not the img within it or video or anything else. Fixes extra borders and streams jumping around as borders appear/disappear
  * fix: use ResizeObserver for zone point positioning on initial load
  * In "src," use '_CameraDirectPrimary' instead of '_0' in "createGo2rtcStream" (skin.js).
  * The z-index for "svg.zones" cannot exceed the index value for ".zonePoint" (skin.css)
  * For ".imageFeed svg.zones" apply z-index: 100 (skin.css)
  * To determine the go2rtc stream type, use "currentMode" instead of "mode" (MonitorStream.js)
  * Support for getTracksFromStream() and getMonitorStream() for Zones &amp; Zone pages (skin.js)
  * Do not adjust MSE delay if streamStartTime is undefined. (MonitorStream.js)
  * feat: integrate EventStream into montagereview with zms recovery and fixes
  * fix: upgrade ESLint config to v9 flat config format
  * Fix: Check the "players" variable (MonitorStream.js).
  * fix: use DOM img element and rAF loop for MJPEG stream reception
  * feat: add EventStream.js for persistent MJPEG event playback
  * Fix RCE vulnerability via API config edit privilege escalation
  * fix: store speed value instead of index in montagereview cookie
  * fix: improve montage review playback smoothness and fix video seek overshoot
  * fix: calculate optimal thumbnail overlay scale from monitor dimensions
  * Automatically a2enmod rewrite
  * fix: link stdc++fs for std::filesystem on GCC 8 and add zma to RPM spec
  * Add Create to canEdit
  * Add Create to canEdit
  * Fix: PanZoom. When scale &gt; 1, prevent the player from responding to image clicks (panzoom.js)
  * fix: add zma binary to redhat zoneminder.spec file list
  * Fix: Assign toggleZones listener only after Event page loads (event.js)
  * fix: mobile layout for monitor and watch views
  * Hide the #delay block when the stream starts (MonitorStream.js)
  * Push to master repo
  * Push to master repo
  * Don't audit log logins
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Add intel-gpu-tools to recommended packages
  * Add intel_gpu_top view
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * feat: add AUDIT logging level for tracking administrative changes
  * feat: store zone coordinates as percentages for resolution independence
  * Bump to 1.39
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * feat: add pushState URL state management for events page filters
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Log commands used when updating db
  * Add ZoneMinder.spec from OBS project
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * build(deps): bump firebase/php-jwt from 6.0.0 to 7.0.0 in /web
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * fix: guard against null evtStream element in restartZmsStream
  * fix: guard against null monitor div in video-stream.js divMode and divError setters
  * Release 1.38.1
  * fix: normalize date/time filter values to ISO format in montagereview API requests
  * fix: fall back to pixel parsing when zone Units=Percent but coords exceed 100
  * FIx missing / on bottomBlock end div
  * fix: default analysis overlay to off in zms streams
  * fix: use int instead of unsigned int for zone pixel coordinates in zm_zone.cpp
  * feat: expand ONVIF config_types with full device/media/imaging/PTZ queries
  * fix: clamp zone polygon extents to actual frame dimensions in CheckAlarms
  * Removed styles for GridStack, since in version 12 styles are now generated dynamically (montage.css)
  * I created some slightly rounded corners for the streams, tables, and navigation block: .imageFeed, .nav, .fixed-table-body, id='videoFeedStream*' (skin.css)
  * Fix: Eslint (skin.js)
  * Changed the style for ".monitor" a bit (watch.css)
  * Added styles for id=liveStream* (skin.css)
  * Merging and moving two identical functions monitorsSetScale from montage.js and watch.js to skin.js
  * Moving "monitorsSetScale" function from to skin.js (watch.js)
  * Wrap "#dvrControls" and "#extButton" in a single DIV "#bottomBlock" for correct scaling in scale=Auto mode (watch.php)
  * Moving "monitorsSetScale" function from montage.js to skin.js (montage.js)
  * feat: add --protocol mode to zmcontrol.pl for direct module testing
  * fix: handle AV_NOPTS_VALUE pts/dts in VideoStore
  * feat: add zma utility for offline event re-analysis
  * docs: add video group setup to Debian/Ubuntu install guides refs #4642
  * fix: add www-data to video group and font path fallback refs #4642
  * Fix Eslint (MonitorStream.js)
  * Fix space (MonitorStream.js)
  * Calculate the playback start time (video-stream.js)
  * Fix: Don't clear the screen when animations are off
  * When executing "onmse" save "MediaSource" in a class variable (video-rtc.js)
  * Feat: Moved some code to the "manageMSESocket" function (MonitorStream.js)
  * fix: reset send_twice flag after use in EventStream::runStream
  * fix: hold mutex for entire processCommand to prevent frame vector race
  * Added an "onplay" event triggered when playback starts (video-rtc.js)
  * Add intel-gpu-tools to recommended packages
  * Fix space (video-rtc.js)
  * Code optimization (video-rtc.js)
  * RTSP2Web support (watch.js)
  * Fix; Eslint (watch.js)
  * Update video-stream.js
  * Fix: If you click “pause”, then hide the page and display it again after at least 15 seconds, the stream will still be paused and not start (as it was before) (watch.js)
  * Added "zmsState" and its processing (MonitorStream.js)
  * Use streamCmdPlay instead of monitorStream.start (watch.js)
  * Code optimization (MonitorStream.js)
  * Code optimization (watch.js)
  * Code optimization (watch.js)
  * Now we use destroyVolumeSlider() when changing the player and when changing the monitor. (watch.js)
  * Changed the destroy method for VolumeSlider (MonitorStream.js)
  * Start playback using a promise (video-rtc.js)
  * Revert MonitorStream.js
  * Update video-rtc.js
  * Add intel_gpu_top view
  * Fix: Display volumeSlider when switching monitors on the Watch page (MonitorStream.js)
  * fix: prevent segfault in MonitorStream::processCommand from shared memory race
  * #volumeControls always includes the monitor ID (MonitorStream.js)
  * Fix: Fix desync between audioStream.muted and MonitorStream.muted (MonitorStream.js)
  * Completely remove noUiSlider from volumeSlider, not just destroy it. (watch.js)
  * ci: use dynamic branch and deploy targets in deb package workflows
  * Convert warning to debug
  * Revert "Add release-1.38 version of rpm building"
  * Destroy the "VolumeSlider" when switching to another monitor. (watch.js)
  * Optimizing "VolumeSlider" (MonitorStream.js)
  * streamPause() in pauseClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('pause'... event is triggered. (event.js)
  * Log commands used when updating db
  * Add release-1.38 version of rpm building
  * ci: add -v=1 to do_debian_package.sh invocations
  * fix(ci): use -r=&lt;tag&gt; for release builds instead of -s=CURRENT
  * fix(ci): fetch do_debian_package.sh from release-1.38 and fix safe.directory
  * ci: rename proposed rsync target to proposed-1.38
  * ci: update aarch64 deb package workflow for release-1.38 branch
  * ci: update deb package workflow for release-1.38 branch
  * Add ZoneMinder.spec from OBS project
  * streamPlay() in playClicked( ) should only be run for MJPEG, since for VID we do this when the vid.on('play'... event is triggered. (event.js)
  * feat: add pushState URL state management for events page filters
  * feat: add AUDIT logging level for tracking administrative changes
  * Fix: Event handling for VID (event.js)
  * Exit the getTracksFromStream function if it could not determine the Monitor.ID from the passed stream (skin.js)
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * build: add selective man3 generation for audited Perl modules
  * build: replace Perl ExtUtils::MakeMaker with pure CMake install
  * fix: update heartbeat during camera close and reconnect
  * Add 4px border-radius to thumbnail img
  * fix: correct App::uses package path in CameraModel
  * Fix: Stop executing "streamQuery" if "zmsBroke" (event.js)
  * Color input[type='checkbox'], input[type='radio'] on dark skin (skin.css)
  * Fix: Color of some buttons on a dark skin (skin.css)
  * fix: warn when zone coordinates extend beyond image dimensions
  * fix: skip V4L2 AutoSelectFormat in non-capture mode
  * fix: remove file_exists() gate on /dev/video in settings modal
  * perf: replace sleep polling with condition wait in Event::Run()
  * perf: reduce lock contention in PacketQueue
  * fix: preserve legacy execlp() behavior for commands without % tokens
  * fix: shell-escape %EC% token to prevent command injection
  * feat: support token substitution in EventStartCommand/EventEndCommand
  * Fix: Clear "srcObject" for "Stream" and adjust Janus connection timeout (MonitorStream.js)
  * Moved getTracksFromStream from MonitorStream.js (skin.js)
  * Added getTracksFromStream function for Go2RTC (video-stream.js)
  * Moved the getTracksFromStream functions to sfin.js, as this will allow you to retrieve tracks from recorded events. (MonitorStream.js)
  * refactor: remove unused reuse_image_ member to keep changes minimal
  * refactor: use reusable reuse_filepath_ member in EventStream::sendFrame
  * Initial plan
  * feat: store zone coordinates as percentages for resolution independence
  * fix: resolve "no url in button" when adding detected cameras
  * refactor: move format_absolute_time_iso8601 from zm_monitor_onvif to zm_time
  * Remove fatal version check. Just error.
  * refactor: use CxxUrl for URL auth injection in FFmpegCamera
  * Bump to 1.39
  * feat: add option to use system-installed jwt-cpp</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773316801">- Add intel-gpu-tools to recommended packages</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1773835200">- spec file improvements:
  * Removing perl-Archive-Tar requires, as it's part of the perl package.
  * Using autopatch macro.
  * Reordering MP macros/sections
  * Better gcc handling for version &lt; 1600
  * Added ZoneMinder-rpmlintrc</changelog>
  <changelog author="obs@mtlfab.com" date="1776254400">- Update to version 1.38.1+git566.2a29e6318:
  * fix: HLS fragment tracking, live playback, and fallback handling
  * Don't pass null as first parameter to strtotime().
  * fix: convert zone threshold columns to DECIMAL before running conversion procedure
  * chore(deps): Bump softprops/action-gh-release from 2 to 3
  * feat: add HLS byte-range playback for event video
  * Fix: For "nouislider.min.css" we use "cache_bust", i.e. disabling caching when the file changes. (functions.php)
  * Update sidebar.css
  * Fix: More correct ".sidebar-footer" style (functions.php)
  * Force memory release of GDImage for PHP &gt;= 8.0.
  * Conditionally calls imagedestroy() as it was deprecated since PHP 8.0 doing nothing except logging errors.
  * Check for /proc/meminfo before reading its content. There is no such proc file system on FreeBSD, hence http server logs a lot of errors.
  * fix: guard MSE addSourceBuffer against detached MediaSource
  * Use qx() lc() and chomp() for command execution and result. Use eq in the if() statement, instead of '=='.
  * fix: prevent empty events in ONDEMAND mode and fix VideoStore fd/codec leaks
  * Change ::Config{uname} to ::Config{ZM_PATH_UNAME}
  * fix: scan-line polygon fill incorrectly filled non-convex polygon gaps
  * Use ZoneMinder::Config.
  * fix: exclude orig tarball from deb uploads to zmrepo
  * Fix "top" command parsing on FreeBSD (tested in FreeBSD 13.5 jail, running 1.38.1).
  * fix: show Device text input when no device is selected on load
  * fix: run form validation on Save button click
  * fix: only validate Device path for Local monitors
  * fix: limit filter Name input to 64 characters
  * fix: add missing dash separator in Content-Range header
  * fix: treat ENOTTY like EINVAL when querying V4L2 JPEG compression options
  * fix: call disconnect() in MonitorLink::connect() before reopening map_fd
  * Move the delay calculation code to after we run the filter so that the time taken running the filter is included
  * Rename last_action to last_reload as that is what it actually is
  * Include ExecuteInterval in warning
  * fix: free video_out_ctx after failed avcodec_open2 in new_extradata path
  * fix: fd leak in MonitorLink::disconnect() when connect() fails
  * Don't use Fatal when there is an error preparing the sql. handle PostSQLConditions being an empty array
  * Include ExecuteInterval in warning
  * Use now instead of 0 when no last_ran so that elapsesd=0 on initial run, and we don't log a warning.
  * fix: redirect stdin/stdout/stderr to /dev/null instead of closing them
  * Warn() -&gt; Warning().  Fixes #4724
  * fix: add Warn() as exported alias for Warning() in Logger
  * fix: reset last_write_index in Pause to restore DECODING_ONDEMAND bootstrap
  * Update options.css
  * Do not use the "form-control-sm" class for rows. (options.php)
  * fix: guard against empty auth_relay producing double &amp;&amp; in zms URLs
  * Fix missing quotes
  * Bump up ubuntu and python version for readthedocs
  * fix: guard against null websocket in VideoRTC.onopen
  * fix: use shoelace formula for zone threshold pixel-to-percent migration
  * fix: null-check StorageId column in Monitor::Load to prevent segfault
  * Upgrade bootstrap-table to 1.27.1
  * fix: add DTS backward jump detection in ffmpeg camera capture
  * Update MonitorStream.js
  * Update MonitorStream.js
  * Revert watch.php
  * fix: clamp user bandwidth before defining ZM_WEB_* constants
  * chore: remove obsolete ZM_FILTER_EXECUTE_INTERVAL config option
  * fix: use minimum per-filter delay instead of last filter's delay in zmfilter
  * fix: use prepare instead of prepare_cached in Filter::Execute
  * fix: clear accumulated state in Filter::Sql() before rebuilding
  * Set style for "div.volume" (skin.css)
  * SPAN tag replaced with DIV tag (watch.php)
  * SPAN tag replaced with DIV tag (functions.php)
  * Added missing UL tag (functions.php)
  * Remove extra space (functions.php)
  * Fix: Removed extra space and extra slash (functions.php)
  * Update web/skins/classic/views/watch.php
  * Include full path in warning when fail to cache bust
  * Log the value when event_close_mode is unkown
  * fix: handle HTTP-to-HTTPS redirect in Reolink_HTTP login
  * fix: prefer MJPEG over raw YUV in V4L2 AUTO palette selection
  * fix: add missing CLOSE_DURATION event close mode handling
  * Added a link to the PR (watch.php)
  * Prevent vertical shifting of #content on the Watch page when displaying the stream status overlay. (watch.php)
  * When executing monitorChangeStreamChannel(), always write the new channel to the cookie and to monitorStream.currentChannelStream (watch.js).
  * Don't use "scrollTo" because it doesn't work properly. (console.js)
  * Silent refresh bootstrapTable on Console page (console.js)
  * wip
  * wip
  * When starting a stream on the Watch page, don't execute controlMute() (watch.js)
  * If the system volume was set to 0, change the state of the "Mute" icon in the volume slider (MonitorStream.js)
  * fix: preserve fractional percentages in zone threshold migration
  * A finger-shaped pointer cursor for the hide/show password buttons (skin.css)
  * Read from 'zmWatchMuted' cookies instead of 'zmWatchMute' (watch.js)
  * fix: include username in auth relay and fix stale auth in stream restart
  * Add br after USE ONVIF events
  * fix: add event-id latch to linked monitor score detection
  * fix: reduce linked monitor reconnect throttle from 60s to 1s
  * Set "pointer-events: none" for "imgInfoBlock" and "infoBlock" to disable pointer events for them (MonitorStream.js)
  * When stopping a stream, execute writeTextInfoBlock after checking the existence of the stream (MonitorStream.js)
  * Normalizing text before assigning it to a DOM element
  * feat: add ZM_WEB_SHOW_SERVER_STATS config to toggle navbar stats
  * Instead of "setTextSizeOnInfoBlock," we now use the new "setTextSizeOnInfoBlocks" function, which sets the text size for all blocks. (skin.js)
  * Instead of explicitly specifying the text size, we use a call to the new function "setTextSizeOnInfoBlock" (MonitorStream.js)
  * feat: add ZM_WEB_SHOW_NAV_BUTTONS config to hide Back/Refresh buttons
  * feat: add ZM_WEB_BUTTON_STYLE config for icons+text, icons, or text buttons
  * Fix: Eslint (MonitorStream.js)
  * Remove extra space (skin.js)
  * When a stream is loaded, paused, or stopped, display a corresponding caption in the center of the stream player. (MonitorStream.js)
  * feat: make Remember Me a tri-state option (None/Yes/No)
  * Added styles for 3D text (skin.css)
  * Added calculation of the text size displayed in the information block (skin.js)
  * fix: strip &lt;br/&gt; from bootstrap-table column picker labels
  * fix: compact montage header layout and move Show Zones to settings row
  * Don't add postLoginQuery to url if it is empty
  * Move tag related commands to canView(Events) instead of canEdit(Events)
  * Updated .spec for OpenSUSE - Corrected
  * Updated .spec for OpenSUSE
  * Increase potential config line size. HTML snippets can easily be larger than 256</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1778760000">- Update to version 1.38.1+git876.2b1627e2:
  * fix: flush decoder_queue on decoder thread exit to avoid stale latency offset across reconnect
  * perf: index Sessions.access and rework session gc to two-phase delete
  * fix: derive event end time from Length when EndDateTime is missing
  * fix: align auth hash validation with generation and warn on user mismatch
  * fix: sanitize reflected user input in ajax error messages
  * fix: remove reflected user input from log ajax XSS sinks
  * fix: do not return SQL error text to client in events ajax
  * fix: remove reflected user input from events ajax XSS sinks
  * Update sidebar.css
  * fix: sanitize download params at event ajax boundary
  * Minor optimization of the sidebar footer box (sidebar.css)
  * fix: sanitize export filename and connkey at event ajax boundary
  * fix: remove reflected user input from event ajax XSS sink
  * fix: remove reflected user input from device ajax XSS sinks
  * fix: remove reflected user input from add_monitors XSS sink
  * feat: recalibrate ZonePresets for modern HD resolutions
  * fix: clamp percentage polygon to width-1/height-1
  * Potential fix for pull request finding
  * Potential fix for pull request finding
  * fix: QP-encode plain-text email body so URLs survive transit
  * Update log.php
  * Fix: Yesli v sessii byl sokhraneno znacheniye "Components", yavlyayushcheyesya pervym elementom massiva "$components", to ono ignorirovalos' pri formirovanii "$selected_component" (log.php) Privesti ZM_WEB_REFRESH_LOGS k tipu INT pered sravneniyem (log.php) YA ne ponimayu, pochemu tip znacheniya `ZM_WEB_REFRESH_LOGS` stanovitsya str, a ne int. Ved' `ZM_WEB_REFRESH_LOGS` poluchayetsya iz `ZM_WEB_*_REFRESH_LOGS`, kotoryye v baze dannykh khranyatsya kak integer. YA vnes ispravleniya v kod https://github.com/ZoneMinder/zoneminder/pull/4819/changes/06f1178a99f6985c9b9c625c3812a576e993de0e, no ya khochu razobrat'sya, pochemu i gde proiskhodit zamena tipov. Vot zapros i rezul'taty zamera. Pervyy zamer - obychnyy indeks. Vtoroy zamer pokryvayushchiy indeks Raznitsa v skorosti vypolneniya boleye 10 raz i eto pri smeshchenii vsego 250000 Dobavil podderzhku konstanty ZM_WEB_REFRESH_LOGS (log.php) Feat: Dobavil nastroyku dlya obnovleniya okna Log page (ConfigData.pm.in) Dobavil konstantu ZM_WEB_REFRESH_LOGS (config.php) Isaac, tebya chto-to ne ustraivayet? Ozhidayu tvoi kommentarii, zamechaniya. Schitayu dannyy PR zakonchennym Poprosi pozhaluysta Copilot proverit' dannyy PR Dobavit' v pervichnyy indeks Component, TimeKey, Level dlya uvelicheniya skorosti obrabotki zaprosov Ispol'zovaniye JOIN podzaprosa pozvolyayet uskorit' vypolneniye osnovnogo zaprosa v 10-20 raz bystreye. Tak-zhe sleduyet proizvodit' otbor po stolbtsu 'Level', a ne 'Code', t.k. imenno 'Level' u nas indeksiruyetsya Optimizatsiya medlennykh SQL zaprosov pri bol'shoy tablitse Optimizirovannyy zapros Dlya optimizitsii zaprosov s ispol'zovaniye podzaprosa Ne posylat' AJAX zaprosy obnovleniya tablitsy, yesli stranitsa skryta (log.js) Eto znachitel'no snizit nagruzku na server. T.k. seychas, yesli otkryt' mnogo Log page i svernut' ikh, to zaprosy postoyanno postupayut na server! Da, kak ya i dumal, rasshireniye mozhet byt' mp4 or mkv or webm (kak dlya zakonchennogo fayla, tak i dlya incomplete), po etomu ya izmenil shablon dlya poiska. YA ne stal perechislyat' vse vozmozhnyye rasshireniya, t.k. v budushchem oni mogut izmenit'sya. Izmenen shablon okhvatyvayushchiy fayly s lyubym rasshireniyem, t.k. ono mozhet byt' mp4 or mkv or webm (functions.php) Dopolnitel'naya proveka sushchestvovaniya fayla Chto by my ne vernuli ssylku na nesushchestvuyushchiy fayl Khotya.... Fayl ved' imeyet takoye imya: `incomplete.h264.mp4`, t.ye. shablon `/incomplete.*.mp4` yavlyayetsya korrektnym. Vozmozhno sleduyet ispol'zovat' shablon `/incomplete*.*`? @connortechnology Chto ty dumayesh' naschet etogo? Eto ne moya oshibka, ona poyavilas' v kode iz za kommita https://github.com/ZoneMinder/zoneminder/commit/3f8bc81760071f49bdce894c664cd507820dcfaa Pri kopirovanii koda ya ne proveril i eto plokho s moyey storony. Zdes' ya ispravlyu, no tak-zhe neobkhodimo ispravit' i v `web/views/view_video.php‎ ` Obrabatyvat' $Event-&gt;DefaultVideo() vsegda kak stroku Vozmozhno eto izlishnyaya proverka, no pust' budet tak... YA reshil proanalizirovat', iz za chego poyavlyayutsya tormoza v SQL i uzhasnoye potrebleniye pamyati. YA vklyuchil logirovaniye medlennykh zaprosov i uzhasnulsya.... YA nakhodilsya na 3y stranitse prosmotra logov (po 25 strok na stranitsu). YA pereshel na 75823 stranitsu (da, u menya 1674290 strok ) Pochemu-to ne verno rasschityvayetsya kol-vo stranits, no s etim pozzhe mozhno razobrat'sya.... I vot chto ya uvidel v medlennykh zaprosakh: U menya yest' mysl', kak uskorit' rabotu SQL s bol'shimi tablitsami. YA poprobuyu. Put' k faylu dlya sobytiya KHKHKH ne nayden Ne naydeno ni odnogo fayla sobytiya dlya eksporta sobytiy monitora s ID=18. Dobavil proverki 3 462 Fix: If the "Components" value, which is the first element of the "$components" array, was stored in the session, it was ignored when generating "$selected_component" (log.php)
  * Cast ZM_WEB_REFRESH_LOGS to INT before comparison (log.php)
  * build(deps): bump actions/dependency-review-action from 4 to 5
  * Fix: Save the selected "All" value in the "zmLogComponent" session (log.php)
  * Preventative loop protection ZM_WEB_REFRESH_LOGS=0 (log.php)
  * Added support for the ZM_WEB_REFRESH_LOGS constant (log.php)
  * Updated description (ConfigData.pm.in)
  * Added the ZM_WEB_REFRESH_LOGS constant (config.php)
  * Feat: Added a setting for refreshing the Log page window (ConfigData.pm.in)
  * Fix: Correct calculation of the total number of pages for pagination with filters (log.php)
  * Apply style only to "#pills-tab" (monitor.css)
  * FIx enmod rewrite
  * Potential fix for pull request finding
  * Pass the $encoding parameter to mb_strtolower/mb_strtoupper (functions.php)
  * Potential fix for pull request finding
  * Optimizing the menu style on the Monitor pagemonitor.css
  * Fix: Annoying error getting $file_path due to ".$file" (image.php)
  * fix: honor explicit port argument in urlToApi single-server case
  * fix: urlToApi falls back to location.host in single-server case
  * Update lang.php
  * Moved the "mb_ucfirst" function to \includes\functions.php (functions.php)
  * Moving the "mb_ucfirst" function from \skins\classic\includes\functions.php And adding a new "mb_lcfirst" function (functions.php)
  * Feat: Search for translations without regard to the case of the first letter (lang.php)
  * If the index.m3u8 file is missing, then MP4HLS is disabled in the select (event.php)
  * feat: encoder parameter templates with editor + REST API closes #4778 closes #4802
  * Feat: Added codec="MP4HLS" (event.php)
  * Update view_video.php
  * More correct assignment of the $path_info value (view_video.php)
  * Update ru_ru.php
  * Instead of "MP4" we will specify "video" (event.php)
  * Potential fix for pull request finding
  * feat: add Report::canEdit() and CreatedBy column
  * ci: skip CodeQL on changes that contain no scanned languages
  * ci: add scheduled workflow to prune old Actions caches
  * Avoid PHP Notice (view_video.php)
  * Fix: Pop-up file name on download button (event.php)
  * Fix: Loading incomplete.mp4 event file (view_video.php)
  * Fix: Display snapshot for incomplete event file (Update image.php)
  * Fix a2enmod cgi =&gt; a2enmod rewrite causing install to fail.
  * Add depenencies for resolute raccoon
  * Analyzing "space" and "," key presses for positioning in the tag input field (event.js)
  * fix: use HTTP_X_FORWARDED_FOR in auth hash validation to fix AUTH_HASH_IPS with reverse proxy
  * Initial plan
  * fix: ensure trigger_state written last in zmTriggerEventOn to fix 1/3 event trigger rate
  * Initial plan
  * Prevent the scrollbar from appearing when displaying table column visibility settings (options.css)
  * Added $CLANG (lang.php)
  * Potential fix for pull request finding
  * docs: document all ONVIF_Options key=value pairs
  * Initial plan
  * Revert "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"
  * fix: PR #4742 round 2 review feedback
  * fix: silence spurious Overlay subpixel-order warning post-AVPixelFormat
  * fix: PR #4742 review feedback + drop stray u_buffer assignments
  * Tag Management Optimization (event.js)
  * Update files.php
  * Added table styles (files.css)
  * Fix: .tags-container on Event page if screen is narrow and there are many tags (skin.css)
  * Fix: ESLint (audioMotionAnalyzer.js)
  * fix: parse HTTP Range header correctly in output_file() fixes #4777
  * build: add Profile CMAKE_BUILD_TYPE for perf/flamegraph
  * fix: bail from MonitorStream::runStream when monitor failed to load
  * To avoid overriding the zmVlang() function (en_gb.php)
  * Merge an array from a custom language file and en_gb.php (lang.php)
  * Update ru_ru.php
  * Correction of the Russian translation (ru_ru.php)
  * Chore: Minor UI optimization for ".tags-container" on the Event page (skin.css)
  * fix: parse audioMotionAnalyzer.js as module so ESLint succeeds
  * Change from translate('What display') to translate('Show') (event.php)
  * Fix: Eslint (skin.js)
  * In applyTemplateAudioMotionTranslation() , execute createClickableLink() &amp; replaceDoubleTildeToBR() (monitor.js)
  * Revert (lang.php)
  * Added replaceDoubleTildeToBR() &amp; createClickableLink() function (skin.js)
  * perf: skip clearPackets early-returns and allow drop-to-iterator-keyframe
  * Apply ".flex-col-2" and ".flex-col-3" to all pages, not just the User page (skin.css)
  * Added ".flex-col-3" for "#frames" (event.php)
  * Changed style for "#frames img" (event.css)
  * Chore: Minor improvements to statistics display on the Event page (event.css)
  * customElements.define moved after the class declaration (audioMotionAnalyzer.js)
  * Abort checkVerAudioMotion() if we couldn't get the CURRENT_AUDIO_MOTION_ANALYZER_VERSION value (monitor.js)
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Fix: https://github.com/ZoneMinder/zoneminder/pull/4752#discussion_r3158319612 (user.php)
  * For now, apply the "legend" style only to the User page (skin.css)
  * Update web/skins/classic/css/base/skin.css
  * Update web/lang/en_gb.php
  * Potential fix for pull request finding
  * Don't use "await" when calling "insertModalHtml()" (options.js)
  * fix: clean up ONVIF subscription before re-Subscribe to stop NotAuthorized loop
  * Update image.php
  * Update image.php
  * Prevent an error from being generated when processing the file "index.m3u8" (image.php)
  * We'll now pause audioMotion in MonitorStream.js. (MonitorStream.js)
  * Added the pauseAudioMotion() function. (skin.js)
  * Now we will pause audioMotion in MonitorStream.js (watch.js)
  * Avoid reinitializing audioMotion if the previous one has not yet finished. (audioMotionAnalyzer.js)
  * Remove  extra "&lt;" (event.php)
  * Instead of " use ' (console.js)
  * Added id="header" (event.php)
  * Apply "chosen" to the Event page (event.php)
  * Update console.php
  * When using ONVIF, the console page should not display simply "Use ONVIF Events", but should also indicate which event the trigger is configured for. (console.js)
  * Bump version to 1.39.5
  * The missing comma has been restored (zm_update-1.39.5.sql)
  * If WhatDisplay already exists, ensure it is the right enum
  * - Added support for "~~" =&gt; &lt;br/&gt; for translation - Now we only specify the supported analyzer version in one place in the audioMotionAnalyzer.js file - Added translations for three cases: when the analyzer is not installed, the wrong version is installed, or everything is fine.
  * Added `WhatDisplay` to the 'Monitors' table (zm_create.sql.in)
  * Upload audioMotionAnalyzer.js to the Monitor page (functions.php)
  * - Style optimization. - Added support for the "flex-col-X" class, where X can be 2 or 3. This is used in cases where, for example, we need to display a theoretical 3 columns, but 1 or 2 of them may not be displayed in certain cases. The remaining columns will then take up all available space. Can be used in conjunction with "col-md/lg-*", which will be placed inside "flex-col-X".
  * Fix: bootstrap legend (skin.css)
  * Adjusting the display of the "infoBlock" block (MonitorStream.js)
  * Create zm_update-1.39.5.sql
  * Safely using $_REQUEST['title'] and $_REQUEST['key'] (delconfirm.php)
  * Update options.js
  * Update version
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Apply suggestion from @Copilot
  * Update web/skins/classic/views/js/options.js
  * Set retention-days: 1
  * Added missing spaces. (options.js)
  * Added translations.
  * - Added the ability to specify a title for the window in the \ajax\modals\delconfirm.php file. - Added the "DeleteUser" function to be executed when the "Delete" button is clicked.
  * Display a modal window confirming the deletion of a user (options.js)
  * Align the thumbnail on the Console page horizontally to the center of the table cell (console.css )
  * Layout optimization
  * fix: restore getCycleHTML for Watch/Cycle navbar item refs #4745
  * Update skin.css
  * Layout optimization
  * Moved .button-block from options.css to skin.css
  * Layout optimization (_options_api.php)
  * Layout optimization (options.php)
  * Added style for ".button-block" (options.css)
  * Optimizing styles for the Options page (options.css)
  * Update ru_ru.php
  * Added Russian translation (ru_ru.php)
  * feat: add G.711 μ-law (PCMU) audio support to zm_rtsp_server
  * fix: coerce null ParentId to '' for array offsets in groups view
  * Added support for audioMotion-analyzer.js in various formats (audioMotionAnalyzer.js)
  * Update audioMotionAnalyzer.js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Analyzing AUDIO_MOTION_ENABLED and checking $whatDisplay using strtolower (Monitor.php)
  * Analysis of AUDIO_MOTION_ENABLED (montage.php)
  * fix: skip sws_scale for identity conversions in Image::Assign
  * Delete web/skins/classic/assets/audioMotion-analyzer/src/audioMotion-analyzer.js
  * Create help.txt
  * Added analysis of the AUDIO_MOTION_ENABLED constant (Monitor.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant for $htmlAudioControlPanel (montage.php)
  * Added analysis of the selectorWhatDisplay variable (montage.js)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (montage.php)
  * style: fix eslint errors in onvif probe js
  * Added analysis of the AUDIO_MOTION_ENABLED constant (watch.php)
  * Added analysis of the AUDIO_MOTION_ENABLED constant (event.php)
  * Added function checkAudioMotionEnabled() (audioMotionAnalyzer.js)
  * fix: YUV422P passthrough and libjpeg grayscale for planar YUV
  * Added translation for OPTIONS_WHATTODISPLAY (en_gb.php)
  * Added translation for OPTIONS_WHATTODISPLAY (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (ru_ru.php)
  * Added translation for RequiresAudioMotionEnabled (en_gb.php)
  * Change requiresAudioMotionEnabled -&gt; RequiresAudioMotionEnabled (monitor.php)
  * Added handling of the AUDIO_MOTION_ENABLED constant to ensure correct operation in the absence of the "audioMotion-analyzer.js" file. "monitor.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" "functions.php"
  * Added constant AUDIO_MOTION_ENABLED for correct operation in the absence of the file "audioMotion-analyzer.js" (skin.js.php)
  * Correct operation without the "audioMotion-analyzer.js" file
  * fix: use decoded frame's native pixel format instead of Monitor.Colours
  * fix: compute Camera linesize/imagesize from pixelFormat, not hardcoded YUV420P
  * fix: use zm_bytes_per_pixel for pixel-rendering dispatch instead of GRAY8-only
  * fix: handle YUVJ422P/YUV422P in zm_colours_from_pixformat
  * fix: sync imagePixFormat in WriteBuffer, Assign, and AssignDirect
  * fix: replace ZM_COLOUR_*/ZM_SUBPIX_ORDER_* with AVPixelFormat for format dispatch
  * feat: install SIGPIPE handler in zms for clean browser-disconnect shutdown
  * fix: guard changeFilters against invalid date input in montagereview
  * Update web/skins/classic/views/js/onvifprobe.js
  * Update web/skins/classic/views/js/onvifprobe.js
  * fix: use full codec profile strings in canPlayCodec feature detection
  * fix: strip SKIP LOCKED from EXPLAIN query in filter debug modal
  * fix: sort events by Tags column alias, not T.Name
  * fix: log bind params correctly when SQL contains literal % characters
  * perf: default ffmpeg decoder thread_count to 2
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (ru_ru.php)
  * Added translation for "OPTIONS_ONVIF_Alarm_Text" (en_gb.php)
  * Added a description of some possible value options for recognizing ONVIF events (monitor.php)
  * Apply suggestion from @Copilot
  * style: replace size attribute with CSS width on manual URL input
  * feat(onvif): add manual camera URL entry to ONVIF probe
  * Removed extra semicolons (watch.js)
  * Added translation for "OPTIONS_WHATTODISPLAY" en_gb.php
  * Load audioMotionAnalyzer.js only on Watch, Montage, and Event pages (functions.php)
  * We'll use $cspNonce (functions.php)
  * Update web/skins/classic/js/skin.js
  * Declare constants (skin.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/views/montage.php
  * Update web/skins/classic/views/watch.php
  * Instead of audioMotion.play(), use audioMotion.init() (MonitorStream.js)
  * Update web/skins/classic/views/event.php
  * Update web/skins/classic/js/skin.js
  * Set maxFPS=30 instead of 50 (audioMotionAnalyzer.js)
  * Feat: Run changeWhatDisplay() without refreshing the page (watch.js)
  * Update skin.js
  * Fix: Eslint (MonitorStream.js)
  * skin.js - Clear IconMute when executing destroyVolumeSlider() - Added the ability to clear the icon state to changeStateIconMute()
  * Removed an unused constant
  * Fix: Eslint
  * Creating a volume slider on the Montage page to simultaneously control the volume of all monitors
  * Add changeWhatDisplay() (event.js)
  * Add $whatDisplay (event.php)
  * Add "#whatDisplayControl" (event.php)
  * Fix parent
  * If we don't display the video, then display the information block on "#monitorXX"
  * Style adjustments
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Remove extra space
  * Audiovisualization
  * Added audio visualization
  * Update functions.php
  * Added &lt;audio-motion&gt; (Monitor.php)
  * Loading "nouislider" and "audioMotion-analyzer" (functions.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1780315200">- Update to version 1.38.1+git1083.97755a96:
  * If the requested Object isn't found in the database, generate a Warning instead of an Error. (Object.php)
  * Use hostname obtained via "parse_url", do not use regular expression to obtain IPv4 (onvifprobe.php)
  * Apply suggestions from code review
  * Now we don't need to return "$monitor-&gt;Id()" because we can get Monitor.Id after Id has become public. (monitor_probe.php)
  * We use Monitor.Id again instead of MonitorId, since Id is now publick
  * "Id" is now public, not protected.  (Monitor.php)
  * Update skin.js
  * When closing SIDEBAR_MAIN_EXTRUDER, reset its z-Index (skin.js)
  * Replaced "stream.Monitor.Id" with "stream.MonitorId" (add_monitors.js)
  * Use "parse_url" instead of "preg_match" when determining hosts (onvifprobe.php)
  * The added class must be escaped using htmlspecialchars() (functions.php)
  * I added ".chosen" in STEP 2. (onvifprobe.php)
  * Removed extra parentheses (monitor_probe.php)
  * fix: widen DefaultScale columns to preserve fit_to_width
  * Added the "controlHeader" class to the filter block on the Events page (Filter.php)
  * Fix Aligning input fields (sidebar.css)
  * Changed the style of the active button in "nav #pills-tab" for the dark theme (monitor.css)
  * Changed the style of the active button in "nav #pills-tab" (monitor.css)
  * Apply scrollbar style to all elements (skin.css)
  * Remove "Loading, please wait" if nothing is found (add_monitors.js)
  * Removed unused const "Monitor" (add_monitors.js)
  * Pass 'MonitorId' in the returned array, since the private method does not pass the monitor ID. (monitor_probe.php)
  * Correctly get Monotor.Id for editing a monitor (add_monitors.js)
  * More readable text color for the DBG level for the dark theme (log.css)
  * Added the ability to specify a class for &lt;select&gt;&lt;option&gt; in the htmlSelect() function (functions.php)
  * Added a style (onvifprobe.css)
  * Optimized the drop-down list of found monitors. (onvifprobe.php)
  * Apply suggestions from code review
  * Added style for .chosen-container
  * Use "Chosen" on Onvifprobe page (onvifprobe.php)
  * Fix: Correct reading of zmWatchMuted cookies
  * fix: avoid OOB read on negative gsoap error codes in ONVIF Subscribe fixes #4842
  * fix: keep DefaultVideo as mp4 name throughout event lifecycle refs #4839
  * fix: polyfill str_starts_with/str_ends_with/str_contains for PHP 7
  * fix: make zm_update-1.39.10.sql idempotent for reruns
  * More correctly retrieves Component from $_REQUEST and writes it to the session (log.php)
  * More correct retrieval of zmLogFilterLevel from session (log.php)
  * fix: keep console summary row aligned when toggling event columns
  * More correct parsing of $_REQUEST['level'] before assigning its value to $L (log.php)
  * fix: string-compare BIGINT counters in zmaudit CAS skip checks
  * Potential fix for pull request finding
  * Correctly save setCookie('zmWatchMuted') when "=false" (MonitorStream.js)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * Don't use the $newSessionValue array and cast $_REQUEST['level'] to a scalar string (log.php)
  * feat: refresh auth hash and retry on MonitorStream image error
  * fix: enrich zms auth-failure warning with diagnostic fields
  * fix: only show 'Use ONVIF' badge on console when listener is enabled
  * Edited comment (log.js)
  * Potential fix for pull request finding
  * fix: CAS-guard Event_Summaries UPDATE in zmaudit to preserve concurrent writes
  * fix: chunk zmstats bucket-prune DELETE IN-list to avoid packet-size limits
  * fix: CAS-style Storage DiskSpace update in zmaudit to preserve concurrent adjustments
  * fix: use $dbh-&gt;do for SET TRANSACTION to preserve the next-TX isolation level
  * fix: skip zmDbDo success Debug when inside a caller-managed transaction
  * Prevent the "#clearLogsBtn" status from appearing active after clicking the "#clearLogsConfirmBtn" button. The issue was related to an unnecessary call to manageClearButtonAvailability() (log.js)
  * Potential fix for pull request finding
  * Open and close the session only once per page refresh. (log.php)
  * More accurate page navigation and statistics display (log.js)
  * refactor: simplify Event::delete bind-list to a plain SQL list
  * fix: track Event_Summaries enumerate failure as partial resync in zmaudit
  * perf: restrict zmstats ES resync to monitors with pruned buckets
  * fix: avoid DB-backed logging inside zmDbDo when caller manages the transaction
  * fix: reset step/send_twice in MonitorStream CMD_STOP; reset stopped in EventStream.js lifecycle
  * fix: address review feedback - endian decode, send_twice init, setLastViewed, curr_frame_id gating
  * fix: track per-row UPDATE failures in zmaudit ES and Storage resync
  * docs: clarify per-monitor UPDATE lock state in zmstats resync
  * docs: reference the actual Event::Event constructor in lock-order block
  * fix: log Error in Event::delete when deadlock retries are exhausted
  * docs: expand triggers.sql lock-order block with full writer list
  * docs: document atomicity tradeoff in zmstats/zmaudit ES resync
  * fix: don't log Error on deadlock inside a caller-managed transaction
  * refactor: route VideoStore destructor through finalize() refs #4757
  * fix: VideoStore filename use-after-free + null-oc destructor guard refs #4757
  * fix: drop DefaultVideo extension check from \$has_hls refs #4757
  * Avoid endless AJAX table update requests if the query returned 0 rows on the Log page. (log.js)
  * Renamed session 'ZM_LOG_FILTER_LEVEL' to 'zmLogFilterLevel' (log.php)
  * Save the selected filter level in the session (log.php)
  * Managing the availability of the clear logs button (log.js)
  * revert: stop forcing DefaultVideo='index.m3u8' for HLS events refs #4757
  * fix: drain VideoStore reorder_queues inside finalize() refs #4757
  * fix: don't force HLS when user explicitly picked MP4 codec refs #4757
  * fix: disable video.js liveui so HLS scrubbing works on in-progress events refs #4757
  * fix: report served mp4 filename in view_video.php Content-Disposition refs #4757
  * fix: stop view_hls.php emitting /zm/index.php?index.php?view=… refs #4757
  * fix: pick HLS player when index.m3u8 exists, not from DefaultVideo refs #4757
  * fix: keep DefaultVideo='index.m3u8' for events with an HLS manifest refs #4757
  * perf: scope Event neighbor queries to Id only
  * fix: stop warning on URL/session user mismatch in getAuthUser
  * fix: correct HLS fragment byte-range and duration tracking refs #4757
  * fix: use getSkinFile() for _monitor_filters.php include path in console.php
  * typo
  * fix: guard ZM_WEB_REFRESH_LOGS against missing Config row
  * Since kFreeBSD was amd64 and i386 archs only, remove unnecessary checks
  * Fix FreeBSD arm builds
  * Fix: ".chosen-drop" should always be in the foreground (sidebar.css)
  * Fix: Fixed overlapping ".eventStats" and dropdown tags (event.css)
  * fix: use getFilterSelection() and validCardinal() per reviewer feedback
  * Use ConfirmDeleteGroups instead of ConfirmDelete
  * Listen for the "click" event for #delConfirmBtn only once. (skin.js)
  * Potential fix for pull request finding
  * fix: use filter_var FILTER_VALIDATE_INT for stricter ID validation in queryRequest
  * fix: GroupId filter persists after browser refresh on Console view
  * Initial plan
  * fix: avoid HierarchyRequestError in submitThisForm on console view
  * Update ru_ru.php
  * Correction and addition of the Russian translation (ru_ru.php)
  * The column order in the component index has been changed, and Logs_Component_idx has been removed, as it's now redundant.
  * When the page is hidden, execute hideLoading() for the bootstrap table, then execute an empty return instead of executing the AJAX request.
  * Set $maxTime to the current time only if $endSecs is missing in the incomplete event or if $maxTime is empty after looping through all events. (download_functions.php)
  * Return false instead of return "" (download_functions.php)
  * Potential fix for pull request finding
  * Server -&gt; ServerId mapping for sorting in a SQL table (log.php)
  * Added composite secondary index (zm_create.sql.in)
  * Potential fix for pull request finding
  * Added a missing space.
  * Don't execute AJAX requests from bootstrap-table if the page is hidden.
  * For now, we'll only search for "mp4" files (download_functions.php)
  * The "findVideoEventFile()" function takes a file extension as an argument (functions.php)
  * Gjntdownload_functions.php
  * Fix: Missing space (log.js)
  * Update log.php
  * Potential fix for pull request finding
  * Fix: Search (log.php)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed. (zm_create.sql.in)
  * Add Component, TimeKey, and Level to the primary index to increase query processing speed.  zm_update-1.39.10.sql
  * Feat: Optimizing slow SQL queries for large tables (log.php)
  * Fix: space (log.js)
  * Don't send AJAX table update requests if the page is hidden (log.js)
  * The template has been changed to cover files with any extension, since it could be mp4, mkv, or webm (functions.php)
  * Additional file existence check (functions.php)
  * Always treat $Event-&gt;DefaultVideo() as a string (functions.php)
  * Added checks (download_functions.php)
  * Potential fix for pull request finding
  * Added findVideoEventFile ($Event) function (functions.php)
  * Code optimization (download_functions.php)
  * Fix: Correct end timestamp of events when exporting MP4 for multiple events (download_functions.php)
  * docs: identify the 1213 magic number as MariaDB ER_LOCK_DEADLOCK
  * fix: check SELECT errors in zmstats bucket-prune loop
  * fix: don't zero Event_Summaries counters on aggregate SELECT failure in zmaudit
  * docs: correct Event::delete lock-order comment to match triggers.sql
  * docs: document canonical Events lock acquisition order in triggers.sql
  * perf: snapshot bucket aggregates instead of joining in Event_Summaries resync
  * fix: rollback and retry Event::delete under deadlock at READ COMMITTED
  * feat: auto-retry zmDbDo on InnoDB deadlock errno 1213
  * Replacing $j('#eventTable') with tableControlCaps (controlcaps.js)
  * Replaced random Russian text with English Display a message when a report deletion error occurs instead of updating a non-existent '#reportsTable' (report.js)
  * Replaced casual Russian text with English (skin.js)
  * Update groups.js
  * Get the "form" for an element (groups.js)
  * Use $report-&gt;canEdit() instead of canEdit('Events') (reports.php)
  * Removed warning in the browser console if the manageDelConfirmModalBtns() function is not found (skin.js)
  * Lost "?" (ru_ru.php)
  * docs: document CMD_PLAY vs CMD_VARPLAY and CMD_STOP in MsgCommand enum
  * fix: improve stopped state handling in EventStream run loop
  * fix: add stopped state for CMD_STOP, fixing paused=true response bug
  * Initial plan
  * Fix: ESLint
  * - Moved the getDelConfirmModal() function from options.js to skin.js - Removed the getDelConfirmModal() function (and its call) from report.js, options.js, reports.js, devices.js, +++controlcaps.js(?view=options&amp;tab=control), and snapshots.js. This is because it's now a single function in skin.js, which is called when the "Delete" button is pressed, rather than during page initialization. - Slightly modified the local functions of manageDelConfirmModalBtns(). Removed the listener, so the code is executed immediately. - You can now call local functions from the global getDelConfirmModal() function (instead of just executing submitThisForm() ). Applies to report.js, reports.js, devices.js, controlcaps.js, snapshots.js - Changed the style of the "Delete" button on the Groups page - Added deletion confirmation to the Storage, Roles, and Groups pages - On the Event page, deletion permissions were broken. Deletes were allowed for those who did NOT have edit permissions, but deletions were blocked for those who did. ! - On the Report page, deletion didn't work and still doesn't work. This needs to be addressed, or maybe it's possible to delete reports only on the Reports page. (FIXED...) - On the Devices page, the "canEdit.Device" permissions check was being performed, but it should be performed like this: "canEdit.Devices" - The $action variable was not defined in \ajax\devices.php - Added translations. - Added a style for the disabled "Delete" button - Minor fixes
  * - Added the DeleteServer() function - Pass the "formName" argument when calling getDelConfirmModal() - Added a translation
  * Changed the "Delete" button to confirm deletion of selected servers (_options_servers.php)</changelog>
  <changelog author="Joel Baltazor &lt;obs@mtlfab.com&gt;" date="1781265600">- Update to version 1.39.11+git175.c103c403:
  * fix: delete FifoSources before RemoveSession on reconnect failure
  * fix: bound ONVIF SOAP timeouts below zmdc 30s kill window
  * fix: correct stale SharedData and TriggerData offsets in PHP shm map
  * fix: probe mp4 duration for events with no capture jpgs in zmrecover
  * chore: remove dead statusCmd code and debug logging from watch.js
  * Attempt to fix case where a console bootstrap table query gets cancelled and so you get no results
  * feat: add LTS CMIP3CD42WI-28AISP white-light control row refs #4895
  * fix: re-auth retry on supplementLight GET for long-lived control daemons
  * feat: add white-light (CanLight) control to HikVision/LTS module refs #4895
  * fix: align positional Controls seed rows with CanLight/CanIndicatorLight columns
  * When getting the value for "form.elements['newMonitor[RTSPStreamName]']" and "form.elements['newMonitor[Recording]']", check for the presence of the elements themselves. (monitor.js.php)
  * Fix: The absence of "#zones-tab" should not result in errors on the Monitor page. (monitor.js)
  * Fix ESLint (skin.js)
  * Added $data['getLogStatusHTML'] = logState() (status.php)
  * Feat: When updating the status panel, also update the status logs (skin.js)
  * Optimizing the waitUntil() function (skin.js)
  * Insert the file name as "text" and not "html" (export.js)
  * Apply suggestions from code review
  * Fixed a regression in retrieving tracks from a stream. (skin.js)
  * When looping through players, check if it's enabled for the monitor. (MonitorStream.js)
  * refactor: remove dead FfmpegCamera::imagePixFormat field
  * fix: include &lt;libavutil/pixdesc.h&gt; in zm_pixformat.h (PR #4788)
  * feat: refresh auth hash on tab resume, redirect to login on dead session refs #4748
  * fix: nullptr-safe pix fmt name in Colourise/Deinterlace_4Field error paths (PR #4788)
  * Delete jquery.panzoom.min.js as unused and without bug fixes
  * Update version jquery.panzoom - Release 4.6.2 (2026-04-02)
  * Update Panzoom 4.6.2 (jquery.panzoom.js)
  * Recovered the spaces lost by Copilot (MonitorStream.js)
  * Potential fix for pull request finding
  * Returned container.appendChild(stream) for createGo2rtcStream() (skin.js)
  * Write "is not" instead of "has not" (view_hls.php)
  * Fix: ESLint (export.js)
  * Don't perform a new AJAX request to check for file existence if the previous one hasn't yet completed.  (export.js)
  * We'll limit ourselves to transferring no more than 100 links and additional file name validation. (event.php)
  * Added a missing space. (MonitorStream.js)
  * Fix: Iterating over players for Player=Auto mode (MonitorStream.js)
  * Potential fix for pull request finding
  * fix: pass delta8_* fn ptrs directly; zm_get_pix_fmt_name in Delta panic (PR #4788)
  * fix: Deinterlace_Discard OOB write on odd heights (PR #4788)
  * Prevent pointless setInterval(this.statusCmdQuery) calls for "frozen" objects. (MonitorStream.js)
  * Interrupt getTracksFromStream() if the stream has been stopped. (skin.js)
  * Restored the missing &lt;canvas&gt; for audioVisualization (Monitor.php)
  * Fix: ESLint (MonitorStream.js)
  * Added error handling. (video-rtc.js)
  * Added error handling. (video-stream.js)
  * Correctly iterates through players when the Player = "Auto" mode is selected. (MonitorStream.js)
  * Deleted the unnecessary line (Event.php)
  * Check the response of file_get_contents() for "false" (view_hls.php)
  * Remove extra space (skin.js)
  * Do not execute checkM3u8File() for live viewing. (skin.js)
  * Allow overflow for "#contentForm" (monitor.css)
  * fix: preserve port and decode url-encoded passwords in parse_ControlAddress
  * Changed the cursor style for &lt;textarea&gt; (skin.css)
  * We will prohibit the use of the ../ combination in paths. (event.php)
  * Apply suggestions from code review
  * fix: more actionable error messages in GetImage/getSnapshot/WriteBuffer (PR #4788)
  * docs: correct epoch-to-UTC time in test comment refs #4870
  * fix: Image(AVFrame*) ctor delegates to default ctor before AssignDirect (PR #4788)
  * chore: bump redhat spec version to 1.39.11
  * chore: bump version to 1.39.11
  * fix: Image::Assign(Image&amp;) handle smaller-source linesize; explicit pixdesc.h (PR #4788)
  * feat: add Indicator LED control capability with session keepalive refs #4875
  * feat: add status-aware Light control capability and control-command response path refs #4869
  * feat: add HiSilicon Hi3510 CGI PTZ control module
  * feat: add Dahua/Amcrest RPC PTZ control module with per-model Controls refs #120
  * feat: re-assert zm.pid in zmdc main loop so systemd keeps tracking refs #4874
  * Fix: Correct state of the "Delete" button if we have only one file in the directory (files.js)
  * fix: Image::Assign(uint8_t*) handle packed source -&gt; aligned dest (PR #4788)
  * fix: apply filter result limit when an empty Tags term is present
  * fix: stop pinning libcurl4-gnutls-dev, fixing curl -dev conflict
  * fix: enforce per-event ACL on direct media endpoints (GHSA-vj5r-pc2v-gfwv)
  * fix: store event StartDateTime with second precision to match disk path refs #4870
  * fix: handle "no frames yet" sentinel before bounds check (PR #4788)
  * fix: use canonical imagePixFormat in Image::Assign(AVFrame*) (PR #4788)
  * fix: free previously-owned buffer in AssignDirect(AVFrame); nullptr-safe logs (PR #4788)
  * Removed "action" parameter from streamCmdStop() as deprecated (watch.js)
  * Apply suggestions from code review
  * When executing the streamCmdStop() command, always stop the stream regardless of the passed "action" parameter.  (watch.js)
  * fix: keep linked event open while source monitor is in ALERT state
  * fix: retain keyframe images so snapshot.jpg is written for pre-event frames refs #4843
  * fix(packetqueue): destroy packets after releasing mutex; drop dead code
  * fix: guard SHM pixformat publish on assign failure (PR #4788)
  * - Optimized setButtonStates() - Added a hidden &lt;INPUT&gt; element to correctly submit the form via JS - Added Russian and English translations for ConfirmDeleteFiles
  * - DIR_EXPORTS_DOWNLOAD is not passed to JS, but is used only in PHP. - When making an AJAX request, we pass an array of file paths relative to DIR_EXPORTS_DOWNLOAD , not absolute ones. - Check $fileName for a non-empty string. - Clear fileExistencePollingInterval if it exists before calling again. - More correctly retrieve parameters from the "el.href" string using "new URL(el.href)". - Disabled the cursor for "a.disabled".
  * Update skin.js
  * Added deleteFiles() (files.js)
  * Confirming file deletion on the Files page (files.php)
  * fix: switch remaining av_get_pix_fmt_name calls in zm_ffmpeg_camera.cpp to zm_ wrapper
  * - Correct HLS playback on the Watch page - When executing Event-&gt;Length() , get the duration of the recorded event file if the duration in the database table is 0 - If native HLS playback fails in Safari, we first try playing MP4, and only if MP4 playback fails do we switch to MJPEG playback
  * fix: nullptr-safe pixfmt name; route GetImage/getSnapshot through ReadShmFrame (PR #4788)
  * fix: SHM padding covers both alignment adjustments (PR #4788)
  * Fix error (export.js)
  * Replaced "let" with "const" (export.js)
  * Added AJAX action='file_existence_check' Added the DIR_EXPORTS_DOWNLOAD constant from PHP to JS Added a style for "#downloadModal a.disabled" on the Events page
  * Removed unnecessary debug information (export.js)
  * If the download file was deleted after downloading, we make the download link for the file inactive. (export.js)
  * fix: per-row Overlay; align image_pixelformats SHM pointer (PR #4788)
  * perf: emit sargable range queries for Date/StartDate/EndDate filter terms
  * fix: stride-aware Delta and Deinterlace_4Field (PR #4788)
  * fix: PopulateFrame error handling + canonical pix fmt in Scale (PR #4788)
  * fix: keep DeColourise/AssignDirect(AVFrame) state self-consistent (PR #4788)
  * fix: Camera::linesize/imagesize back to tightly-packed (PR #4788)
  * fix: ceiling chroma dims in Rotate/Flip; clearer Assign error (PR #4788)
  * fix: dest linesize in HighlightEdges, ceiling chroma dims in MaskPrivacy (PR #4788)
  * Switch to MP4 playback instead of HLS only if a fatal HLS error occurs.
  * Apply suggestions from code review
  * fix: report AVPixelFormat in Panic messages for actionable diagnosis (PR #4788)
  * fix: linesize/planar correctness for Overlay, Rotate, Flip, AssignDirect(AVFrame) (PR #4788)
  * If a defective MP4 video stops or freezes (checking the current time every 1 second), execute fallbackToMjpeg(). (skin.js)
  * Added the data-event-start attribute to the img on the Watch page (watch.php).
  * Before getting infoStatusBar, check for the presence of a statusBar (skin.js)
  * Add a 250ms delay to all thumbnail_onmouseover() code. (skin.js)
  * - Do not check the M3u8 file if currentView === 'frames' - When executing Length() and Duration() , do not write the result to the database. - When assigning a value to the "data-video-duration-secs" attribute, first check the Length in $row['Length'] and, if it is 0, only then check the file's Duration. - If the M3u8 file is missing or invalid, do not cache the server response.
  * Apply suggestions from code review
  * fix: address remaining width-vs-linesize and planar chroma issues (PR #4788)
  * fix: fully invalidate Image on AssignDirect(AVFrame) format failure (PR #4788)
  * fix: use linesize for row stride in pixel ops (PR #4788)
  * Update skin.js
  * fix: cross-process AVPixelFormat sync for alarm_image (PR #4788)
  * Added comment (Event.php)
  * Duration is only saved to the database if it's greater than zero. (Event.php)
  * Added a private Duration() method as a synonym for the Length() method. (Event.php)
  * Use $event-&gt;Duration() instead of "($event-&gt;EndDateTimeSecs() - $event-&gt;StartDateTimeSecs())" (events.php)
  * fix: address PR #4788 review comments on planar sizing and SHM bounds
  * fix: address PR #4788 review comments on SHM publish ordering and overlay bounds
  * fix: only emit HLS/duration attrs for events with video (events.php)
  * fix: address PR #4788 review comments on AVPixelFormat migration
  * Added the m3u8Exists constant, which is used to decide how to play the video. (skin.js)
  * If the m3u8 manifest doesn't contain fragments, then instead of outputting to the page body, save the message in the logs as Warning, since we're passing status code 204.  (view_hls.php)
  * Update skin.js
  * Picky ESLint (skin.js)
  * Before raising statusBar.innerHTML, we check for the presence of a statusBar. (skin.js)
  * Before loading the "index.m3u8" manifest in hls.js, always check the server response status and load the manifest only if the response status is 200. (skin.js)
  * The "data-video-hls-src" attribute should always reference the "index.m3u8" manifest file, even if the physical file is missing. (events.php)
  * If the "index.m3u8" manifest file is missing or if the manifest is invalid, the return status code is 204 instead of 404. (view_hls.php)
  * Removed extra semicolons (skin.js)
  * Fixed cookie reading and video launch for native HLS. (skin.js)
  * Fixed the value assignment for "$args['view']" (Event.php)
  * Fix: ESLint (skin.js)
  * Added support for HLS playback when hovering over the thumbs.(skin.js)
  * Added the "data-video-duration-secs" attribute to VIDEO (events.php)
  * Option to generate 'view=view_hls' (Event.php)
  * Add a link to playback the recorded event using HLS to the IMG tag if there is an index.m3u8 file. (events.php)
  * feat: SHM cross-process format consistency via per-slot AVPixelFormat
  * fix: planar YUV correctness + alignment in Image methods
  * Reapply "fix: replace ZM_COLOUR system with AVPixelFormat for format dispatch"</changelog>
</package>
</otherdata>