VYPR
High severityNVD Advisory· Published Feb 22, 2022· Updated Aug 3, 2024

CVE-2022-23043

CVE-2022-23043

Description

Zenario CMS 9.2 allows an authenticated admin user to bypass the file upload restriction by creating a new 'File/MIME Types' using the '.phar' extension. Then an attacker can upload a malicious file, intercept the request and change the extension to '.phar' in order to run commands on the server.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Zenario CMS 9.2 allows authenticated admin to bypass file upload restrictions by defining a .phar MIME type, then upload and execute a malicious .phar file for remote code execution.

Vulnerability

In Zenario CMS 9.2, an authenticated administrator can bypass the file upload restrictions via the 'File/MIME Types' administrative feature. By creating a new MIME type entry that uses the .phar extension, the admin is able to subsequently upload a file with that extension. The uploaded .phar file can then be executed on the server, leading to remote code execution [1]. The vulnerability affects version 9.2 specifically [1].

Exploitation

An attacker must first authenticate as an administrator to access the 'File/MIME Types' configuration. After creating a new MIME type that maps to the .phar extension, the attacker can upload a malicious .phar file. The upload mechanism does not perform adequate server-side validation of the file extension, allowing the .phar file to be stored. The attacker can then trigger execution of the uploaded file, likely by accessing it through a web-accessible path [1]. The necessary steps require network access to the Zenario admin panel and valid admin credentials [1].

Impact

Successful exploitation enables an attacker to execute arbitrary PHP code on the server through the .phar file, effectively achieving remote code execution (RCE) with the privileges of the web server process. This can lead to full compromise of the CMS, data disclosure, and potential lateral movement within the hosting environment [1].

Mitigation

The vendor released a fix in version 9.2.55826, which prevents administrators from uploading .phar files to the server [2][4]. Users should upgrade to Zenario 9.2.55826 or later. No workaround is provided for the vulnerable version. The CVE is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of the publication date [1].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
tribalsystems/zenarioPackagist
< 9.2.558269.2.55826

Affected products

2

Patches

1
f0682d22688d

Copying the latest maintenance patch for 9.2 to the GitHub repo:

https://github.com/TribalSystems/ZenarioChris TurnbullFeb 8, 2022via ghsa
75 files changed · +627 1698
  • .htaccess+1 1 modified
    @@ -7,7 +7,7 @@ Options -Indexes
     <ifModule mod_headers.c>
     	Header setifempty Content-Security-Policy "default-src *; img-src * data:; script-src * 'unsafe-eval' 'unsafe-inline'; style-src * 'unsafe-inline'"
     	Header setifempty Feature-Policy "sync-xhr *; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none';"
    -	Header setifempty Permissions-Policy "sync-xhr=(self), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), fullscreen=(self), payment=()"
    +	Header setifempty Permissions-Policy "sync-xhr=(self), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=()"
     	Header setifempty Referrer-Policy strict-origin-when-cross-origin
     	Header setifempty X-Content-Type-Options nosniff
     	Header setifempty X-Frame-Options SAMEORIGIN
    
  • package.json+1 1 modified
    @@ -28,5 +28,5 @@
     		"wowjs": "*",
     		"zxcvbn": "^4.4.2"
     	},
    -	"version": "9.2.55622"
    +	"version": "9.2.55826"
     }
    \ No newline at end of file
    
  • zenario/admin/db_updates/latest_revision_no.inc.php+2 2 modified
    @@ -27,7 +27,7 @@
      */
     if (!defined('NOT_ACCESSED_DIRECTLY')) exit('This file may not be directly accessed');
     
    -define('LATEST_REVISION_NO', 55051);	//N.b. 9.2 starts at revision #55140
    +define('LATEST_REVISION_NO', 55052);	//N.b. 9.2 starts at revision #55140
     define('LATEST_BIG_CHANGE_REVISION_NO', 55050);
     define('INSTALLER_REVISION_NO', 53100);
     define('INSTALLER_DEFAULT_THEME', 'zebra_designs');
    @@ -39,6 +39,6 @@
     define('ZENARIO_MINOR_VERSION', '2');
     define('ZENARIO_CHANGELOG_URL', 'https://zenar.io/zenario-92');
     define('ZENARIO_IS_BUILD', true);
    -define('ZENARIO_REVISION', '55622');
    +define('ZENARIO_REVISION', '55826');
     
     define('TINYMCE_DIR', 'zenario/libs/manually_maintained/lgpl/tinymce_4_7_3/');
    
  • zenario/admin/db_updates/step_2_update_the_database_schema/content_tables.inc.php+8 1 modified
    @@ -1609,4 +1609,11 @@
     	ALTER TABLE `[[DB_PREFIX]]spare_aliases` MODIFY COLUMN `alias` varchar(250) CHARACTER SET utf8mb4 NOT NULL
     _sql
     
    -);
    +);	ze\dbAdm::revision( 55052
    +, <<<_sql
    +	ALTER TABLE `[[DB_PREFIX]]writer_profiles`
    +	DROP KEY `admin_id`,
    +	ADD KEY (`admin_id`)
    +_sql
    +
    +);
    \ No newline at end of file
    
  • zenario/autoload/db.php+32 10 modified
    @@ -150,7 +150,9 @@ public function __construct($f) {
     
     
     //Wrapper class for a SQL query
    -class queryCursor implements \Iterator {
    +	//Note: I'm declaring this as an abstract class. I don't actually an an stract class, but this is going
    +	//to be used as a workaround to fix a particually stupid bug in PHP further below!
    +abstract class abstractQueryCursor implements \Iterator {
     	public $q;
     	protected $d = [];
     	protected $dc = 0;
    @@ -306,24 +308,44 @@ public function close() {
     	protected $i = 0;
     	protected $nr;
     	
    -	public function rewind() {
    +	public function rewind(): void {
     	}
     	
    -	public function next() {
    +	public function next(): void {
     	}
     	
    -	public function valid() {
    +	public function valid(): bool {
     		++$this->i;
     		return false !== ($this->nr = $this->fAssoc());
     	}
     	
    -	public function key() {
    -		return $this->i;
    -	}
    +}
    +
    +//OK so here's the particually stupid bug in PHP.
    +//Due to a breaking change, code written for PHP 7 and earlier isn't compatible
    +//with code written for PHP 8.1 and later.
    +//I'm forced to have a class declaration inside an if-statement, and have both versions
    +//of the code, to fix it!
    +if (version_compare(PHP_VERSION, '8.0.0') >= 0) {
    +    class queryCursor extends abstractQueryCursor {
    +		public function key(): mixed {
    +			return $this->i;
    +		}
     	
    -	public function current() {
    -		return $this->nr;
    -	}
    +		public function current(): mixed {
    +			return $this->nr;
    +		}
    +    }
    +} else {
    +    class queryCursor extends abstractQueryCursor {
    +		public function key() {
    +			return $this->i;
    +		}
    +	
    +		public function current() {
    +			return $this->nr;
    +		}
    +    }
     }
     
     
    
  • zenario/autoload/escape.php+2 2 modified
    @@ -85,13 +85,13 @@ public static function hyp($text) {
     	const jsFromTwig = true;
     	//Formerly "jsEscape()"
     	public static function js($text) {
    -		return strtr(addcslashes($text, "\\\n\r\"'"), ['&' => '\\x26', '<' => '\\x3c', '>' => '\\x3e', '{' => '\\x7b', '}' => '\\x7d']);
    +		return strtr(addcslashes((string) $text, "\\\n\r\"'"), ['&' => '\\x26', '<' => '\\x3c', '>' => '\\x3e', '{' => '\\x7b', '}' => '\\x7d']);
     	}
     
     	const jsOnClickFromTwig = true;
     	//Formerly "jsOnClickEscape()", "jsOnclickEscape()"
     	public static function jsOnClick($text) {
    -		return htmlspecialchars(addcslashes($text, "\\\n\r\"'"));
    +		return htmlspecialchars(addcslashes((string) $text, "\\\n\r\"'"));
     	}
     
     	public static function utf($string) {
    
  • zenario/autoload/fileAdm.php+1 0 modified
    @@ -441,6 +441,7 @@ public static function getImageUsage($imageId) {
                   AND in_use = 1
     			  AND archived = 0
     			  AND foreign_key_to IN ('content', 'library_plugin', 'menu_node', 'email_template', 'newsletter', 'newsletter_template') 
    +			  AND foreign_key_id != 0
     			GROUP BY foreign_key_to, is_nest, is_slideshow
     		") as $ucat) {
     			$keyTo = $ucat['foreign_key_to'];
    
  • zenario/autoload/file.php+1 0 modified
    @@ -606,6 +606,7 @@ public static function isExecutable($extension) {
     			case 'exe':
     			case 'js':
     			case 'jsp':
    +			case 'phar':
     			case 'php':
     			case 'php3':
     			case 'ph3':
    
  • zenario/autoload/fun/showStartSitePageIfNeeded.php+20 2 modified
    @@ -29,6 +29,10 @@
     
     \ze\cookie::startSession();
     
    +
    +//If the site is not yet correctly set up, display the logo and a message
    +//if someone tries to access it.
    +
     $logoURL = $logoWidth = $logoHeight = false;
     if (\ze::$dbL
      && \ze::setting('brand_logo') == 'custom'
    @@ -41,6 +45,10 @@
     }
     
     
    +$errorTitle = \ze::setting('site_disabled_title');
    +
    +
    +//Display a different message and/or destination URL depending on the situation.
     if ($reportDBOutOfDate && \ze\priv::check()) {
     	$errorMessage = '<p>This site is currently unavailable because a major database update needs to be applied.</p><p>Please go to <a href="[[admin_link]]">/admin</a> to apply the update.</p>';
     	$adminLink = \ze\link::absolute(). 'admin.php';
    @@ -61,13 +69,23 @@
     	$adminLink = \ze\link::absolute(). 'admin.php?og=zenario__organizer/panels/start_page';
     }
     
    +
    +//If the error title and error message are ever missing for whatever reason,
    +//instead of displaying a blank message, use their default values.
    +if (!$errorTitle || empty(trim($errorTitle))) {
    +	$errorTitle = 'Welcome';
    +}
    +if (!$errorMessage || empty(trim($errorMessage))) {
    +	$errorMessage = '<p>A site is being built at this location.</p><p><span class="x-small">If you are a site administrator please <a href="[[admin_link]]">click here</a> to manage your site.</span></p>';
    +}
    +
     $errorMessage = \ze\admin::phrase($errorMessage, ['admin_link' => htmlspecialchars($adminLink)]);
     
     
     echo '
     <html>
     	<head>
    -		<title>', \ze::setting('site_disabled_title'), '</title>
    +		<title>', htmlspecialchars($errorTitle), '</title>
     		<style type="text/css">
     			div, p {
     				color: #9a9a9a; font-family: Verdana,Tahoma,Arial,Helvetica,sans-serif;
    @@ -116,9 +134,9 @@
     </html>';
     
     
    +//If a visitor has discovered a site that's missing database updates, warn the site admin.
     if ($reportDBOutOfDate && !\ze\priv::check()) {
     	\ze\db::reportError('Database update needed at',
     'This site is currently unavailable because a major database update needs to be applied.
     Please go to '. \ze\link::absolute(). 'admin to apply the update.');
     }
    -
    
  • zenario/autoload/fun/startIncludeAdminControls.php+13 10 modified
    @@ -65,7 +65,7 @@
     				href="', $organizerLink, $nestPath, '~.plugin_settings~tbreadcrumbs~k', htmlspecialchars(json_encode(['instanceId' => $this->instanceId])), '"
     				class="zenario_slotButton zenario_editNestedPlugin"
     				id="', $this->containerId, '-egg"
    -				onclick="return zenarioA.pluginSlotEditSettings(this, \'', $this->slotName, '\');"
    +				onclick="if (zenarioA.checkForEdits()) zenarioA.pluginSlotEditSettings(this, \'', $this->slotName, '\'); return false;"
     				title="'. htmlspecialchars($tooltip). '"
     				data-tooltip-options=\'{"tooltipClass": "zenario_admin_tooltip"}\'
     			><span></span></a>';
    @@ -92,7 +92,7 @@ class="zenario_slotButton zenario_editNestedPlugin"
     				href="', $organizerLink, $nestPath, $this->eggId, '~.plugin_settings~k', htmlspecialchars(json_encode(['eggId' => $this->eggId])), '"
     				class="zenario_slotButton zenario_editNestedPlugin"
     				id="', $this->containerId, '-egg"
    -				onclick="return zenarioA.pluginSlotEditSettings(this, \'', $this->slotName, '\', false, {eggId: ', (int) $this->eggId, '});"
    +				onclick="if (zenarioA.checkForEdits()) zenarioA.pluginSlotEditSettings(this, \'', $this->slotName, '\', false, {eggId: ', (int) $this->eggId, '}); return false;"
     				title="'. htmlspecialchars($tooltip). '"
     				data-tooltip-options=\'{"tooltipClass": "zenario_admin_tooltip zenario_plugin_info_tooltip"}\'
     			><span></span></a>
    @@ -101,14 +101,17 @@ class="zenario_slotButton zenario_editNestedPlugin"
     				class="zenario_slotButton zenario_nestedPluginOptions"
     				id="', $this->containerId, '-egg-options"
     				onclick="', "
    -					return zenarioAT.organizerQuick(
    -						'", $nestPath, $this->eggId, "',
    -						'zenario__modules/panels/nested_plugins',
    -						false,
    -						'", ze\escape::js($this->slotName), "',
    -						false,
    -						". ze\ring::engToBoolean($this->isVersionControlled). ",
    -						this);", '"
    +					if (zenarioA.checkForEdits())
    +						zenarioAT.organizerQuick(
    +							'", $nestPath, $this->eggId, "',
    +							'zenario__modules/panels/nested_plugins',
    +							false,
    +							'", ze\escape::js($this->slotName), "',
    +							false,
    +							". ze\ring::engToBoolean($this->isVersionControlled). ",
    +							this
    +						);
    +					return false;", '"
     			><span></span></a>';
     	}
     	
    
  • zenario/autoload/welcome.php+56 69 modified
    @@ -55,83 +55,66 @@ public static function directoryIsWritable($dir) {
     
     
     	public static function passwordMessageSnippet($password, $isInstaller = false) {
    -		$passwordValidation = \ze\user::checkPasswordStrength($password);
    -
     		$passwordMessageSnippet = '';
    -		if (!$passwordValidation['password_matches_requirements']) {
    -			
    -			if ($passwordValidation['password_length'] > 0) {
    -				$passPhrase = 'Password does not match the requirements';
    -				$class = "title_red";
    -			} else {
    -				$passPhrase = 'Please enter a password';
    -				$class = "title_orange";
    -			}
    -			//Set the post-html field to display "FAIL" highlighted in red.
    -			$passwordMessageSnippet = 
    -				'<div>
    -					<span id="snippet_password_message" class="' . $class . '">' . \ze\admin::phrase($passPhrase) . '</span>
    -				</div>';
    -		} else {
    -			$minScore = (int) (\ze::setting('min_extranet_user_password_score') ?: 2);
     
    -			$zxcvbn = new \ZxcvbnPhp\Zxcvbn();
    -			$result = $zxcvbn->passwordStrength($password);
    +		$minScore = (int) (\ze::setting('min_extranet_user_password_score') ?: 2);
     
    -			if ($result && isset($result['score'])) {
    -				switch ($result['score']) {
    -					case 4: //is very unguessable (guesses >= 10^10) and provides strong protection from offline slow-hash scenario
    -						if ($minScore < 4) {
    -							$phrase = 'Password is very strong and exceeds requirements (score 4, max)';
    -						} elseif ($minScore == 4) {
    -							$phrase = 'Password matches the requirements (score 4)';
    -						}
    +		$zxcvbn = new \ZxcvbnPhp\Zxcvbn();
    +		$result = $zxcvbn->passwordStrength($password);
    +
    +		if ($result && isset($result['score'])) {
    +			switch ($result['score']) {
    +				case 4: //is very unguessable (guesses >= 10^10) and provides strong protection from offline slow-hash scenario
    +					if ($minScore < 4) {
    +						$phrase = 'Password is very strong and exceeds requirements (score 4, max)';
    +					} elseif ($minScore == 4) {
    +						$phrase = 'Password matches the requirements (score 4)';
    +					}
     
    +					$passwordMessageSnippet = 
    +						'<div>
    +							<span id="snippet_password_message" class="title_green">' . \ze\admin::phrase($phrase) . '</span>
    +						</div>';
    +					break;
    +				case 3: //is safely unguessable (guesses < 10^10), offers moderate protection from offline slow-hash scenario
    +					if ($minScore == 4) {
    +						$passwordMessageSnippet = 
    +						'<div>
    +							<span id="snippet_password_message" class="title_red">' . \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]) . '</span>
    +						</div>';
    +					} elseif ($minScore < 4) {
     						$passwordMessageSnippet = 
     							'<div>
    -								<span id="snippet_password_message" class="title_green">' . \ze\admin::phrase($phrase) . '</span>
    +								<span id="snippet_password_message" class="title_green">' . \ze\admin::phrase('Password matches the requirements (score 3)') . '</span>
     							</div>';
    -						break;
    -					case 3: //is safely unguessable (guesses < 10^10), offers moderate protection from offline slow-hash scenario
    -						if ($minScore == 4) {
    -							$passwordMessageSnippet = 
    +					}
    +					break;
    +				case 2: //is somewhat guessable (guesses < 10^8), provides some protection from unthrottled online attacks
    +					if ($minScore == 2) {
    +						if ($isInstaller) {
    +							$phrase = \ze\admin::phrase('Password is easy to guess. Make your password stronger if this will be a production site.');
    +						} else {
    +							$phrase = \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]);
    +						}
    +						$passwordMessageSnippet = 
     							'<div>
    -								<span id="snippet_password_message" class="title_red">' . \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]) . '</span>
    +								<span id="snippet_password_message" class="title_orange">' . $phrase . '</span>
     							</div>';
    -						} elseif ($minScore < 4) {
    -							$passwordMessageSnippet = 
    -								'<div>
    -									<span id="snippet_password_message" class="title_green">' . \ze\admin::phrase('Password matches the requirements (score 3)') . '</span>
    -								</div>';
    -						}
    -						break;
    -					case 2: //is somewhat guessable (guesses < 10^8), provides some protection from unthrottled online attacks
    -						if ($minScore == 2) {
    -							if ($isInstaller) {
    -								$phrase = \ze\admin::phrase('Password is easy to guess. Make your password stronger if this will be a production site.');
    -							} else {
    -								$phrase = \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]);
    -							}
    -							$passwordMessageSnippet = 
    -								'<div>
    -									<span id="snippet_password_message" class="title_orange">' . $phrase . '</span>
    -								</div>';
    -						} elseif ($minScore > 2) {
    -							$passwordMessageSnippet = 
    -								'<div>
    -									<span id="snippet_password_message" class="title_red">' . \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]) . '</span>
    -								</div>';
    -						}
    -						break;
    -					case 1: //is still very guessable (guesses < 10^6)
    -					case 0: //s extremely guessable (within 10^3 guesses)
    -					default:
    +					} elseif ($minScore > 2) {
     						$passwordMessageSnippet = 
     							'<div>
     								<span id="snippet_password_message" class="title_red">' . \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]) . '</span>
     							</div>';
    -						break;
    -				}
    +					}
    +					break;
    +				case 1: //is still very guessable (guesses < 10^6)
    +				case 0: //s extremely guessable (within 10^3 guesses)
    +				default:
    +					$passwordMessageSnippet = 
    +						'<div>
    +							<span id="snippet_password_message" class="title_red">' . \ze\admin::phrase('Password is too easy to guess (score [[score]])', ['score' => (int) $result['score']]) . '</span>
    +						</div>';
    +					break;
     			}
     		}
     		
    @@ -1582,7 +1565,6 @@ public static function installerAJAX(&$source, &$tags, &$fields, &$values, $chan
     				\ze::$dbL = null;
     				
     					$fields['5/password_message']['snippet']['html'] = self::passwordMessageSnippet(($fields['5/password']['current_value'] ?? false), $isInstaller = true);
    -					$fields['5/password_requirements']['snippet']['html'] = \ze\admin::displayPasswordRequirementsNoteAdmin($fields['5/password']['current_value'] ?? false);
     				
     				//Restore the connection
     				\ze::$dbL = $db;
    @@ -2646,7 +2628,6 @@ public static function changePasswordAJAX(&$source, &$tags, &$fields, &$values,
     		}
     	
     		$fields['change_password/password_message']['snippet']['html'] = self::passwordMessageSnippet($values['password']);
    -		$fields['change_password/password_requirements']['snippet']['html'] = \ze\admin::displayPasswordRequirementsNoteAdmin($fields['5/password']['current_value'] ?? false);
     	
     		return false;
     	}
    @@ -2683,7 +2664,6 @@ public static function newAdminAJAX(&$source, &$tags, &$fields, &$values, $chang
     		}
     		
     		$fields['new_admin/password_message']['snippet']['html'] = self::passwordMessageSnippet($fields['new_admin/password']['current_value'] ?? false);
    -		$fields['new_admin/password_requirements']['snippet']['html'] = \ze\admin::displayPasswordRequirementsNoteAdmin($fields['new_admin/password']['current_value'] ?? false);
     		
     		return false;
     	}
    @@ -4122,8 +4102,15 @@ public static function redirectAdmin($getRequest, $forceAliasInAdminMode = false
     		}
     		
     		$domain = ($forceAliasInAdminMode || !\ze\priv::check())? \ze\link::primaryDomain() : \ze\link::adminDomain();
    -	
    -		if (!empty($getRequest['og']) && \ze\priv::check()) {
    +		
    +		//A language needs to be enabled, when an admin logs in, the admin should always be taken to
    +		//the languages panel in Organizer to enable it.
    +		if (!\ze\row::exists('languages', []) && \ze\priv::check()) {
    +			return
    +				'organizer.php'.
    +				'#zenario__languages/panels/languages';
    +
    +		} elseif (!empty($getRequest['og']) && \ze\priv::check()) {
     			return
     				'organizer.php'.
     				(isset($getRequest['fromCID']) && isset($getRequest['fromCType'])? '?fromCID='. $getRequest['fromCID']. '&fromCType='. $getRequest['fromCType'] : '').
    
  • zenario/includes/js_minify.inc.php+30 13 modified
    @@ -25,23 +25,43 @@
      * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      */
    +if (!defined('NOT_ACCESSED_DIRECTLY')) exit('This file may not be directly accessed');
     
     
    -define('YUI_COMPRESSOR_PATH', 'zenario/libs/manually_maintained/bsd/yuicompressor/yuicompressor-2.4.8.jar');
     define('CLOSURE_COMPILER_PATH', 'zenario/libs/not_to_redistribute/closure-compiler/closure-compiler.jar');
    -
    -//Use the closure compiler for .js files if it has been installed
    -//(otherwise we must use YUI Compressor which gives slightly larger filesizes).
    -define('USE_CLOSURE_COMPILER', file_exists(CLOSURE_COMPILER_PATH));
    +define('YUI_COMPRESSOR_PATH', 'zenario/libs/manually_maintained/bsd/yuicompressor/yuicompressor-2.4.8.jar');
     
     define('DEBUG_DONT_MINIFY', false);
     
     
    +if (!is_file(CMS_ROOT. CLOSURE_COMPILER_PATH)
    + || !is_file(CMS_ROOT. YUI_COMPRESSOR_PATH)) {
    +	echo
    +"A tool for minifying JavaScript used by Zenario;
    +this is a wrapper for calling Closure Compiler (https://developers.google.com/closure/compiler/)
    +and YUI Compressor (https://yui.github.io/yuicompressor/) on all relevant files.
    +
    +To save space, the Zenario download does not come with copies of these libraries,
    +but if you download them and put them in the right place, then this tool will use them.
    +
    +To use this tool:
    + - Java must be available on your server.
    + - You must download the closure-compiler.jar file from the site mentioned above.
    + - This needs to be placed in the zenario/libs/not_to_redistribute/closure-compiler/ directory.
    + - You must have a copy of the yuicompressor-2.4.8.jar file from the site mentioned above.
    + - This needs to be placed in the zenario/libs/manually_maintained/bsd/yuicompressor/ directory.
    +
    +";
    +	exit;
    +}
    +
    +
    +
     function displayUsage() {
     	echo
     "A tool for minifying JavaScript used by Zenario;
    -this is a wrapper for calling YUI Compressor (http://developer.yahoo.com/yui/compressor/)
    -or Closure Compiler (https://developers.google.com/closure/compiler/) on all relevant files.
    +this is a wrapper for calling YUI Compressor (https://yui.github.io/yuicompressor/)
    +and Closure Compiler (https://developers.google.com/closure/compiler/) on all relevant files.
     
     Usage:
     	php js_minify
    @@ -55,10 +75,7 @@ function displayUsage() {
     	php js_minify v
     		Use debug/verbose mode when minifying.
     
    -Notes:
    -  * The Zenario download does not come with a copy of Closure Compiler to save space,
    - 	but if you download a copy and put it in the right place then this program will use it.
    -  * If you have svn, this script will only minify files that svn says are new or modified.
    +If you have svn, this script will only minify files that svn says are new or modified.
     
     ";
     	exit;
    @@ -893,7 +910,7 @@ function minify($dir, $file, $level, $ext = '.js', $string = false) {
     	if ($level > 2) {
     		echo ':'. $srcFile. "\n";
     		
    -		if (!$isCSS && USE_CLOSURE_COMPILER) {
    +		if (!$isCSS) {
     			$v = '--warning_level VERBOSE ';
     		} else {
     			$v = '-v ';
    @@ -960,7 +977,7 @@ function minify($dir, $file, $level, $ext = '.js', $string = false) {
     						$tags = Spyc::YAMLLoad($srcFile);
     						file_put_contents($minFile, json_encode($tags, JSON_FORCE_OBJECT));
     					
    -					} elseif (!$isCSS && USE_CLOSURE_COMPILER) {
    +					} elseif (!$isCSS) {
     						if (DEBUG_DONT_MINIFY) {
     							//Use this line ot skip the minification, useful for debugging the compilation macros
     							copy($srcFile, $minFile);
    
  • zenario/js/admin_grid_maker.js+3 3 modified
    @@ -885,7 +885,7 @@ zenarioGM.drawEditor = function(
     	//All a little bit of padding (which will be hidden with an "overflow-x: hidden;") to help prevent various bugs
     	//of things wrapping onto new lines when dragging things around.
     	if (level == 0) {
    -		html += '<div class="zenario_overflow_wrap" style="width: ' + zenarioGM.scaleWidth(zenarioGM.data.maxWidth) + 'px; overflow-x: hidden;">';
    +		html += '<div class="zenario_overflow_wrap">';
     		html += '<ul id="' + elId + 's" class="zenario_grids" style="width: ' + zenarioGM.scaleWidth(wrapWidth + Math.abs(gGutterRight - gGutterRightEdge) + 1) + 'px;';
     	} else {
     		html += '<ul id="' + elId + 's" class="zenario_grids" style="width: ' + zenarioGM.scaleWidth(wrapWidth) + 'px;';
    @@ -900,7 +900,7 @@ zenarioGM.drawEditor = function(
     	
     	//If this is the outer-most tag, add a pink striped background so we can easily see the grid
     	if (level == 0) {
    -		html += 'background: white top left repeat-y url(' + htmlspecialchars(URLBasePath) + 'zenario/admin/grid_maker/grid_bg.php?gColWidth=' + gColWidth + '&gCols=' + gCols + '&gGutter=' + gGutter + '&gGutterLeftEdge=' + gGutterLeftEdge + '&gGutterRightEdge=' + gGutterRightEdge + '); background-size: ' + zenarioGM.scaleWidth(zenarioGM.data.maxWidth) + 'px;';
    +		html += 'background-image: url(' + htmlspecialchars(URLBasePath) + 'zenario/admin/grid_maker/grid_bg.php?gColWidth=' + gColWidth + '&gCols=' + gCols + '&gGutter=' + gGutter + '&gGutterLeftEdge=' + gGutterLeftEdge + '&gGutterRightEdge=' + gGutterRightEdge + ');';
     		
     		//Remember the width and height for typical new elements.
     		//This will be used later when trying to drag them in from the "add" toolbar
    @@ -1119,7 +1119,7 @@ zenarioGM.drawEditor = function(
     			}
     			
     			
    -			var nHTML = htmlspecialchars(zenarioGM.cellLabel(cells[i]))
    +			var nHTML = htmlspecialchars(zenarioGM.cellLabel(cells[i]));
     			
     			if (cells[i].height && cells[i].height != 'small') {
     				nHTML += ' (' + htmlspecialchars(cells[i].height) + ')';
    
  • zenario/js/admin_grid_maker.min.js+50 51 modified
    @@ -19,54 +19,53 @@ a.pos&&(a.savedAtPos=-1));a.draw(b)};a.undoOrRedo=function(c){var b=a.pos-c;0>b|
     a.init=function(c,b,d,e){a.data="object"==typeof c?c:JSON.parse(c);d&&(a.layoutName=d);b&&(a.layoutId=b);a.slotContents=e||{};a.checkData(d);a.checkDataR(a.data.cells);a.rememberNames(a.data.cells);a.editing=!0;a.data.cells.length||(a.editing=!0);I&&!I.zenarioGM&&I.$&&I.$.colorbox?$("#close_button").click(function(){if(a.savedAtPos==a.pos||confirm(z.gridConfirmClose))y._stPo(a),I.zenario&&I.zenario.cID?I.location.reload(!0):I.$.colorbox.close()}):T("close_button").style.display="none";y._sP(a)};a.scaleWidth=
     function(c){return.5*c};a.draw=function(c){c||a.drawOptions();a.editing?a.drawEditor():a.drawPreview()};var oa,pa;a.drawEditor=function(c,b,d,e,h,g,v,p,F,w,H){var qa=H=0;d||$("#settings--tabs").removeClass("zenario_grid_tabs_grid_selected").addClass("zenario_grid_tabs_slots_selected");if(d&&E(d[0])){var A=a.data;for(var U in d)B(d,U)&&(U*=1,H=U+1,A=A.cells[d[U]])}else qa=$("#"+a.gridId).scrollTop(),a.checkData(),A=a.data,H=0,d=[],a.names={},a.randomNameCount=0;E(c)||(c=a.gridId);E(e)||(e=a.data.cols);
     E(h)||(a.data.fluid?(oa=a.data.gutterFlu,w=pa=(100-a.data.gutterLeftEdgeFlu-(a.data.cols-1)*a.data.gutterFlu-a.data.gutterRightEdgeFlu)/a.data.cols,g=Math.round(a.data.gutterFlu*a.data.maxWidth/100),v=Math.round(a.data.gutterLeftEdgeFlu*a.data.maxWidth/100),p=Math.round(a.data.gutterRightEdgeFlu*a.data.maxWidth/100),F=g,h=Math.round(w*a.data.maxWidth/100)):(w=0,g=a.data.gutter,v=a.data.gutterLeftEdge,p=a.data.gutterRightEdge,F=g,h=a.data.colWidth));var l="";w={};U=1;var f=A.cells,G=a.gridId+"__cell"+
    -d.join("-"),P=h+g,aa=e*P,ba=0,ca=0,ka=0,la=0,da=Math.ceil(g/2),Z=Math.floor(g/2),xa=Math.ceil(F/2),ya=Math.floor(F/2);v>=da?ba=v-da:aa-=ka=da-v;p>=Z?ca=p-Z:aa-=la=Z-p;var ra=function(r){return r*pa+(r-1)*oa};0==H?(l+='<div class="zenario_overflow_wrap" style="width: '+a.scaleWidth(a.data.maxWidth)+'px; overflow-x: hidden;">',l+='<ul id="'+G+'s" class="zenario_grids" style="width: '+a.scaleWidth(aa+Math.abs(Z-p)+1)+"px;"):l+='<ul id="'+G+'s" class="zenario_grids" style="width: '+a.scaleWidth(aa)+"px;";
    -ba&&(l+="padding-left: "+a.scaleWidth(ba)+"px;");ca&&(l+="padding-right: "+a.scaleWidth(ca)+"px;");0==H&&(l+="background: white top left repeat-y url("+O(m)+"zenario/admin/grid_maker/grid_bg.php?gColWidth="+h+"&gCols="+e+"&gGutter="+g+"&gGutterLeftEdge="+v+"&gGutterRightEdge="+p+"); background-size: "+a.scaleWidth(a.data.maxWidth)+"px;",a.gGutterLeftEdge=v,a.gGutterLeft=da,a.gGutterRight=Z,a.gGutterRightEdge=p,a.gColAndGutterWidth=P,a.typAddSlot=2*P-g,a.typAddBreak=e*P-g);l+='">';0<H&&(l+=C("class",
    -"zenario_grid_object_properties",C(ea("class","zenario_grid_object_edit_properties","title",z.gridEditProperties,"data-for",b,"data-type","grouping",A.css_class?O(A.css_class):z.gridEditPlaceholder)))+"<br/>");f||(f=[]);for(b=f.length-1;0<=b;--b)f[b].cells&&a.checkCellsEmpty(f[b])&&f.splice(b,1);A=e;var V=!1;for(b in f)if(B(f,b)){f[b].width=f[b].grid_break?e:Math.min(e,f[b].width||1);A+=f[b].width;if(f[b].width==e||0==A%e)f[b].atRightEdge=!0;A>e&&(A=f[b].width,!1!==V&&(f[V].isOmega=!0),f[b].isAlpha=
    -!0);V=b}!1!==V&&(f[V].isOmega=!0);for(b in f)if(B(f,b)){a.data.responsive&&("first"!=f[b].small||!f[b].isAlpha&&f[b].isOmega||delete f[b].small,"only"!=f[b].small||f[b].isAlpha&&f[b].isOmega||delete f[b].small);f[b].widthPx=f[b].width*P-(f[b].isAlpha?ka:0)-(f[b].atRightEdge?la:0);f[b].widthPercent=ra(f[b].width);f[b].marginLeft=f[b].isAlpha&&ka?v:da;f[b].marginRight=f[b].atRightEdge&&la?p:Z;l+=wa("id",G+"-"+b,"data-i",b,"data-level",H,"data-levels",d.join("-"),"data-gutter",g,"data-minwidth",1*P-
    -g,"data-maxwidth",P*e-g,"data-is_alpha",ja(f[b].isAlpha),"data-is_omega",ja(f[b].isOmega),"data-at_right_edge",ja(f[b].atRightEdge),"data-col_and_gutter_width",P,"data-displayed_width",f[b].width*P-g,"data-displayed_margin_left",f[b].marginLeft," ");A="";f[b].grid_break||"only"==f[b].small||(A="zenario_grid_cell_resizable");l+=' class="zenario_grid_cell '+A+" zenario_grid_cell__"+G;f[b].flash&&!a.undoing&&(delete f[b].flash,l+=" zenario_grid_newly_added");l=f[b].cells?l+' zenario_grid_nest"':f[b].space?
    -l+' zenario_grid_space_cell"':l+' zenario_grid_slot"';l+=' style="width: '+a.scaleWidth(f[b].widthPx)+'px;">';f[b].grid_break&&(l+=C("class","zenario_grid_break_outer_wrap",">"));A="margin-left: "+a.scaleWidth(f[b].marginLeft)+"px; margin-right: "+a.scaleWidth(f[b].marginRight)+"px;";if(f[b].cells)l+=C("id",G+"-"+b+"-span","class","zenario_grid_wrap");else{if(f[b].slot)f[b].name?a.checkIfNameUsed(f[b].name)||(a.registerNewName(f[b].name),++a.randomNameCount):f[b].name=a.uniqueRandomName(),V=O(a.cellLabel(f[b])),
    -f[b].height&&"small"!=f[b].height&&(V+=" ("+O(f[b].height)+")"),l+=C("class","zenario_grid_border zenario_cell_in_grid zenario_slot zenario_grid_gutter "+(f[b].grid_break?"zenario_grid_break zenario_grid_break_with_slot":""),"style",A,">"),l+=C("class","zenario_grid_name_area",C("class","zenario_grid_delete","title",z.gridDelete,"data-for",G+"-"+b,"style","right: "+a.scaleWidth(f[b].marginRight)+"px;")+C("class","zenario_grid_faux_block_t")+C("class","zenario_grid_object_properties",C(ea("class",
    -"zenario_grid_slot_name zenario_grid_object_edit_properties","title",z.gridEditProperties,"data-for",G+"-"+b,"data-type",f[b].grid_break?"grid_break_with_slot":"slot",V)+ea("class","zenario_grid_object_properties_wrap",ea("class","zenario_grid_slot_contents",a.getSlotDescription(a.slotContents[f[b].name])))))),l+=C("class","zenario_grid_faux_block_r"),l+=C("class","zenario_grid_cell_size",">"),f[b].grid_break||(l=a.data.fluid?l+(y._ro(f[b].widthPercent,1)+"%"):l+(f[b].width*P-g+"px")),l+="</div>",
    -l+=C("class","zenario_grid_faux_block_t");else{l+=C("class","zenario_cell_in_grid zenario_grid_gutter zenario_no_slot "+(f[b].grid_break?"zenario_grid_break zenario_grid_break_no_slot":"zenario_grid_space"),"style",A,"title",f[b].grid_break?z.gridGridBreak:z.gridEmptySpace,">");l+=C("class","zenario_grid_delete","title",z.gridDelete,"data-for",G+"-"+b,"style","right: "+a.scaleWidth(f[b].marginRight)+"px;");l+=C("&nbsp;");l+=C("&nbsp;");l+='<div class="zenario_grid_object_properties"><div><span title="'+
    -z.gridEditProperties+'" class="zenario_grid_object_edit_properties" data-for="'+G+"-"+b+'" data-type="'+(f[b].grid_break?"grid_break":"space")+'"';var K;l=f[b].grid_break?l+(' data-grid_css_class="'+O(K=f[b].grid_css_class)+'"'):l+(' data-css_class="'+O(K=f[b].css_class)+'"');l+=">"+(K?O(K):z.gridEditPlaceholder)+"</span></div></div>"}l+="</div>"}f[b].grid_break&&(l+="</div>");l+="</li>"}l+="</ul>";0==H&&(l+="</div>");$(".ui-tooltip").remove();T(c).innerHTML=l;A=0;for(b in f)if(B(f,b)){b*=1;f[b].cells&&
    -(g=h,K=f[b].width,d.push(b),g=a.drawEditor(G+"-"+b+"-span",G+"-"+b,d,K,g,F,f[b].isAlpha?v-ba:xa,f[b].atRightEdge?p-ca:ya,F,f[b].widthPercent/K,0),d.pop(),1<g&&(f[b].width=Math.max(f[b].width,g)));U=Math.max(U,f[b].width);delete f[b].isAlpha;delete f[b].isOmega;delete f[b].atRightEdge;delete f[b].widthPx;delete f[b].widthPercent;delete f[b].marginLeft;delete f[b].marginRight;A+=f[b].width;if(A>e){K=g=0;for(g in w)B(w,g)&&(K=Math.max(K,$("#"+G+"-"+g).height()));for(g in w)B(w,g)&&$("#"+G+"-"+g).height(K);
    -A=f[b].width;w={}}w[b]=!0}K=g=0;for(g in w)B(w,g)&&(K=Math.max(K,$("#"+G+"-"+g).height()));for(g in w)B(w,g)&&$("#"+G+"-"+g).height(K);$("#"+G+"s").disableSelection();$("#"+G+"s").sortable({cancel:"a,button,input,select",placeholder:"zenario_grid_cell zenario_grid_sortable_target",sort:function(r,t){r=$(".zenario_grid_sortable_target");var q=t.item.data("add");$(".zenario_overflow_wrap").scrollLeft(0);if(E(q)){t=70;switch(q){case "grid_break":case "grid_break_with_slot":q=a.scaleWidth(a.typAddBreak);
    -break;default:q=a.scaleWidth(a.typAddSlot)}var u=r.next();u.length||(u=r.prev());u.length&&(t=u.height()-10);r.height(t).width(q)}else t=1*t.item.data("displayed_width"),r.height(70).width(a.scaleWidth(t));u=r.next();u.hasClass("ui-draggable")&&(u=!1);var N=r.offset().left<a.gColAndGutterWidth;q=!u||!u.offset()||u.offset().left<r.offset().left;t=!!(u&&1*u.data("is_alpha"));u&&u.data("at_right_edge");u=N?a.gGutterLeftEdge:a.gGutterLeft;q=q?a.gGutterRightEdge:a.gGutterRight;t&&(q+=a.gGutterLeft-a.gGutterLeftEdge);
    -r.html(C("style","margin-left: "+a.scaleWidth(u)+"px; margin-right: "+a.scaleWidth(q)+"px;"))},items:"li.zenario_grid_cell__"+G,connectWith:".zenario_grids",start:function(r,t){a.stopRenames=!0},stop:function(r,t){r=a.data;var q=t.item.data(),u=t.item.prev().data();t.item.prev().data();var N=t.item.parent().parent().parent().data();N&&E(N.level)||(N=k);if(!q.add){var L=q.i;var M=r;if(1*q.level)for(J in d=(""+q.levels).s("-"),d)if(B(d,J)){var W=d[J];M=M.cells[1*W]}}u=u?u.i+1:0;t=r;if(N)for(J in d=
    -""!=N.levels?(N.levels+"-"+N.i).s("-"):[N.i],d)B(d,J)&&(W=d[J],t=t.cells[1*W]);var J=L==u;if(W=M===t){if(J)return;u>L&&--u}if(W||!M||!M.cells[L].grid_break){switch(q.add){case "slot":L={width:2,slot:!0,name:a.uniqueRandomName(),flash:!0};M=z.growlSlotAdded;break;case "space":L={width:2,space:!0,css_class:a.randomName(2,"Space_"),flash:!0};M=z.growlSpaceAdded;break;case "grouping":L={width:2,css_class:a.randomName(2,"Grouping_"),flash:!0,cells:[{width:2,slot:!0,name:a.uniqueRandomName()},{width:2,
    -slot:!0,name:a.uniqueRandomName()}]};M=z.growlChildrenAdded;break;case "grid_break":if(N){a.change();return}L={width:r.cols,grid_break:!0,grid_css_class:a.randomName(2,"Gridbreak_"),flash:!0};M=z.growlGridBreakAdded;break;case "grid_break_with_slot":if(N){a.change();return}L={width:r.cols,grid_break:!0,slot:!0,grid_css_class:a.randomName(2,"Gridbreak_"),name:a.uniqueRandomName(),flash:!0};M=z.growlSlotAdded;break;default:L=M.cells.splice(L,1)[0],M=z.growlSlotMoved}t.cells.splice(u,0,L);toastr.success(M)}a.change()}});
    -if(0==H)$("#"+c+" .zenario_grid_cell_resizable").each(function(r,t){var q=$(t);q.width();q.data("displayed_width");var u=1*q.data("col_and_gutter_width"),N=1*q.data("displayed_margin_left");r=1*q.data("minwidth");t=1*q.data("maxwidth");q.data("level");var L=1*q.data("gutter"),M=Math.floor(a.scaleWidth(u)),W=1/a.scaleWidth(1);q.resizable({cancel:"a,button,input,select",handles:"se",grid:M,minHeight:q.height(),maxHeight:q.height(),minWidth:Math.floor(a.scaleWidth(r-.5*u+1)),maxWidth:Math.floor(a.scaleWidth(t+
    -.5*u-1)),helper:"ui-resizable-helper",start:function(J,Q){q.hasClass("zenario_grid_nest")?$(n.body).addClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell"):q.hasClass("zenario_grid_space_cell")?$(n.body).removeClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").addClass("zenario_grid_resizing_space_cell"):$(n.body).removeClass("zenario_grid_resizing_nest").addClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell")},
    -resize:function(J,Q){J=Q.helper.width();var X=Q.element.width(),R="",S=Math.round((J+L/2)/u*W),fa=S*u-L;J!=X&&(R=a.data.fluid?R+(y._ro(ra(S),1)+"%"):R+(fa+"px"));Q.helper.html(C("class","zenario_resizing_border","style","height: "+(Q.helper.height()-4)+"px; width: "+(a.scaleWidth(fa)-4)+"px; margin-left: "+a.scaleWidth(N)+"px;",C("class","zenario_size_when_resizing",R)))},stop:function(J,Q){$(n.body).removeClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell");
    -J=1*Q.element.data("i");var X=a.getLevels(Q.element),R=a.data;if(X){X=X.s("-");for(var S in X)B(X,S)&&(S*=1,R=R.cells[1*X[S]])}S=R.cells[1*J];var fa=S.width,sa=S.width=Math.round((Q.element.width()+L/2)/u*W),ta=function(ha){if(ha){var ma;for(ma in ha)if(B(ha,ma)){var ia=ha[ma];if(ia.width==fa||ia.width>sa)ia.width=sa;ta(ia.cells)}}};ta(R.cells[J].cells);a.change()}})}),$("#"+c+" .ui-resizable-handle").each(function(r,t){r=$(t);t=r.prev();var q=t.children().first();q&&q.length&&q.hasClass("zenario_grids")?
    -(r.css("right","-2px"),r.css("top",t.height()-12+"px"),r.attr("title",z.gridResizeNestedCells)):(r.css("right",1*t.css("marginRight").r(/[^\d\.]/g,"")),r.css("top",t.height()+10+2+10+10+2-19+"px"),r.attr("title",z.gridResizeSlot))}),$("#"+c).width(aa+ba+ca).addClass("zenario_grid_wrapper"),a.tooltips("#"+c),$("#"+c+" .zenario_grid_delete").click(function(){a.deleteCell(this)}),$("#"+c+" .zenario_grid_object_edit_properties").click(function(){a.stopRenames||a.editProperties(this)}),setTimeout(function(){delete a.stopRenames},
    -100),a.drawLinks(),$("#"+c+" .zenario_grid_newly_added .zenario_cell_in_grid").effect({effect:"highlight",duration:1E3,easing:"zenarioOmmitEnd"}),$("#"+a.gridId).scrollTop(qa),a.drawAddToolbar();else return U};a.getSlotDescription=function(c){if(c){var b=O(c.display_name);if(c.instance_id){b+=", ";switch(c.class_name){case "zenario_plugin_nest":b+="N";break;case "zenario_slideshow":case "zenario_slideshow_simple":b+="S";break;default:b+="P"}b+=(""+c.instance_id).padStart(2,"0")}else b+=" (version controlled)"}else b=
    -va("em","class","zenario_grid_empty_slot_contents","Empty");return b};a.drawOptions=function(){var c=a.microTemplate(a.mtPrefix+"top",{formId:"settings"});$(".ui-tooltip").remove();T("settings").innerHTML=c;Y._to("#settings  *[title]");a.data.fluid||a.recalcColumnAndGutterOptions(a.data);$("#settings input.zenario_grid_setting_break_1").change(a.update).spinner({stop:a.update,min:10,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_break_2").change(a.update).spinner({stop:a.update,
    -min:300,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_min_width").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:100,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_max_width").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:320,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_gutter_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,
    -min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_gutter_left_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_gutter_right_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_full_width").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,
    -min:320,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_cols").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,min:1,step:1});$("#settings input.zenario_grid_setting_gutter_left").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,min:0,step:1}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_gutter_right").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,
    -min:0,step:1}).after('<span class="zenario_grid_unit">px</span>');$("#settings select.zenario_grid_setting_col_and_gutter").change(a.recalcOnChange);$("#settings input.zenario_grid_setting_fixed").change(a.updateAndChange);$("#settings input.zenario_grid_setting_flu").change(a.updateAndChange);$("#settings input.zenario_grid_setting_responsive").change(a.updateAndChange);$("#settings input.zenario_grid_setting_mirror").change(a.updateAndChange);a.canUndo()&&$("#settings .zenario_grid_setting_undo").click(function(){a.undo()});
    -a.canRedo()&&$("#settings .zenario_grid_setting_redo").click(function(){a.redo()});$("#settings .zenario_grid_setting_preview_grid").click(function(){a.editing=!1;a.drawPreview()});$("#settings .zenario_grid_setting_edit_slots").click(function(){a.editing=!0;a.drawEditor()})};a.recalcColumnAndGutterOptions=function(c,b,d){var e=!1,h=(d?d:1*$("#settings--setting_full_width").val())-c.gutterLeftEdge-c.gutterRightEdge;d=Math.floor(h/c.cols);var g=0,v=!1,p=0;b||(e=T("settings--setting_col_width"));if(!c.cols)return!1;
    -if(e)for(p=e.length-1;0<=p;--p)e.remove(p);if(1==c.cols)e&&e.add(new Option(d+" px / "+g+" px",d+"/"+g),++p),v={colWidth:d,gutter:g};else{p=c.cols-1;b=h/p;h=c.cols/p;var F=999999;for(p=-1;d>g;--d)if(g=b-h*d,g=Math.round(1E4*g)/1E4,g==Math.floor(g)){e&&e.add(new Option(d+" px / "+g+" px",d+"/"+g),++p);var w=Math.abs(c.gutter/c.colWidth-g/d);F>w&&(e&&(e.selectedIndex=p),F=w,v={colWidth:d,gutter:g})}}return v};a.editProperties=function(c){$(c);var b,d={},e=["zenario_grid_box","zenario_grid_rename_slot_box"];
    -if((b=$(c).data("for"))&&(b=$("#"+b))){var h=b.data();var g=h.i;d.type=$(c).data("type");b=a.getLevels(b);var v=a.data;if(b){b=b.s("-");for(var p in b)B(b,p)&&(p*=1,v=v.cells[1*b[p]])}d.cell=h;d.data=v.cells[g];d.slot=E(d.data.name)&&a.slotContents[d.data.name];$.colorbox({transition:"none",html:a.microTemplate(a.mtPrefix+"object_properties",d),height:"99%",width:580,onOpen:function(){y._aCTC(e)},onClosed:function(){y._rCTC(e)},onComplete:function(){$("#zenario_grid_slotname_button").click(function(){var F,
    -w={},H=$("#colorbox .zenario_grid_properties_form").serializeArray();for(F in H)B(H,F)&&(w[H[F].name]=H[F].value);a.saveProperties(c,w)});$(".zenario_grid_properties_form input,textarea")[1].focus()}})}};a.ajaxURL=function(){return m+"zenario/admin/grid_maker/ajax.php"};a.ajaxData=function(){return JSON.stringify(a.data)};a.ajaxSrc=function(){var c=a.ajaxData(),b=a.ajaxURL()+"?data="+ua(c);400<b.length&&(b=a.ajaxURL()+"?cdata="+y._nAA(a.ajaxURL(),{compress:1,data:c}));return b};a.drawPreview=function(){a.clearAddToolbar();
    -a.checkData();var c=Math.max(a.desktopSmallestSize,100*Math.round(($(x).width()-a.previewPaddingLeftRight)/100)),b=Math.min(c-20,a.data.maxWidth),d=a.microTemplate(a.mtPrefix+"preview",{gridId:a.gridId,topHack:5,leftHack:10,min:100,max:c,startingValue:b});$("#"+a.gridId).css("margin","auto");$(".ui-tooltip").remove();T(a.gridId).innerHTML=d;Y._to("#"+a.gridId+"  *[title]");$('<form action="'+O(a.ajaxURL())+'" method="post" target="'+a.gridId+'-iframe"><input name="data" value="'+O(a.ajaxData())+'"/></form>').appendTo("body").hide().submit().remove();
    -$("#"+a.gridId+"-slider").slider({min:100,max:c,step:10,animate:!0,value:b,start:function(h,g){$("#"+a.gridId+"-slider_overlay").css("display","block")},stop:function(h,g){$("#"+a.gridId+"-slider_overlay").css("display","none")},slide:function(h,g){$("#"+a.gridId+"-slider_val").val(g.value);$("#"+a.gridId+"-iframe").clearQueue();$("#"+a.gridId+"-size").clearQueue();!h.originalEvent||"mousedown"!=h.originalEvent.type&&"touchstart"!=h.originalEvent.type?($("#"+a.gridId+"-iframe").width(g.value),$("#"+
    -a.gridId+"-size").css("marginLeft",g.value+"px")):($("#"+a.gridId+"-iframe").animate({width:g.value}),$("#"+a.gridId+"-size").animate({marginLeft:g.value}));a.resizePreview()}});$("#"+a.gridId+"-slider_val").change(function(){var h=1*this.value;h&&100<=h&&h<=c&&($("#"+a.gridId+"-slider").slider("value",h),$("#"+a.gridId+"-iframe").clearQueue().animate({width:h}),$("#"+a.gridId+"-size").clearQueue().animate({marginLeft:h}))});a.resizePreview();var e=function(h){$("#"+a.gridId+"-slider_val").val(h);
    -$("#"+a.gridId+"-slider").slider("value",h);$("#"+a.gridId+"-size").clearQueue().animate({marginLeft:h});$("#"+a.gridId+"-iframe").clearQueue().animate({width:h},{complete:a.resizePreview});a.lastToast&&a.lastToast.remove();a.lastToast=toastr.info(z.gridDisplayingAt.r("[[pixels]]",h))};$("#"+a.gridId+"-slider_mobile").click(function(){e(a.mobileWidth)});$("#"+a.gridId+"-slider_tablet").click(function(){e(a.tabletWidth)});$("#"+a.gridId+"-slider_desktop").click(function(){e(c)});$("#settings--tabs").removeClass("zenario_grid_tabs_slots_selected").addClass("zenario_grid_tabs_grid_selected");
    -a.drawLinks()};a.clearAddToolbar=function(){$("#"+a.addToolbarId).hide().html("")};a.drawAddToolbar=function(){$("#"+a.addToolbarId).show().html(a.microTemplate(a.mtPrefix+"add_toolbar",{}));$("#"+a.addToolbarId+" a").draggable({connectToSortable:".zenario_grids",helper:"clone",revert:"invalid"});var c=$("#"+a.addToolbarId),b=c.position();b&&E(b.top)&&E(b.left)&&c.css({right:"auto",top:b.top,left:b.left});$("#"+a.addToolbarId).draggable({cursor:"move"})};$(n).ready(function(){$("#"+a.addToolbarId).hover(function(){$(this).css("cursor",
    -"move")},function(){$(this).css("cursor","pointer")})});a.resizePreview=function(){var c,b=0;(c=T(a.gridId+"-iframe"))&&c.contentWindow&&c.contentWindow.document&&c.contentWindow.document.body&&(b=$(c.contentWindow.document.body).height()||360,360>b&&(b=360),$("#"+a.gridId+"-iframe").height(b),$("#"+a.gridId+"-slider_overlay").height(b),$("#"+a.gridId+"-slider a").css("position","absolute").css("z-index",20).css("top","-"+(b+5)+"px").height(b+5).html('<span style="margin-top: '+Math.ceil((b+5)/2)+
    -'px;"></span>'));a.lastIframeHeight=b};a.drawLinks=function(){a.checkData();var c={src:a.ajaxSrc()};a.microTemplate(a.mtPrefix+"bottom_links",c);$(".ui-tooltip").remove();Y._to("#download_links  *[title]");c=$("#"+a.gridId);a.editing?c.addClass("zenario_grid_slot_view").removeClass("zenario_grid_grid_view"):(c.addClass("zenario_grid_grid_view").removeClass("zenario_grid_slot_view"),c.css({height:"auto"}),c=$("#"+a.gridId+" .zenario_grid_preview_frame"));c.height(0);c.height(Math.max(a.gridAreaSmallestHeight,
    -$(x).height()-$("body").height()-a.bodyPadding));var b=["zenario_grid_box","zenario_grid_copy_box","zenario_grid_copy_css_box"];$("#download_links a.zenario_grid_copy_css").colorbox({onOpen:function(){y._aCTC(b)},onClosed:function(){y._rCTC(b)},onComplete:function(){$("#colorbox textarea").focus()}});var d=["zenario_grid_box","zenario_grid_copy_box","zenario_grid_copy_html_box"];$("#download_links a.zenario_grid_copy_html").colorbox({onOpen:function(){y._aCTC(d)},onClosed:function(){y._rCTC(d)},onComplete:function(){$("#colorbox textarea").focus()}})};
    -a.confirmDeleteSlot=function(c,b){y._a(m+"zenario/ajax.php?moduleClassName=zenario_common_features&method_call=handleAJAX"+y._uR({removeSlot:1,level:2,slotName:c.oName,layoutId:a.layoutId})).after(function(d){Y._flBo(d,Y.phrase.gridDelete,"warning",!1,!1,!0,k,b)})};a.save=function(c){a.layoutId||(c=!0);var b;if(c){var d=["zenario_grid_box","zenario_grid_new_layout_box"];(b=y._nAA(a.ajaxURL(),{saveas:1,data:a.ajaxData(),layoutId:a.layoutId},!0))&&$.colorbox({transition:"none",html:a.microTemplate(a.mtPrefix+
    -"save_prompt",{name:a.newLayoutName||b.oldLayoutName||""}),onOpen:function(){y._aCTC(d)},onClosed:function(){y._rCTC(d)},onComplete:function(){$("#zenario_grid_new_layout_save").click(function(){$("#zenario_grid_error").hide();(b=y._nAA(a.ajaxURL(),{saveas:1,confirm:1,data:a.ajaxData(),layoutId:a.layoutId,layoutName:a.newLayoutName=T("zenario_grid_layout_name").value},!0))?b.error?$("#zenario_grid_error").html(O(b.error)).slideDown():($.colorbox.close(),a.layoutName=a.newLayoutName,a.markAsSaved(b)):
    -$.colorbox.close()});T("zenario_grid_layout_name").focus()}})}else if(b=y._nAA(a.ajaxURL(),{save:1,data:a.ajaxData(),layoutId:a.layoutId},!0))b.success?a.markAsSaved(b,!0):(Y._flBo(b.message,z.gridSave,"warning",!0,!0),$("#zenario_fbMessageButtons .submit_selected").click(function(){setTimeout(function(){var e;(e=y._nAA(a.ajaxURL(),{save:1,data:a.ajaxData(),layoutId:a.layoutId,confirm:1},!0))&&a.markAsSaved(e)},50)}))};a.saveProperties=function(c,b){var d;if((d=$(c).data("for"))&&(d=$("#"+d))){c=
    -d.data("i");d=a.getLevels(d);var e=a.data;if(d){d=d.s("-");for(var h in d)B(d,h)&&(h*=1,e=e.cells[1*d[h]])}if(e.cells[c].slot){if(b.name){if(b.name!=b.name.r(/[^a-zA-Z0-9_]/g,"")){$("#zenario_grid_error").html(z.gridErrorNameFormat).slideDown();return}if(b.name!=e.cells[c].name&&a.checkIfNameUsed(b.name)){$("#zenario_grid_error").html(z.gridErrorNameInUse).slideDown();return}}else{$("#zenario_grid_error").html(z.gridErrorNameIncomplete).slideDown();return}delete a.names[e.cells[c].name];a.registerNewName(b.name)}for(var g in b)B(b,
    -g)&&(""!=b[g]?e.cells[c][g]=b[g]:delete e.cells[c][g]);a.change()}$.colorbox.close()};a.markAsSaved=function(c,b){a.savedAtPos=a.pos;E(c.layoutId)&&(a.layoutId=c.layoutId);a.rememberNames(a.data.cells);c.success&&(b?Y._flBo(c.success,!0,"success"):toastr.success(c.success));if(I&&I.zenarioO.init)switch(I.zenarioO.path){case "zenario__layouts/panels/layouts":c.layoutId&&I.zenarioO._rTSI(c.layoutId)}};a.readSettings=function(c){c.fluid=$("#settings input.zenario_grid_setting_flu").prop("checked");c.responsive=
    -$("#settings input.zenario_grid_setting_responsive").prop("checked");c.mirror=$("#settings input.zenario_grid_setting_mirror").prop("checked");c.cols=1*$("#settings input.zenario_grid_setting_cols").val();var b;(b=$("#settings input.zenario_grid_setting_full_width")).length?c.maxWidth=1*b.val():(b=$("#settings input.zenario_grid_setting_max_width")).length&&(c.maxWidth=1*b.val());(b=$("#settings input.zenario_grid_setting_min_width")).length&&(c.minWidth=1*b.val());(b=$("#settings input.zenario_grid_setting_break_1")).length&&
    -(c.bp1=1*b.val());(b=$("#settings input.zenario_grid_setting_break_2")).length&&(c.bp2=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_left")).length&&(c.gutterLeftEdge=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_right")).length&&(c.gutterRightEdge=1*b.val());(b=$("#settings select.zenario_grid_setting_col_and_gutter")).length&&(b=b.val())&&(b=b.s("/"))&&(c.colWidth=1*b[0],c.gutter=1*b[1]);(b=$("#settings input.zenario_grid_setting_gutter_left_flu")).length&&(c.gutterLeftEdgeFlu=
    -1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_flu")).length&&(c.gutterFlu=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_right_flu")).length&&(c.gutterRightEdgeFlu=1*b.val())};a.updateAndChange=function(){a.update();a.change()};a.update=function(){a.readSettings(a.data);a.checkData()};a.recalcOnKeyUp=function(){a.recalc(this)};a.recalcOnChange=function(){a.recalc(this,!0,!0)};a.recalcOnInc=function(c,b){if(c.originalEvent&&"mouseup"==c.originalEvent.type)return a.recalc(this,
    -!0)};a.recalc=function(c,b,d){var e=$.extend(!1,{},a.data),h=!1,g=!1,v=0,p=c.className,F;e.fluid?(delete e.gutter,delete e.gutterLeftEdge,delete e.gutterRightEdge):(delete e.gutterFlu,delete e.gutterLeftEdgeFlu,delete e.gutterRightEdgeFlu);d||(h=JSON.stringify(e));a.readSettings(e);g=a.checkDataNonZeroAndNumeric(e,g);if(e.fluid)delete e.gutter,delete e.gutterLeftEdge,delete e.gutterRightEdge;else{switch(p.s(" ")[0]){case "zenario_grid_setting_full_width":v=1;break;case "zenario_grid_setting_cols":v=
    -2;break;case "zenario_grid_setting_gutter_left":v=3;break;case "zenario_grid_setting_gutter_right":v=4;break;case "zenario_grid_setting_col_and_gutter":v=5}if(v){if(d||$(c).val()!=$(c).attr("data-initial-value"))$(c).attr("data-initial-value",$(c).val());else return;do if(!e.maxWidth||1>e.cols)g=!0;else{if(e.gutterLeftEdge+e.cols+e.gutterRightEdge>e.maxWidth)if(3>v)e.gutterLeftEdge=e.gutterRightEdge=0;else{g=!0;break}5>v&&(F=a.recalcColumnAndGutterOptions(e))&&(e.colWidth=F.colWidth,e.gutter=F.gutter);
    -g=a.checkDataNonZeroAndNumeric(e,g);p=0;var w=[{l:3,c:"zenario_grid_setting_gutter_left",v:e.gutterLeftEdge},{l:4,c:"zenario_grid_setting_gutter_right",v:e.gutterRightEdge},{l:5,c:"zenario_grid_setting_col_and_gutter",v:e.colWidth+"/"+e.gutter}];for(p in w)if(B(w,p)&&v<w[p].l){var H=$("#settings ."+w[p].c);H.val()!=w[p].v&&H.animate({opacity:.3},"fast").val(w[p].v).animate({opacity:1},"fast")}}while(0)}delete e.gutterFlu;delete e.gutterLeftEdgeFlu;delete e.gutterRightEdgeFlu}if(d||h!=JSON.stringify(e))$("#settings .zenario_grid_setting_warning").removeClass("zenario_grid_setting_warning"),
    -b?g?a.revert():(a.readSettings(a.data),a.checkDataNonZeroAndNumeric(a.data),a.change(!1,!0)):g&&$(c).parent().addClass("zenario_grid_setting_warning");return!g}})},window.zenarioGM=zenario._cZL("GM"));
    +d.join("-"),P=h+g,aa=e*P,ba=0,ca=0,ka=0,la=0,da=Math.ceil(g/2),Z=Math.floor(g/2),xa=Math.ceil(F/2),ya=Math.floor(F/2);v>=da?ba=v-da:aa-=ka=da-v;p>=Z?ca=p-Z:aa-=la=Z-p;var ra=function(r){return r*pa+(r-1)*oa};l=0==H?l+'<div class="zenario_overflow_wrap"><ul id="'+(G+'s" class="zenario_grids" style="width: '+a.scaleWidth(aa+Math.abs(Z-p)+1)+"px;"):l+('<ul id="'+G+'s" class="zenario_grids" style="width: '+a.scaleWidth(aa)+"px;");ba&&(l+="padding-left: "+a.scaleWidth(ba)+"px;");ca&&(l+="padding-right: "+
    +a.scaleWidth(ca)+"px;");0==H&&(l+="background-image: url("+O(m)+"zenario/admin/grid_maker/grid_bg.php?gColWidth="+h+"&gCols="+e+"&gGutter="+g+"&gGutterLeftEdge="+v+"&gGutterRightEdge="+p+");",a.gGutterLeftEdge=v,a.gGutterLeft=da,a.gGutterRight=Z,a.gGutterRightEdge=p,a.gColAndGutterWidth=P,a.typAddSlot=2*P-g,a.typAddBreak=e*P-g);l+='">';0<H&&(l+=C("class","zenario_grid_object_properties",C(ea("class","zenario_grid_object_edit_properties","title",z.gridEditProperties,"data-for",b,"data-type","grouping",
    +A.css_class?O(A.css_class):z.gridEditPlaceholder)))+"<br/>");f||(f=[]);for(b=f.length-1;0<=b;--b)f[b].cells&&a.checkCellsEmpty(f[b])&&f.splice(b,1);A=e;var V=!1;for(b in f)if(B(f,b)){f[b].width=f[b].grid_break?e:Math.min(e,f[b].width||1);A+=f[b].width;if(f[b].width==e||0==A%e)f[b].atRightEdge=!0;A>e&&(A=f[b].width,!1!==V&&(f[V].isOmega=!0),f[b].isAlpha=!0);V=b}!1!==V&&(f[V].isOmega=!0);for(b in f)if(B(f,b)){a.data.responsive&&("first"!=f[b].small||!f[b].isAlpha&&f[b].isOmega||delete f[b].small,"only"!=
    +f[b].small||f[b].isAlpha&&f[b].isOmega||delete f[b].small);f[b].widthPx=f[b].width*P-(f[b].isAlpha?ka:0)-(f[b].atRightEdge?la:0);f[b].widthPercent=ra(f[b].width);f[b].marginLeft=f[b].isAlpha&&ka?v:da;f[b].marginRight=f[b].atRightEdge&&la?p:Z;l+=wa("id",G+"-"+b,"data-i",b,"data-level",H,"data-levels",d.join("-"),"data-gutter",g,"data-minwidth",1*P-g,"data-maxwidth",P*e-g,"data-is_alpha",ja(f[b].isAlpha),"data-is_omega",ja(f[b].isOmega),"data-at_right_edge",ja(f[b].atRightEdge),"data-col_and_gutter_width",
    +P,"data-displayed_width",f[b].width*P-g,"data-displayed_margin_left",f[b].marginLeft," ");A="";f[b].grid_break||"only"==f[b].small||(A="zenario_grid_cell_resizable");l+=' class="zenario_grid_cell '+A+" zenario_grid_cell__"+G;f[b].flash&&!a.undoing&&(delete f[b].flash,l+=" zenario_grid_newly_added");l=f[b].cells?l+' zenario_grid_nest"':f[b].space?l+' zenario_grid_space_cell"':l+' zenario_grid_slot"';l+=' style="width: '+a.scaleWidth(f[b].widthPx)+'px;">';f[b].grid_break&&(l+=C("class","zenario_grid_break_outer_wrap",
    +">"));A="margin-left: "+a.scaleWidth(f[b].marginLeft)+"px; margin-right: "+a.scaleWidth(f[b].marginRight)+"px;";if(f[b].cells)l+=C("id",G+"-"+b+"-span","class","zenario_grid_wrap");else{if(f[b].slot)f[b].name?a.checkIfNameUsed(f[b].name)||(a.registerNewName(f[b].name),++a.randomNameCount):f[b].name=a.uniqueRandomName(),V=O(a.cellLabel(f[b])),f[b].height&&"small"!=f[b].height&&(V+=" ("+O(f[b].height)+")"),l+=C("class","zenario_grid_border zenario_cell_in_grid zenario_slot zenario_grid_gutter "+(f[b].grid_break?
    +"zenario_grid_break zenario_grid_break_with_slot":""),"style",A,">"),l+=C("class","zenario_grid_name_area",C("class","zenario_grid_delete","title",z.gridDelete,"data-for",G+"-"+b,"style","right: "+a.scaleWidth(f[b].marginRight)+"px;")+C("class","zenario_grid_faux_block_t")+C("class","zenario_grid_object_properties",C(ea("class","zenario_grid_slot_name zenario_grid_object_edit_properties","title",z.gridEditProperties,"data-for",G+"-"+b,"data-type",f[b].grid_break?"grid_break_with_slot":"slot",V)+ea("class",
    +"zenario_grid_object_properties_wrap",ea("class","zenario_grid_slot_contents",a.getSlotDescription(a.slotContents[f[b].name])))))),l+=C("class","zenario_grid_faux_block_r"),l+=C("class","zenario_grid_cell_size",">"),f[b].grid_break||(l=a.data.fluid?l+(y._ro(f[b].widthPercent,1)+"%"):l+(f[b].width*P-g+"px")),l+="</div>",l+=C("class","zenario_grid_faux_block_t");else{l+=C("class","zenario_cell_in_grid zenario_grid_gutter zenario_no_slot "+(f[b].grid_break?"zenario_grid_break zenario_grid_break_no_slot":
    +"zenario_grid_space"),"style",A,"title",f[b].grid_break?z.gridGridBreak:z.gridEmptySpace,">");l+=C("class","zenario_grid_delete","title",z.gridDelete,"data-for",G+"-"+b,"style","right: "+a.scaleWidth(f[b].marginRight)+"px;");l+=C("&nbsp;");l+=C("&nbsp;");l+='<div class="zenario_grid_object_properties"><div><span title="'+z.gridEditProperties+'" class="zenario_grid_object_edit_properties" data-for="'+G+"-"+b+'" data-type="'+(f[b].grid_break?"grid_break":"space")+'"';var K;l=f[b].grid_break?l+(' data-grid_css_class="'+
    +O(K=f[b].grid_css_class)+'"'):l+(' data-css_class="'+O(K=f[b].css_class)+'"');l+=">"+(K?O(K):z.gridEditPlaceholder)+"</span></div></div>"}l+="</div>"}f[b].grid_break&&(l+="</div>");l+="</li>"}l+="</ul>";0==H&&(l+="</div>");$(".ui-tooltip").remove();T(c).innerHTML=l;A=0;for(b in f)if(B(f,b)){b*=1;f[b].cells&&(g=h,K=f[b].width,d.push(b),g=a.drawEditor(G+"-"+b+"-span",G+"-"+b,d,K,g,F,f[b].isAlpha?v-ba:xa,f[b].atRightEdge?p-ca:ya,F,f[b].widthPercent/K,0),d.pop(),1<g&&(f[b].width=Math.max(f[b].width,g)));
    +U=Math.max(U,f[b].width);delete f[b].isAlpha;delete f[b].isOmega;delete f[b].atRightEdge;delete f[b].widthPx;delete f[b].widthPercent;delete f[b].marginLeft;delete f[b].marginRight;A+=f[b].width;if(A>e){K=g=0;for(g in w)B(w,g)&&(K=Math.max(K,$("#"+G+"-"+g).height()));for(g in w)B(w,g)&&$("#"+G+"-"+g).height(K);A=f[b].width;w={}}w[b]=!0}K=g=0;for(g in w)B(w,g)&&(K=Math.max(K,$("#"+G+"-"+g).height()));for(g in w)B(w,g)&&$("#"+G+"-"+g).height(K);$("#"+G+"s").disableSelection();$("#"+G+"s").sortable({cancel:"a,button,input,select",
    +placeholder:"zenario_grid_cell zenario_grid_sortable_target",sort:function(r,t){r=$(".zenario_grid_sortable_target");var q=t.item.data("add");$(".zenario_overflow_wrap").scrollLeft(0);if(E(q)){t=70;switch(q){case "grid_break":case "grid_break_with_slot":q=a.scaleWidth(a.typAddBreak);break;default:q=a.scaleWidth(a.typAddSlot)}var u=r.next();u.length||(u=r.prev());u.length&&(t=u.height()-10);r.height(t).width(q)}else t=1*t.item.data("displayed_width"),r.height(70).width(a.scaleWidth(t));u=r.next();
    +u.hasClass("ui-draggable")&&(u=!1);var N=r.offset().left<a.gColAndGutterWidth;q=!u||!u.offset()||u.offset().left<r.offset().left;t=!!(u&&1*u.data("is_alpha"));u&&u.data("at_right_edge");u=N?a.gGutterLeftEdge:a.gGutterLeft;q=q?a.gGutterRightEdge:a.gGutterRight;t&&(q+=a.gGutterLeft-a.gGutterLeftEdge);r.html(C("style","margin-left: "+a.scaleWidth(u)+"px; margin-right: "+a.scaleWidth(q)+"px;"))},items:"li.zenario_grid_cell__"+G,connectWith:".zenario_grids",start:function(r,t){a.stopRenames=!0},stop:function(r,
    +t){r=a.data;var q=t.item.data(),u=t.item.prev().data();t.item.prev().data();var N=t.item.parent().parent().parent().data();N&&E(N.level)||(N=k);if(!q.add){var L=q.i;var M=r;if(1*q.level)for(J in d=(""+q.levels).s("-"),d)if(B(d,J)){var W=d[J];M=M.cells[1*W]}}u=u?u.i+1:0;t=r;if(N)for(J in d=""!=N.levels?(N.levels+"-"+N.i).s("-"):[N.i],d)B(d,J)&&(W=d[J],t=t.cells[1*W]);var J=L==u;if(W=M===t){if(J)return;u>L&&--u}if(W||!M||!M.cells[L].grid_break){switch(q.add){case "slot":L={width:2,slot:!0,name:a.uniqueRandomName(),
    +flash:!0};M=z.growlSlotAdded;break;case "space":L={width:2,space:!0,css_class:a.randomName(2,"Space_"),flash:!0};M=z.growlSpaceAdded;break;case "grouping":L={width:2,css_class:a.randomName(2,"Grouping_"),flash:!0,cells:[{width:2,slot:!0,name:a.uniqueRandomName()},{width:2,slot:!0,name:a.uniqueRandomName()}]};M=z.growlChildrenAdded;break;case "grid_break":if(N){a.change();return}L={width:r.cols,grid_break:!0,grid_css_class:a.randomName(2,"Gridbreak_"),flash:!0};M=z.growlGridBreakAdded;break;case "grid_break_with_slot":if(N){a.change();
    +return}L={width:r.cols,grid_break:!0,slot:!0,grid_css_class:a.randomName(2,"Gridbreak_"),name:a.uniqueRandomName(),flash:!0};M=z.growlSlotAdded;break;default:L=M.cells.splice(L,1)[0],M=z.growlSlotMoved}t.cells.splice(u,0,L);toastr.success(M)}a.change()}});if(0==H)$("#"+c+" .zenario_grid_cell_resizable").each(function(r,t){var q=$(t);q.width();q.data("displayed_width");var u=1*q.data("col_and_gutter_width"),N=1*q.data("displayed_margin_left");r=1*q.data("minwidth");t=1*q.data("maxwidth");q.data("level");
    +var L=1*q.data("gutter"),M=Math.floor(a.scaleWidth(u)),W=1/a.scaleWidth(1);q.resizable({cancel:"a,button,input,select",handles:"se",grid:M,minHeight:q.height(),maxHeight:q.height(),minWidth:Math.floor(a.scaleWidth(r-.5*u+1)),maxWidth:Math.floor(a.scaleWidth(t+.5*u-1)),helper:"ui-resizable-helper",start:function(J,Q){q.hasClass("zenario_grid_nest")?$(n.body).addClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell"):q.hasClass("zenario_grid_space_cell")?
    +$(n.body).removeClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").addClass("zenario_grid_resizing_space_cell"):$(n.body).removeClass("zenario_grid_resizing_nest").addClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell")},resize:function(J,Q){J=Q.helper.width();var X=Q.element.width(),R="",S=Math.round((J+L/2)/u*W),fa=S*u-L;J!=X&&(R=a.data.fluid?R+(y._ro(ra(S),1)+"%"):R+(fa+"px"));Q.helper.html(C("class","zenario_resizing_border","style","height: "+
    +(Q.helper.height()-4)+"px; width: "+(a.scaleWidth(fa)-4)+"px; margin-left: "+a.scaleWidth(N)+"px;",C("class","zenario_size_when_resizing",R)))},stop:function(J,Q){$(n.body).removeClass("zenario_grid_resizing_nest").removeClass("zenario_grid_resizing_cell").removeClass("zenario_grid_resizing_space_cell");J=1*Q.element.data("i");var X=a.getLevels(Q.element),R=a.data;if(X){X=X.s("-");for(var S in X)B(X,S)&&(S*=1,R=R.cells[1*X[S]])}S=R.cells[1*J];var fa=S.width,sa=S.width=Math.round((Q.element.width()+
    +L/2)/u*W),ta=function(ha){if(ha){var ma;for(ma in ha)if(B(ha,ma)){var ia=ha[ma];if(ia.width==fa||ia.width>sa)ia.width=sa;ta(ia.cells)}}};ta(R.cells[J].cells);a.change()}})}),$("#"+c+" .ui-resizable-handle").each(function(r,t){r=$(t);t=r.prev();var q=t.children().first();q&&q.length&&q.hasClass("zenario_grids")?(r.css("right","-2px"),r.css("top",t.height()-12+"px"),r.attr("title",z.gridResizeNestedCells)):(r.css("right",1*t.css("marginRight").r(/[^\d\.]/g,"")),r.css("top",t.height()+10+2+10+10+2-19+
    +"px"),r.attr("title",z.gridResizeSlot))}),$("#"+c).width(aa+ba+ca).addClass("zenario_grid_wrapper"),a.tooltips("#"+c),$("#"+c+" .zenario_grid_delete").click(function(){a.deleteCell(this)}),$("#"+c+" .zenario_grid_object_edit_properties").click(function(){a.stopRenames||a.editProperties(this)}),setTimeout(function(){delete a.stopRenames},100),a.drawLinks(),$("#"+c+" .zenario_grid_newly_added .zenario_cell_in_grid").effect({effect:"highlight",duration:1E3,easing:"zenarioOmmitEnd"}),$("#"+a.gridId).scrollTop(qa),
    +a.drawAddToolbar();else return U};a.getSlotDescription=function(c){if(c){var b=O(c.display_name);if(c.instance_id){b+=", ";switch(c.class_name){case "zenario_plugin_nest":b+="N";break;case "zenario_slideshow":case "zenario_slideshow_simple":b+="S";break;default:b+="P"}b+=(""+c.instance_id).padStart(2,"0")}else b+=" (version controlled)"}else b=va("em","class","zenario_grid_empty_slot_contents","Empty");return b};a.drawOptions=function(){var c=a.microTemplate(a.mtPrefix+"top",{formId:"settings"});
    +$(".ui-tooltip").remove();T("settings").innerHTML=c;Y._to("#settings  *[title]");a.data.fluid||a.recalcColumnAndGutterOptions(a.data);$("#settings input.zenario_grid_setting_break_1").change(a.update).spinner({stop:a.update,min:10,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_break_2").change(a.update).spinner({stop:a.update,min:300,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_min_width").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,
    +min:100,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_max_width").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:320,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_gutter_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_gutter_left_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,
    +min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_gutter_right_flu").change(a.recalcOnChange).spinner({stop:a.recalcOnInc,min:0,step:.1}).after('<span class="zenario_grid_unit">%</span>');$("#settings input.zenario_grid_setting_full_width").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,min:320,step:10}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_cols").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,
    +min:1,step:1});$("#settings input.zenario_grid_setting_gutter_left").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,min:0,step:1}).after('<span class="zenario_grid_unit">px</span>');$("#settings input.zenario_grid_setting_gutter_right").change(a.recalcOnChange).keyup(a.recalcOnKeyUp).spinner({stop:a.recalcOnInc,min:0,step:1}).after('<span class="zenario_grid_unit">px</span>');$("#settings select.zenario_grid_setting_col_and_gutter").change(a.recalcOnChange);$("#settings input.zenario_grid_setting_fixed").change(a.updateAndChange);
    +$("#settings input.zenario_grid_setting_flu").change(a.updateAndChange);$("#settings input.zenario_grid_setting_responsive").change(a.updateAndChange);$("#settings input.zenario_grid_setting_mirror").change(a.updateAndChange);a.canUndo()&&$("#settings .zenario_grid_setting_undo").click(function(){a.undo()});a.canRedo()&&$("#settings .zenario_grid_setting_redo").click(function(){a.redo()});$("#settings .zenario_grid_setting_preview_grid").click(function(){a.editing=!1;a.drawPreview()});$("#settings .zenario_grid_setting_edit_slots").click(function(){a.editing=
    +!0;a.drawEditor()})};a.recalcColumnAndGutterOptions=function(c,b,d){var e=!1,h=(d?d:1*$("#settings--setting_full_width").val())-c.gutterLeftEdge-c.gutterRightEdge;d=Math.floor(h/c.cols);var g=0,v=!1,p=0;b||(e=T("settings--setting_col_width"));if(!c.cols)return!1;if(e)for(p=e.length-1;0<=p;--p)e.remove(p);if(1==c.cols)e&&e.add(new Option(d+" px / "+g+" px",d+"/"+g),++p),v={colWidth:d,gutter:g};else{p=c.cols-1;b=h/p;h=c.cols/p;var F=999999;for(p=-1;d>g;--d)if(g=b-h*d,g=Math.round(1E4*g)/1E4,g==Math.floor(g)){e&&
    +e.add(new Option(d+" px / "+g+" px",d+"/"+g),++p);var w=Math.abs(c.gutter/c.colWidth-g/d);F>w&&(e&&(e.selectedIndex=p),F=w,v={colWidth:d,gutter:g})}}return v};a.editProperties=function(c){$(c);var b,d={},e=["zenario_grid_box","zenario_grid_rename_slot_box"];if((b=$(c).data("for"))&&(b=$("#"+b))){var h=b.data();var g=h.i;d.type=$(c).data("type");b=a.getLevels(b);var v=a.data;if(b){b=b.s("-");for(var p in b)B(b,p)&&(p*=1,v=v.cells[1*b[p]])}d.cell=h;d.data=v.cells[g];d.slot=E(d.data.name)&&a.slotContents[d.data.name];
    +$.colorbox({transition:"none",html:a.microTemplate(a.mtPrefix+"object_properties",d),height:"99%",width:580,onOpen:function(){y._aCTC(e)},onClosed:function(){y._rCTC(e)},onComplete:function(){$("#zenario_grid_slotname_button").click(function(){var F,w={},H=$("#colorbox .zenario_grid_properties_form").serializeArray();for(F in H)B(H,F)&&(w[H[F].name]=H[F].value);a.saveProperties(c,w)});$(".zenario_grid_properties_form input,textarea")[1].focus()}})}};a.ajaxURL=function(){return m+"zenario/admin/grid_maker/ajax.php"};
    +a.ajaxData=function(){return JSON.stringify(a.data)};a.ajaxSrc=function(){var c=a.ajaxData(),b=a.ajaxURL()+"?data="+ua(c);400<b.length&&(b=a.ajaxURL()+"?cdata="+y._nAA(a.ajaxURL(),{compress:1,data:c}));return b};a.drawPreview=function(){a.clearAddToolbar();a.checkData();var c=Math.max(a.desktopSmallestSize,100*Math.round(($(x).width()-a.previewPaddingLeftRight)/100)),b=Math.min(c-20,a.data.maxWidth),d=a.microTemplate(a.mtPrefix+"preview",{gridId:a.gridId,topHack:5,leftHack:10,min:100,max:c,startingValue:b});
    +$("#"+a.gridId).css("margin","auto");$(".ui-tooltip").remove();T(a.gridId).innerHTML=d;Y._to("#"+a.gridId+"  *[title]");$('<form action="'+O(a.ajaxURL())+'" method="post" target="'+a.gridId+'-iframe"><input name="data" value="'+O(a.ajaxData())+'"/></form>').appendTo("body").hide().submit().remove();$("#"+a.gridId+"-slider").slider({min:100,max:c,step:10,animate:!0,value:b,start:function(h,g){$("#"+a.gridId+"-slider_overlay").css("display","block")},stop:function(h,g){$("#"+a.gridId+"-slider_overlay").css("display",
    +"none")},slide:function(h,g){$("#"+a.gridId+"-slider_val").val(g.value);$("#"+a.gridId+"-iframe").clearQueue();$("#"+a.gridId+"-size").clearQueue();!h.originalEvent||"mousedown"!=h.originalEvent.type&&"touchstart"!=h.originalEvent.type?($("#"+a.gridId+"-iframe").width(g.value),$("#"+a.gridId+"-size").css("marginLeft",g.value+"px")):($("#"+a.gridId+"-iframe").animate({width:g.value}),$("#"+a.gridId+"-size").animate({marginLeft:g.value}));a.resizePreview()}});$("#"+a.gridId+"-slider_val").change(function(){var h=
    +1*this.value;h&&100<=h&&h<=c&&($("#"+a.gridId+"-slider").slider("value",h),$("#"+a.gridId+"-iframe").clearQueue().animate({width:h}),$("#"+a.gridId+"-size").clearQueue().animate({marginLeft:h}))});a.resizePreview();var e=function(h){$("#"+a.gridId+"-slider_val").val(h);$("#"+a.gridId+"-slider").slider("value",h);$("#"+a.gridId+"-size").clearQueue().animate({marginLeft:h});$("#"+a.gridId+"-iframe").clearQueue().animate({width:h},{complete:a.resizePreview});a.lastToast&&a.lastToast.remove();a.lastToast=
    +toastr.info(z.gridDisplayingAt.r("[[pixels]]",h))};$("#"+a.gridId+"-slider_mobile").click(function(){e(a.mobileWidth)});$("#"+a.gridId+"-slider_tablet").click(function(){e(a.tabletWidth)});$("#"+a.gridId+"-slider_desktop").click(function(){e(c)});$("#settings--tabs").removeClass("zenario_grid_tabs_slots_selected").addClass("zenario_grid_tabs_grid_selected");a.drawLinks()};a.clearAddToolbar=function(){$("#"+a.addToolbarId).hide().html("")};a.drawAddToolbar=function(){$("#"+a.addToolbarId).show().html(a.microTemplate(a.mtPrefix+
    +"add_toolbar",{}));$("#"+a.addToolbarId+" a").draggable({connectToSortable:".zenario_grids",helper:"clone",revert:"invalid"});var c=$("#"+a.addToolbarId),b=c.position();b&&E(b.top)&&E(b.left)&&c.css({right:"auto",top:b.top,left:b.left});$("#"+a.addToolbarId).draggable({cursor:"move"})};$(n).ready(function(){$("#"+a.addToolbarId).hover(function(){$(this).css("cursor","move")},function(){$(this).css("cursor","pointer")})});a.resizePreview=function(){var c,b=0;(c=T(a.gridId+"-iframe"))&&c.contentWindow&&
    +c.contentWindow.document&&c.contentWindow.document.body&&(b=$(c.contentWindow.document.body).height()||360,360>b&&(b=360),$("#"+a.gridId+"-iframe").height(b),$("#"+a.gridId+"-slider_overlay").height(b),$("#"+a.gridId+"-slider a").css("position","absolute").css("z-index",20).css("top","-"+(b+5)+"px").height(b+5).html('<span style="margin-top: '+Math.ceil((b+5)/2)+'px;"></span>'));a.lastIframeHeight=b};a.drawLinks=function(){a.checkData();var c={src:a.ajaxSrc()};a.microTemplate(a.mtPrefix+"bottom_links",
    +c);$(".ui-tooltip").remove();Y._to("#download_links  *[title]");c=$("#"+a.gridId);a.editing?c.addClass("zenario_grid_slot_view").removeClass("zenario_grid_grid_view"):(c.addClass("zenario_grid_grid_view").removeClass("zenario_grid_slot_view"),c.css({height:"auto"}),c=$("#"+a.gridId+" .zenario_grid_preview_frame"));c.height(0);c.height(Math.max(a.gridAreaSmallestHeight,$(x).height()-$("body").height()-a.bodyPadding));var b=["zenario_grid_box","zenario_grid_copy_box","zenario_grid_copy_css_box"];$("#download_links a.zenario_grid_copy_css").colorbox({onOpen:function(){y._aCTC(b)},
    +onClosed:function(){y._rCTC(b)},onComplete:function(){$("#colorbox textarea").focus()}});var d=["zenario_grid_box","zenario_grid_copy_box","zenario_grid_copy_html_box"];$("#download_links a.zenario_grid_copy_html").colorbox({onOpen:function(){y._aCTC(d)},onClosed:function(){y._rCTC(d)},onComplete:function(){$("#colorbox textarea").focus()}})};a.confirmDeleteSlot=function(c,b){y._a(m+"zenario/ajax.php?moduleClassName=zenario_common_features&method_call=handleAJAX"+y._uR({removeSlot:1,level:2,slotName:c.oName,
    +layoutId:a.layoutId})).after(function(d){Y._flBo(d,Y.phrase.gridDelete,"warning",!1,!1,!0,k,b)})};a.save=function(c){a.layoutId||(c=!0);var b;if(c){var d=["zenario_grid_box","zenario_grid_new_layout_box"];(b=y._nAA(a.ajaxURL(),{saveas:1,data:a.ajaxData(),layoutId:a.layoutId},!0))&&$.colorbox({transition:"none",html:a.microTemplate(a.mtPrefix+"save_prompt",{name:a.newLayoutName||b.oldLayoutName||""}),onOpen:function(){y._aCTC(d)},onClosed:function(){y._rCTC(d)},onComplete:function(){$("#zenario_grid_new_layout_save").click(function(){$("#zenario_grid_error").hide();
    +(b=y._nAA(a.ajaxURL(),{saveas:1,confirm:1,data:a.ajaxData(),layoutId:a.layoutId,layoutName:a.newLayoutName=T("zenario_grid_layout_name").value},!0))?b.error?$("#zenario_grid_error").html(O(b.error)).slideDown():($.colorbox.close(),a.layoutName=a.newLayoutName,a.markAsSaved(b)):$.colorbox.close()});T("zenario_grid_layout_name").focus()}})}else if(b=y._nAA(a.ajaxURL(),{save:1,data:a.ajaxData(),layoutId:a.layoutId},!0))b.success?a.markAsSaved(b,!0):(Y._flBo(b.message,z.gridSave,"warning",!0,!0),$("#zenario_fbMessageButtons .submit_selected").click(function(){setTimeout(function(){var e;
    +(e=y._nAA(a.ajaxURL(),{save:1,data:a.ajaxData(),layoutId:a.layoutId,confirm:1},!0))&&a.markAsSaved(e)},50)}))};a.saveProperties=function(c,b){var d;if((d=$(c).data("for"))&&(d=$("#"+d))){c=d.data("i");d=a.getLevels(d);var e=a.data;if(d){d=d.s("-");for(var h in d)B(d,h)&&(h*=1,e=e.cells[1*d[h]])}if(e.cells[c].slot){if(b.name){if(b.name!=b.name.r(/[^a-zA-Z0-9_]/g,"")){$("#zenario_grid_error").html(z.gridErrorNameFormat).slideDown();return}if(b.name!=e.cells[c].name&&a.checkIfNameUsed(b.name)){$("#zenario_grid_error").html(z.gridErrorNameInUse).slideDown();
    +return}}else{$("#zenario_grid_error").html(z.gridErrorNameIncomplete).slideDown();return}delete a.names[e.cells[c].name];a.registerNewName(b.name)}for(var g in b)B(b,g)&&(""!=b[g]?e.cells[c][g]=b[g]:delete e.cells[c][g]);a.change()}$.colorbox.close()};a.markAsSaved=function(c,b){a.savedAtPos=a.pos;E(c.layoutId)&&(a.layoutId=c.layoutId);a.rememberNames(a.data.cells);c.success&&(b?Y._flBo(c.success,!0,"success"):toastr.success(c.success));if(I&&I.zenarioO.init)switch(I.zenarioO.path){case "zenario__layouts/panels/layouts":c.layoutId&&
    +I.zenarioO._rTSI(c.layoutId)}};a.readSettings=function(c){c.fluid=$("#settings input.zenario_grid_setting_flu").prop("checked");c.responsive=$("#settings input.zenario_grid_setting_responsive").prop("checked");c.mirror=$("#settings input.zenario_grid_setting_mirror").prop("checked");c.cols=1*$("#settings input.zenario_grid_setting_cols").val();var b;(b=$("#settings input.zenario_grid_setting_full_width")).length?c.maxWidth=1*b.val():(b=$("#settings input.zenario_grid_setting_max_width")).length&&
    +(c.maxWidth=1*b.val());(b=$("#settings input.zenario_grid_setting_min_width")).length&&(c.minWidth=1*b.val());(b=$("#settings input.zenario_grid_setting_break_1")).length&&(c.bp1=1*b.val());(b=$("#settings input.zenario_grid_setting_break_2")).length&&(c.bp2=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_left")).length&&(c.gutterLeftEdge=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_right")).length&&(c.gutterRightEdge=1*b.val());(b=$("#settings select.zenario_grid_setting_col_and_gutter")).length&&
    +(b=b.val())&&(b=b.s("/"))&&(c.colWidth=1*b[0],c.gutter=1*b[1]);(b=$("#settings input.zenario_grid_setting_gutter_left_flu")).length&&(c.gutterLeftEdgeFlu=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_flu")).length&&(c.gutterFlu=1*b.val());(b=$("#settings input.zenario_grid_setting_gutter_right_flu")).length&&(c.gutterRightEdgeFlu=1*b.val())};a.updateAndChange=function(){a.update();a.change()};a.update=function(){a.readSettings(a.data);a.checkData()};a.recalcOnKeyUp=function(){a.recalc(this)};
    +a.recalcOnChange=function(){a.recalc(this,!0,!0)};a.recalcOnInc=function(c,b){if(c.originalEvent&&"mouseup"==c.originalEvent.type)return a.recalc(this,!0)};a.recalc=function(c,b,d){var e=$.extend(!1,{},a.data),h=!1,g=!1,v=0,p=c.className,F;e.fluid?(delete e.gutter,delete e.gutterLeftEdge,delete e.gutterRightEdge):(delete e.gutterFlu,delete e.gutterLeftEdgeFlu,delete e.gutterRightEdgeFlu);d||(h=JSON.stringify(e));a.readSettings(e);g=a.checkDataNonZeroAndNumeric(e,g);if(e.fluid)delete e.gutter,delete e.gutterLeftEdge,
    +delete e.gutterRightEdge;else{switch(p.s(" ")[0]){case "zenario_grid_setting_full_width":v=1;break;case "zenario_grid_setting_cols":v=2;break;case "zenario_grid_setting_gutter_left":v=3;break;case "zenario_grid_setting_gutter_right":v=4;break;case "zenario_grid_setting_col_and_gutter":v=5}if(v){if(d||$(c).val()!=$(c).attr("data-initial-value"))$(c).attr("data-initial-value",$(c).val());else return;do if(!e.maxWidth||1>e.cols)g=!0;else{if(e.gutterLeftEdge+e.cols+e.gutterRightEdge>e.maxWidth)if(3>v)e.gutterLeftEdge=
    +e.gutterRightEdge=0;else{g=!0;break}5>v&&(F=a.recalcColumnAndGutterOptions(e))&&(e.colWidth=F.colWidth,e.gutter=F.gutter);g=a.checkDataNonZeroAndNumeric(e,g);p=0;var w=[{l:3,c:"zenario_grid_setting_gutter_left",v:e.gutterLeftEdge},{l:4,c:"zenario_grid_setting_gutter_right",v:e.gutterRightEdge},{l:5,c:"zenario_grid_setting_col_and_gutter",v:e.colWidth+"/"+e.gutter}];for(p in w)if(B(w,p)&&v<w[p].l){var H=$("#settings ."+w[p].c);H.val()!=w[p].v&&H.animate({opacity:.3},"fast").val(w[p].v).animate({opacity:1},
    +"fast")}}while(0)}delete e.gutterFlu;delete e.gutterLeftEdgeFlu;delete e.gutterRightEdgeFlu}if(d||h!=JSON.stringify(e))$("#settings .zenario_grid_setting_warning").removeClass("zenario_grid_setting_warning"),b?g?a.revert():(a.readSettings(a.data),a.checkDataNonZeroAndNumeric(a.data),a.change(!1,!0)):g&&$(c).parent().addClass("zenario_grid_setting_warning");return!g}})},window.zenarioGM=zenario._cZL("GM"));
    
  • zenario/js/admin.js+0 1 modified
    @@ -750,7 +750,6 @@ zenarioA.getGridSlotDetails = function(slotName) {
     						}
     					
     						rules = styleSheet.rules || styleSheet.cssRules;
    -						//console.log('rules', rules);
     		
     						//middleLoop:
     						foreach (rules as ri => rule) {
    
  • zenario/js/js_minify.shell.php+1 1 modified
    @@ -35,7 +35,7 @@
     	$dirname = dirname($cwd = $argv[0] ?? $_SERVER['SCRIPT_FILENAME'] ?? '.');
     	$cwd = $cwd[0] === '/'? $dirname. '/' : getcwd(). '/'. ($dirname === '.'? '' : $dirname. '/');
     
    -	define('CMS_ROOT', dirname(dirname(dirname($cwd))). '/');
    +	define('CMS_ROOT', dirname(dirname($cwd)). '/');
     }
     
     require CMS_ROOT. 'zenario/basicheader.inc.php';
    
  • zenario/js/tidy_libs.shell.php+1 1 modified
    @@ -35,7 +35,7 @@
     	$dirname = dirname($cwd = $argv[0] ?? $_SERVER['SCRIPT_FILENAME'] ?? '.');
     	$cwd = $cwd[0] === '/'? $dirname. '/' : getcwd(). '/'. ($dirname === '.'? '' : $dirname. '/');
     
    -	define('CMS_ROOT', dirname(dirname(dirname($cwd))). '/');
    +	define('CMS_ROOT', dirname(dirname($cwd)). '/');
     }
     
     require CMS_ROOT. 'zenario/basicheader.inc.php';
    
  • zenario/libs/manually_maintained/mit/payson/account.php+0 31 removed
    @@ -1,31 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -     class Account{
    -        /** @var string $accountEmail */
    -        public $accountEmail;
    -        /** @var string $status */
    -        public $status;
    -        /** @var int $merchantId */
    -        public $merchantId;
    -        /** @var string $enabledForInvoice */
    -        public $enabledForInvoice;
    -        /** @var string $enabledForPaymentPlan */
    -        public $enabledForPaymentPlan;
    -        
    -        public function __construct($accountEmail, $status,  $merchantId,  $enabledForInvoice, $enabledForpaymentPlan){
    -            $this->accountEmail = $accountEmail;
    -            $this->status = $status;
    -            $this->merchantId = $merchantId;
    -            $this->enabledForInvoice = $enabledForInvoice;
    -            $this->enabledForpaymentPlan = $enabledForpaymentPlan;
    -        }
    -        
    -        public static function create($data) {
    -             return new Account($data->accountEmail,$data->status,$data->merchantId,$data->enabledForInvoice,$data->enabledForpaymentPlan);
    -        }
    -        
    -        public function toArray(){
    -            return get_object_vars($this);   
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/customer.php+0 45 removed
    @@ -1,45 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -     class Customer{
    -        /** @var string $city */
    -        public $city;
    -        /** @var string $countryCode */
    -        public $countryCode;
    -        /** @var int $identityNumber Date of birth YYMMDD (digits). */
    -        public $identityNumber;
    -        /** @var string $email */
    -        public $email;
    -        /** @var string $firstName */
    -        public $firstName;
    -        /** @var string $lastName */
    -        public $lastName;
    -        /** @var string $phone Phone number. */
    -        public $phone;
    -        /** @var string $postalCode Postal code. */
    -        public $postalCode;
    -        /** @var string $street Street address.*/
    -        public $street;
    -        /** @var string $type Type of customer ("business", "person" (default)).*/
    -        public $type;
    -        public function __construct($firstName = Null, $lastName = Null,  $email = Null,  $phone = Null, $identityNumber = Null, $city = Null, $countryCode = Null, $postalCode = Null, $street = Null, $type = 'person'){
    -            $this->firstName = $firstName;
    -            $this->lastName = $lastName;
    -            $this->email = $email;
    -            $this->phone = $phone;
    -            $this->identityNumber = $identityNumber;
    -            $this->city = $city; 
    -            $this->countryCode = $countryCode;
    -            $this->postalCode = $postalCode;
    -            $this->street = $street;
    -            $this->type = $type;   
    -        }
    -        
    -        public static function create($data) {
    -             return new Customer($data->firstName,$data->lastName,$data->email,$data->phone,$data->identityNumber,$data->city,$data->countryCode,$data->postalCode,$data->street,$data->type);
    -        }
    -        
    -        public function toArray(){
    -            return get_object_vars($this);   
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/gui.php+0 33 removed
    @@ -1,33 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -    class Gui{
    -        /** @var string $colorScheme Color scheme of the checkout snippet("white", "black", "blue" (default), "red"). */
    -        public $colorScheme;
    -        /** @var string $locale Used to change the language shown in the checkout snippet ("se", "fi", "en" (default)). */
    -        public $locale;
    -        /** @var string $verification  Can be used to add extra customer verfication ("bankid", "none" (default)). */
    -        public $verification;
    -        /** @var bool $requestPhone  Can be used to require the user to fill in his phone number. */
    -        public $requestPhone;
    -        /** @var list $countries  List of countries shown in the checkout snippet. */
    -        public $countries = array();
    -        /** @var bool $phoneOptional  Can be used to ask the user to fill in his phone number, but not strict required. */
    -        public $phoneOptional;
    -        
    -        public function __construct($locale = "sv", $colorScheme = "gray", $verification = 0, $requestPhone = NULL, $countries = NULL, $phoneOptional = NULL){
    -            $this->colorScheme = $colorScheme;
    -            $this->locale = $locale; 
    -            $this->verification = $verification;
    -            $this->requestPhone = $requestPhone;
    -            $this->countries = $countries;
    -            $this->phoneOptional = $phoneOptional;
    -        }
    -        public static function create($data) {
    -            return new Gui($data->locale, $data->colorScheme, $data->verification, $data->requestPhone, $data->countries, $data->phoneOptional);
    -        }
    -        
    -        public function toArray(){
    -            return get_object_vars($this);      
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/orderitem.php+0 83 removed
    @@ -1,83 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -    
    -    abstract class OrderItemType
    -    {
    -        const PHYSICAL = 'physical';
    -        const DISCOUNT = 'discount';
    -        const SERVICE  = 'service';
    -        const FEE      = 'fee';
    -    }
    -    
    -    class OrderItem {
    -        
    -        /** @var string $id */
    -        public $itemId;
    -        /** @var float $discountRate Discount rate of the article (Decimal number (0.00-1.00)). */
    -        public $discountRate;
    -        /** @var float $creditedAmount Credited amount (Decimal number (with two decimals)). */
    -        public $creditedAmount;
    -        /** @var url $imageUri An URI to an image of the article. */
    -        public $imageUri;
    -        /** @var string $name Name of the article. */
    -        public $name;
    -        /** @var float $unitPrice Unit price of the article (including tax). */
    -        public $unitPrice ;
    -        /** @var int $quantity  Quantity of the article. */
    -        public $quantity;
    -        /** @var float taxRate Tax rate of the article (0.00-1.00). */
    -        public $taxRate;
    -        /** @var string $reference Article reference, usually the article number. */
    -        public $reference;
    -        /** @var string $type Type of article ("Fee", "Physical" (default), "Service"). */
    -        public $type;
    -        /** @var url $uri URI to a the article page of the order item. */
    -        public $uri;
    -        /** @var ean $ean European Article Number. Discrete number (13 digits) */
    -        public $ean;
    - 
    -        /**
    -        * Constructs an OrderItem object
    -        * 
    -        * If any other value than description is provided all of them has to be entered
    -        * 
    -        * @param string $name Name of order item. Max 128 characters
    -        * @param float $unitPrice Unit price incl. VAT
    -        * @param int $quantity  Quantity of this item. Can have at most 2 decimal places
    -        * @param float $taxRate Tax value. Not actual percentage. For example, 25% has to be entered as 0.25
    -        * @param string $reference Sku of item
    -        */
    -        public function __construct($name, $unitPrice, $quantity, $taxRate, $reference, $type=OrderItemType::PHYSICAL, $discountRate=null, $ean = null, $uri=null, $imageUri=null) {
    -            // Mandatory 
    -            $this->name = $name;
    -            $this->unitPrice = $unitPrice;
    -            $this->quantity = $quantity;
    -            $this->taxRate = $taxRate;
    -            $this->type = $type;
    -            $this->reference = $reference;
    -            
    -			if(!$name || is_null($unitPrice) || !$quantity || is_null($taxRate) || !$type || !$reference) {
    -                throw new PaysonApiException("Not all of mandatory fields are set for creating of an OrderItem object");
    -            }
    -            
    -            // Optional
    -            $this->discountRate = $discountRate;
    -            $this->ean = $ean;
    -            $this->uri = $uri;
    -            $this->imageUri = $imageUri;
    -        }
    -        public static function create($data) {
    -            $item = new OrderItem($data->name, $data->unitPrice, $data->quantity, $data->taxRate, $data->reference, $data->type, isset($data->discountRate)?$data->discountRate:null, isset($data->ean)?$data->ean:null, isset($data->uri)?$data->uri:null, isset($data->imageUri)?$data->imageUri:null);
    -            $item->discountRate=$data->discountRate;
    -            $item->creditedAmount=$data->creditedAmount;
    -            if(isset($data->itemId)) {
    -                $item->itemId = $data->itemId;
    -            }
    -            return $item;
    -        }
    -        
    -        public function toArray() {
    -            return get_object_vars($this);   
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/paydata.php+0 61 removed
    @@ -1,61 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -    require_once "orderitem.php";
    -    abstract class CurrencyCode {
    -        const SEK = "SEK";
    -        const EUR = "EUR";
    -    }
    -    
    -    class PayData {
    -        /** @var string $currency Currency of the order ("sek", "eur"). */
    -        public $currency = NULL;
    -        /** @var array $items An array with objects of the order items*/
    -        public $items = array();
    -        
    -        /** @var float $totalPriceExcludingTax - Read only */
    -        public $totalPriceExcludingTax;
    -        /** @var float $totalPriceIncludingTax - Read only */
    -        public $totalPriceIncludingTax;
    -        /** @var float $totalTaxAmount - Read only */
    -        public $totalTaxAmount;
    -        /** @var float $totalCreditedAmount - Read only */
    -        public $totalCreditedAmount;
    -        public function __construct($currencyCode) {
    -            $this->currency = $currencyCode;
    -            $this->items = array();
    -        }
    -        
    -        public static function create($data) {
    -            $payData = new PayData($data->currency);
    -            $payData->totalPriceExcludingTax = $data->totalPriceExcludingTax;
    -            $payData->totalPriceIncludingTax = $data->totalPriceIncludingTax;
    -            $payData->totalTaxAmount = $data->totalTaxAmount;
    -            $payData->totalCreditedAmount =$data->totalCreditedAmount;
    -            
    -            foreach($data->items as $item) {
    -                $payData->items[] = OrderItem::create($item);
    -            }
    -            
    -            return $payData;
    -        }
    -        
    -        public function AddOrderItem(OrderItem $item) {
    -            $this->items[] = $item;
    -        }
    -     
    -        public function setOrderItems($items) { 
    -            if(!($items instanceof OrderItem))
    -                throw new PaysonApiException("Parameter must be an object of class Item");
    -            $this->items = $items;
    -        }
    -        public function toArray(){
    -            $items = array();
    -            foreach($this->items as $item) { $items[] = $item->toArray();  }
    -            return array( 'currency'=>$this->currency, 'items'=>$items );
    -        }
    -        
    -        public function toJson(){
    -            return json_encode($this->toArray());
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/paysonapierror.php+0 14 removed
    @@ -1,14 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -    class PaysonApiError {
    -        public $message = NULL;
    -        public $parameter = NULL;
    -        public function __construct($message, $parameter = null) {
    -            $this->message = $message;
    -            $this->parameter = $parameter;
    -        }
    -        public function __toString() {
    -            return "Message: " . $this->message . "\t Parameter: " . $this->parameter;
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/payson/paysonapiexception.php+0 30 removed
    @@ -1,30 +0,0 @@
    -<?php
    -namespace PaysonEmbedded{
    -    class PaysonApiException extends \Exception {
    -        private $errors = array();
    -        
    -        public function getErrorList() {
    -            return $this->errors;
    -        }
    -        
    -        public function getErrors() {
    -            $r = '';
    -            if(count($this->errors)) {
    -                foreach ($this->errors as $error){
    -                    $r.='<pre>'.$error->message . ($error->parameter?'  --  Parameter: ' .$error->parameter:'').'</pre>';    
    -                }
    -            } else {
    -                $r .= $this->getMessage();
    -            }
    -            return $r;
    -        }
    -    
    -        public function __construct($message,array $errors = array()) {
    -            $this->errors = $errors;
    -            if(count($errors)) {
    -                $message .="\n\n"; foreach($errors as $error) { $message .= "\n".$error."\n"; } $message .="\n\n";
    -            }
    -            parent::__construct($message);
    -        }
    -    }
    -}
    
  • zenario/libs/manually_maintained/mit/payson/paysonapi.php+0 164 removed
    @@ -1,164 +0,0 @@
    -<?php
    -namespace PaysonEmbedded {
    -    require_once "paysonapiexception.php";
    -    require_once "paysonapierror.php";
    -    require_once "paydata.php";
    -    require_once "paysonmerchant.php";
    -    require_once "customer.php";
    -    require_once "gui.php";
    -    require_once "paysoncheckout.php";
    -    require_once "account.php";
    -    
    -}
    -namespace PaysonEmbedded {
    -    class PaysonApi {
    -        private $merchantId;
    -        private $apiKey;
    -        private $protocol = "https://%s";
    -        const PAYSON_HOST = "api.payson.se/2.0/";
    -        const ACTION_CHECKOUTS = "Checkouts/";
    -        const ACTION_ACCOUNTS = "Accounts/";
    -        private $paysonMerchant = null;
    -        private $payData = null;
    -        private $customer = null;
    -        private $allOrderData = array();
    -        private $gui = null;
    -        private $useTestEnvironment = null;
    -        private $checkoutId = null;
    -        private $paysonResponse = null;
    -        public $paysonResponseErrors = array();
    -        public function __construct($merchantId, $apiKey, $useTestEnvironment = false) {
    -            $this->useTestEnvironment = $useTestEnvironment;
    -            $this->merchantId = $merchantId;
    -            $this->apiKey = $apiKey;
    -            
    -            if (!function_exists('curl_exec')) {
    -                throw new PaysonApiException('Curl not installed. Is required for PaysonApi.');
    -            }
    -        }
    -        public function getMerchantId() {
    -            return $this->merchantId;
    -        }
    -        public function getApiKey() {
    -            return $this->apiKey;
    -        }
    -        public function CreateCheckout(Checkout $checkout) {
    -            $result = $this->doCurlRequest('POST', $this->getUrl(self::ACTION_CHECKOUTS), $checkout->toArray());
    -            $checkoutId = $this->extractCheckoutId($result);
    -            if(!$checkoutId) {
    -                throw new PaysonApiException("Checkout Id not received of unclear reason");
    -            }
    -            return $checkoutId;
    -        }
    -        
    -        public function CreateGetCheckout(Checkout $checkout) {
    -            $result = $this->doCurlRequest('POST', $this->getUrl(self::ACTION_CHECKOUTS), $checkout->toArray(), true);
    -            $newCheckout = Checkout::create(json_decode($result));
    -            if(!$newCheckout->id) {
    -                throw new PaysonApiException("Checkout ID not received of unclear reason");
    -            }
    -            return $newCheckout;
    -        }
    -        
    -        public function UpdateCheckout($checkout) {
    -            if(!$checkout->id) {
    -                throw new PaysonApiException("Checkout object which should be updated must have id property set");
    -            }
    -            $result = $this->doCurlRequest('PUT', $this->getUrl(self::ACTION_CHECKOUTS).$checkout->id, $checkout->toArray());
    -            return $checkout;
    -        }
    -        
    -        public function GetCheckout($checkoutId) {
    -            $result = $this->doCurlRequest('GET', $this->getUrl(self::ACTION_CHECKOUTS).$checkoutId, null);
    -            return Checkout::create(json_decode($result));
    -        }
    -        
    -        public function ShipCheckout(Checkout $checkout) {
    -            $checkout->status = 'shipped';
    -            return $this->UpdateCheckout($checkout);
    -        }
    -        
    -        public function CancelCheckout(Checkout $checkout) {
    -            $checkout->status = 'canceled';
    -            return $this->UpdateCheckout($checkout);
    -        }
    -        
    -        public function Validate() {
    -            $result = $this->doCurlRequest('GET', $this->getUrl(self::ACTION_ACCOUNTS), null);
    -            return Account::create(json_decode($result));
    -        }
    -        private function doCurlRequest($method, $url, $postfields, $returnBody = false) {
    -            $ch = curl_init($url);
    -            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->authorizationHeader());
    -            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    -            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    -            curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields?json_encode($postfields):null);
    -            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    -            curl_setopt($ch, CURLOPT_HEADER, true);
    -            $result = curl_exec($ch);
    -            $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    -            $body = substr($result, $header_size);
    -            $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    -            curl_close($ch);
    -            
    -            /* This class of status codes indicates the action requested by the client was received, understood, accepted and processed successfully
    -             * 200 OK
    -             * 201 Created
    -             * 202 Accepted
    -             * 203 Non-Authoritative Information (since HTTP/1.1)
    -             */
    -            if ($response_code == 200) {
    -                return $body;
    -            } elseif ($response_code == 201) {
    -                if ($returnBody == true) {
    -                    return $body;
    -                }
    -                return $result;
    -            } elseif ($result == false) {
    -                throw new PaysonApiException('Curl error: '.curl_error($ch));
    -            } else {
    -                $errors = array();
    -                
    -                $data = json_decode($body,true);
    -                $errors[] = new PaysonApiError('HTTP status code: ' . $response_code.', '.$data['message'], null);
    -                
    -                if(isset($data['errors']) && count($data['errors'])) {
    -                    $errors = array_merge($errors, $this->parseErrors($data['errors'], $response_code));    
    -                }
    -                
    -                throw new PaysonApiException("Api errors", $errors);
    -            }
    -            
    -        }
    -        
    -        private function authorizationHeader() {
    -            $header = array();
    -            $header[] = 'Content-Type: application/json';
    -            $header[] = 'Authorization: Basic ' . base64_encode($this->merchantId . ':' . $this->apiKey);
    -            return $header;
    -        }
    -        private function extractCheckoutId($result) {
    -            $checkoutId = null;
    -            if (preg_match('#Location: (.*)#', $result, $res)) {
    -                $checkoutId = trim($res[1]);
    -            }
    -            $checkoutId = explode('/', $checkoutId);
    -            $checkoutId = $checkoutId[count($checkoutId) - 1];
    -            return $checkoutId;
    -        }
    -        private function parseErrors($responseErrors, $response_code) {
    -            $errors = array();
    -            foreach ($responseErrors as $error) {
    -                $errors[] = new PaysonApiError($error['message'], (isset($error['property'])?$error['property']:null));
    -            }
    -            return $errors;
    -        }
    -        public function setStatus($status) {
    -            $this->allOrderData['status'] = $status;
    -        }
    -        
    -        private function getUrl($action) {
    -            return (sprintf($this->protocol, ($this->useTestEnvironment ? 'test-' : '')) . self::PAYSON_HOST.$action);
    -        }
    -    }
    -}
    
  • zenario/libs/manually_maintained/mit/payson/paysoncheckout.php+0 67 removed
    @@ -1,67 +0,0 @@
    -<?php
    -namespace PaysonEmbedded {
    -    class Checkout {
    -        /** @var Merchant $merchant */
    -        public $merchant;
    -        
    -        /** @var PayData $order */
    -        public $payData;
    -        
    -        /** @var Gui $gui */
    -        public $gui;
    -        
    -        /** @var Customer $customer */
    -        public $customer;
    -       
    -       /** @var string $status */
    -        public $status;
    -        
    -        /** @var string $id */
    -        public $id;
    -        
    -        /** @var int $purchaseId */
    -        public $purchaseId;
    -        
    -        /** @var string $snippet */
    -        public $snippet;
    -        
    -        /** @var string $description */
    -        public $description;
    -       
    -        public function __construct(Merchant $merchant, PayData $payData,  Gui $gui = null,  Customer $customer = null, $description = '') {
    -            $this->merchant = $merchant;
    -            $this->payData = $payData;
    -            $this->gui = $gui?:new Gui();
    -            $this->customer = $customer?:new Customer();
    -            $this->purchaseId = null;
    -            $this->description = $description;
    -        }
    -        
    -        public static function create($data) {
    -            $checkout = new Checkout(Merchant::create($data->merchant), PayData::create($data->order), Gui::create($data->gui), Customer::create($data->customer));
    -            $checkout->status = $data->status;
    -            $checkout->id = $data->id;
    -            $checkout->snippet = $data->snippet;
    -            if(isset($data->purchaseId)) {
    -                $checkout->purchaseId = $data->purchaseId;
    -            }
    -            
    -            if(isset($data->description)) {
    -                $checkout->description = $data->description;
    -            }
    -            return $checkout;
    -        }
    -      
    -        public function toArray() {
    -            return array(
    -                'id' => $this->id,
    -                'description' => $this->description,
    -                'status' => $this->status,
    -                'merchant' => $this->merchant->toArray(),
    -                'order' => $this->payData->toArray(),
    -                'gui' => $this->gui->toArray(),
    -                'customer' => $this->customer->toArray()
    -            );
    -        }
    -    }
    -}
    
  • zenario/libs/manually_maintained/mit/payson/paysonmerchant.php+0 40 removed
    @@ -1,40 +0,0 @@
    -<?php
    -namespace PaysonEmbedded {
    -    class Merchant {
    -        /** @var url $checkoutUri URI to the merchants checkout page.*/
    -        public $checkoutUri = NULL;
    -        /** @var url $confirmationUri URI to the merchants confirmation page. */
    -        public $confirmationUri;
    -        /** @var url $notificationUri Notification URI which receives CPR-status updates. */
    -        public $notificationUri;
    -        /** @var url $verificationUri Validation URI which is called to verify an order before it can be paid. */
    -        public $validationUri = NULL;
    -        /** @var url $termsUri URI leading to the sellers terms. */
    -        public $termsUri;
    -        /** @var string $reference Merchants own reference of the checkout.*/
    -        public $reference = NULL;
    -        /** @var string $partnerId Partners unique identifier */
    -        public $partnerId = NULL;
    -        /** @var string $integrationInfo Information about the integration. */
    -        public $integrationInfo = NULL;
    -        public function __construct($checkoutUri, $confirmationUri, $notificationUri, $termsUri, $partnerId = NULL, $integrationInfo = 'PaysonCheckout2.0|1.0|NONE') {
    -            $this->checkoutUri = $checkoutUri;
    -            $this->confirmationUri = $confirmationUri;
    -            $this->notificationUri = $notificationUri;
    -            $this->termsUri = $termsUri;
    -            $this->partnerId = $partnerId;
    -            $this->integrationInfo = $integrationInfo;
    -        }
    -        
    -        public static function create($data) {
    -            $merchant =  new Merchant($data->checkoutUri,$data->confirmationUri,$data->notificationUri,$data->termsUri, $data->partnerId, $data->integrationInfo);
    -            $merchant->reference=$data->reference;
    -            $merchant->validationUri=$data->validationUri;
    -            return $merchant;
    -        }
    -     
    -        public function toArray(){
    -            return get_object_vars($this);      
    -        }
    -    }
    -}
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/phpmqtt/composer.json+0 21 removed
    @@ -1,21 +0,0 @@
    -{
    -    "name": "bluerhinos/phpmqtt",
    -    "description": "Simple MQTT Class",
    -    "license": "BSD",
    -    "type": "library",
    -    "authors": [
    -        {
    -            "name": "Andrew Milsted",
    -            "email": "andrew@bluerhinos.co.uk"
    -        }
    -    ],
    -    "minimum-stability": "dev",
    -    "require": {
    -        "php": ">=7.2"
    -    },
    -    "autoload": {
    -        "psr-4": {
    -            "Bluerhinos\\": "./"
    -        }
    -    }
    -}
    
  • zenario/libs/manually_maintained/mit/phpmqtt/examples/publish.php+0 18 removed
    @@ -1,18 +0,0 @@
    -<?php
    -
    -require('../phpMQTT.php');
    -
    -$server = 'localhost';     // change if necessary
    -$port = 1883;                     // change if necessary
    -$username = '';                   // set your username
    -$password = '';                   // set your password
    -$client_id = 'phpMQTT-publisher'; // make sure this is unique for connecting to sever - you could use uniqid()
    -
    -$mqtt = new Bluerhinos\phpMQTT($server, $port, $client_id);
    -
    -if ($mqtt->connect(true, NULL, $username, $password)) {
    -	$mqtt->publish('bluerhinos/phpMQTT/examples/publishtest', 'Hello World! at ' . date('r'), 0, false);
    -	$mqtt->close();
    -} else {
    -    echo "Time out!\n";
    -}
    
  • zenario/libs/manually_maintained/mit/phpmqtt/examples/README.md+0 44 removed
    @@ -1,44 +0,0 @@
    -# Output example
    
    -
    
    -For info on MQTT: https://mntolia.com/fundamentals-mqtt/#4_Advantages_of_MQTT_for_IoT_over_HTTP_UDP
    
    -
    
    -> Before running each file be sure to review the four connection parameters in the headers.
    
    -
    
    -subscribe.php
    
    ---
    
    -This example is to demonstrate using MQTT for a long-running script that will wait for subscribed topics.
    
    -This script is not suitable to be run as web requests, instead should be run on the commandline.
    
    -
    
    -Let `subscribe.php` listening the broker: 
    
    -```console
    
    -$ php subscribe.php 
    
    -Msg Recieved: Fri, 13 Jan 2017 01:58:23 +0000
    
    -Topic: bluerhinos/phpMQTT/examples/publishtest
    
    -
    
    -	Hello World! at Fri, 13 Jan 2017 01:58:23 +0000
    
    -
    
    -Msg Recieved: Fri, 13 Jan 2017 01:58:35 +0000
    
    -Topic: bluerhinos/phpMQTT/examples/publishtest
    
    -
    
    -	Hello World! at Fri, 13 Jan 2017 01:58:35 +0000
    
    -
    
    -^C
    
    -```
    
    -
    
    -publish.php
    
    ----
    
    -This example will publish a message to a topic.
    
    -
    
    -The results shown above corresponds to publisher's two actions:
    
    -```console
    
    -$ php publish.php
    
    -$ php publish.php
    
    -```
    
    -
    
    -When run as a web request you it is ok to just `$mqtt->connect()`, `$mqtt->publish()` and `$mqtt->close()`.
    
    -If it is being run as long-running command line script you should run `$mqtt->proc()` regularly in order maintain the connection with the broker.
    
    - 
    
    -subscribeAndWaitForMessage.php
    
    ---
    
    -In order to use this library to display messages on a website you can use `$mqtt->subscribeAndWaitForMessage()`, this will subscribe to a topic and then wait for, and return the message.
    
    -If you want messages to appear instantly, you should use retained messages (https://mntolia.com/mqtt-retained-messages-explained-example/)  
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/phpmqtt/examples/subscribeAndWaitForMessage.php+0 18 removed
    @@ -1,18 +0,0 @@
    -<?php
    -
    -require('../phpMQTT.php');
    -
    -$server = 'localhost';     // change if necessary
    -$port = 1883;                     // change if necessary
    -$username = '';                   // set your username
    -$password = '';                   // set your password
    -$client_id = 'phpMQTT-subscribe-msg'; // make sure this is unique for connecting to sever - you could use uniqid()
    -
    -$mqtt = new Bluerhinos\phpMQTT($server, $port, $client_id);
    -if(!$mqtt->connect(true, NULL, $username, $password)) {
    -	exit(1);
    -}
    -
    -echo $mqtt->subscribeAndWaitForMessage('bluerhinos/phpMQTT/examples/publishtest', 0);
    -
    -$mqtt->close();
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/phpmqtt/examples/subscribe.php+0 32 removed
    @@ -1,32 +0,0 @@
    -<?php
    -
    -require('../phpMQTT.php');
    -
    -
    -$server = 'localhost';     // change if necessary
    -$port = 1883;                     // change if necessary
    -$username = '';                   // set your username
    -$password = '';                   // set your password
    -$client_id = 'phpMQTT-subscriber'; // make sure this is unique for connecting to sever - you could use uniqid()
    -
    -$mqtt = new Bluerhinos\phpMQTT($server, $port, $client_id);
    -if(!$mqtt->connect(true, NULL, $username, $password)) {
    -	exit(1);
    -}
    -
    -$mqtt->debug = true;
    -
    -$topics['bluerhinos/phpMQTT/examples/publishtest'] = array('qos' => 0, 'function' => 'procMsg');
    -$mqtt->subscribe($topics, 0);
    -
    -while($mqtt->proc()) {
    -
    -}
    -
    -$mqtt->close();
    -
    -function procMsg($topic, $msg){
    -		echo 'Msg Recieved: ' . date('r') . "\n";
    -		echo "Topic: {$topic}\n\n";
    -		echo "\t$msg\n\n";
    -}
    
  • zenario/libs/manually_maintained/mit/phpmqtt/.gitignore+0 2 removed
    @@ -1,2 +0,0 @@
    -/vendor/
    -.idea
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/phpmqtt/LICENSE+0 20 removed
    @@ -1,20 +0,0 @@
    -Copyright (c) 2010 Blue Rhinos Consulting | Andrew Milsted
    -andrew@bluerhinos.co.uk | http://www.bluerhinos.co.uk
    -
    -Permission is hereby granted, free of charge, to any person obtaining a copy
    -of this software and associated documentation files (the "Software"), to deal
    -in the Software without restriction, including without limitation the rights
    -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    -copies of the Software, and to permit persons to whom the Software is
    -furnished to do so, subject to the following conditions:
    -
    -The above copyright notice and this permission notice shall be included in
    -all copies or substantial portions of the Software.
    -
    -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    -THE SOFTWARE.
    \ No newline at end of file
    
  • zenario/libs/manually_maintained/mit/phpmqtt/phpMQTT.php+0 669 removed
    @@ -1,669 +0,0 @@
    -<?php
    -
    -namespace Bluerhinos;
    -
    -/*
    - 	phpMQTT
    -	A simple php class to connect/publish/subscribe to an MQTT broker
    -
    -*/
    -
    -/*
    -	Licence
    -
    -	Copyright (c) 2010 Blue Rhinos Consulting | Andrew Milsted
    -	andrew@bluerhinos.co.uk | http://www.bluerhinos.co.uk
    -
    -	Permission is hereby granted, free of charge, to any person obtaining a copy
    -	of this software and associated documentation files (the "Software"), to deal
    -	in the Software without restriction, including without limitation the rights
    -	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    -	copies of the Software, and to permit persons to whom the Software is
    -	furnished to do so, subject to the following conditions:
    -
    -	The above copyright notice and this permission notice shall be included in
    -	all copies or substantial portions of the Software.
    -
    -	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    -	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    -	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    -	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    -	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    -	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    -	THE SOFTWARE.
    -	
    -*/
    -
    -/* phpMQTT */
    -
    -class phpMQTT
    -{
    -    protected $socket;            /* holds the socket	*/
    -    protected $msgid = 1;            /* counter for message id */
    -    public $keepalive = 10;        /* default keepalive timmer */
    -    public $timesinceping;        /* host unix time, used to detect disconects */
    -    public $topics = [];    /* used to store currently subscribed topics */
    -    public $debug = false;        /* should output debug messages */
    -    public $address;            /* broker address */
    -    public $port;                /* broker port */
    -    public $clientid;            /* client id sent to brocker */
    -    public $will;                /* stores the will of the client */
    -    protected $username;            /* stores username */
    -    protected $password;            /* stores password */
    -
    -    public $cafile;
    -    protected static $known_commands = [
    -        1 => 'CONNECT',
    -        2 => 'CONNACK',
    -        3 => 'PUBLISH',
    -        4 => 'PUBACK',
    -        5 => 'PUBREC',
    -        6 => 'PUBREL',
    -        7 => 'PUBCOMP',
    -        8 => 'SUBSCRIBE',
    -        9 => 'SUBACK',
    -        10 => 'UNSUBSCRIBE',
    -        11 => 'UNSUBACK',
    -        12 => 'PINGREQ',
    -        13 => 'PINGRESP',
    -        14 => 'DISCONNECT'
    -    ];
    -
    -    /**
    -     * phpMQTT constructor.
    -     *
    -     * @param $address
    -     * @param $port
    -     * @param $clientid
    -     * @param null $cafile
    -     */
    -    public function __construct($address, $port, $clientid, $cafile = null)
    -    {
    -        $this->broker($address, $port, $clientid, $cafile);
    -    }
    -
    -    /**
    -     * Sets the broker details
    -     *
    -     * @param $address
    -     * @param $port
    -     * @param $clientid
    -     * @param null $cafile
    -     */
    -    public function broker($address, $port, $clientid, $cafile = null): void
    -    {
    -        $this->address = $address;
    -        $this->port = $port;
    -        $this->clientid = $clientid;
    -        $this->cafile = $cafile;
    -    }
    -
    -    /**
    -     * Will try and connect, if fails it will sleep 10s and try again, this will enable the script to recover from a network outage
    -     *
    -     * @param bool $clean - should the client send a clean session flag
    -     * @param null $will
    -     * @param null $username
    -     * @param null $password
    -     *
    -     * @return bool
    -     */
    -    public function connect_auto($clean = true, $will = null, $username = null, $password = null): bool
    -    {
    -        while ($this->connect($clean, $will, $username, $password) === false) {
    -            sleep(10);
    -        }
    -        return true;
    -    }
    -
    -    /**
    -     * @param bool $clean - should the client send a clean session flag
    -     * @param null $will
    -     * @param null $username
    -     * @param null $password
    -     *
    -     * @return bool
    -     */
    -    public function connect($clean = true, $will = null, $username = null, $password = null): bool
    -    {
    -        if ($will) {
    -            $this->will = $will;
    -        }
    -        if ($username) {
    -            $this->username = $username;
    -        }
    -        if ($password) {
    -            $this->password = $password;
    -        }
    -
    -        if ($this->cafile) {
    -            $socketContext = stream_context_create(
    -                [
    -                    'ssl' => [
    -                        'verify_peer_name' => true,
    -                        'cafile' => $this->cafile
    -                    ]
    -                ]
    -            );
    -            $this->socket = stream_socket_client('tls://' . $this->address . ':' . $this->port, $errno, $errstr, 60, STREAM_CLIENT_CONNECT, $socketContext);
    -        } else {
    -            $this->socket = stream_socket_client('tcp://' . $this->address . ':' . $this->port, $errno, $errstr, 60, STREAM_CLIENT_CONNECT);
    -        }
    -
    -        if (!$this->socket) {
    -            $this->_errorMessage("stream_socket_create() $errno, $errstr");
    -            return false;
    -        }
    -
    -        stream_set_timeout($this->socket, 5);
    -        stream_set_blocking($this->socket, 0);
    -
    -        $i = 0;
    -        $buffer = '';
    -
    -        $buffer .= chr(0x00);
    -        $i++; // Length MSB
    -        $buffer .= chr(0x04);
    -        $i++; // Length LSB
    -        $buffer .= chr(0x4d);
    -        $i++; // M
    -        $buffer .= chr(0x51);
    -        $i++; // Q
    -        $buffer .= chr(0x54);
    -        $i++; // T
    -        $buffer .= chr(0x54);
    -        $i++; // T
    -        $buffer .= chr(0x04);
    -        $i++; // // Protocol Level
    -
    -        //No Will
    -        $var = 0;
    -        if ($clean) {
    -            $var += 2;
    -        }
    -
    -        //Add will info to header
    -        if ($this->will !== null) {
    -            $var += 4; // Set will flag
    -            $var += ($this->will['qos'] << 3); //Set will qos
    -            if ($this->will['retain']) {
    -                $var += 32;
    -            } //Set will retain
    -        }
    -
    -        if ($this->username !== null) {
    -            $var += 128;
    -        }    //Add username to header
    -        if ($this->password !== null) {
    -            $var += 64;
    -        }    //Add password to header
    -
    -        $buffer .= chr($var);
    -        $i++;
    -
    -        //Keep alive
    -        $buffer .= chr($this->keepalive >> 8);
    -        $i++;
    -        $buffer .= chr($this->keepalive & 0xff);
    -        $i++;
    -
    -        $buffer .= $this->strwritestring($this->clientid, $i);
    -
    -        //Adding will to payload
    -        if ($this->will !== null) {
    -            $buffer .= $this->strwritestring($this->will['topic'], $i);
    -            $buffer .= $this->strwritestring($this->will['content'], $i);
    -        }
    -
    -        if ($this->username !== null) {
    -            $buffer .= $this->strwritestring($this->username, $i);
    -        }
    -        if ($this->password !== null) {
    -            $buffer .= $this->strwritestring($this->password, $i);
    -        }
    -
    -        $head = chr(0x10);
    -
    -        while ($i > 0) {
    -            $encodedByte = $i % 128;
    -            $i /= 128;
    -            $i = (int)$i;
    -            if ($i > 0) {
    -                $encodedByte |= 128;
    -            }
    -            $head .= chr($encodedByte);
    -        }
    -
    -        fwrite($this->socket, $head, 2);
    -        fwrite($this->socket, $buffer);
    -
    -        $string = $this->read(4);
    -
    -        if (ord($string[0]) >> 4 === 2 && $string[3] === chr(0)) {
    -            $this->_debugMessage('Connected to Broker');
    -        } else {
    -            $this->_errorMessage(
    -                sprintf(
    -                    "Connection failed! (Error: 0x%02x 0x%02x)\n",
    -                    ord($string[0]),
    -                    ord($string[3])
    -                )
    -            );
    -            return false;
    -        }
    -
    -        $this->timesinceping = time();
    -
    -        return true;
    -    }
    -
    -    /**
    -     * Reads in so many bytes
    -     *
    -     * @param int $int
    -     * @param bool $nb
    -     *
    -     * @return false|string
    -     */
    -    public function read($int = 8192, $nb = false)
    -    {
    -        $string = '';
    -        $togo = $int;
    -
    -        if ($nb) {
    -            return fread($this->socket, $togo);
    -        }
    -
    -        while (!feof($this->socket) && $togo > 0) {
    -            $fread = fread($this->socket, $togo);
    -            $string .= $fread;
    -            $togo = $int - strlen($string);
    -        }
    -
    -        return $string;
    -    }
    -
    -    /**
    -     * Subscribes to a topic, wait for message and return it
    -     *
    -     * @param $topic
    -     * @param $qos
    -     *
    -     * @return string
    -     */
    -    public function subscribeAndWaitForMessage($topic, $qos): string
    -    {
    -        $this->subscribe(
    -            [
    -                $topic => [
    -                    'qos' => $qos,
    -                    'function' => '__direct_return_message__'
    -                ]
    -            ]
    -        );
    -
    -        do {
    -            $return = $this->proc();
    -        } while ($return === true);
    -
    -        return $return;
    -    }
    -
    -    /**
    -     * subscribes to topics
    -     *
    -     * @param $topics
    -     * @param int $qos
    -     */
    -    public function subscribe($topics, $qos = 0): void
    -    {
    -        $i = 0;
    -        $buffer = '';
    -        $id = $this->msgid;
    -        $buffer .= chr($id >> 8);
    -        $i++;
    -        $buffer .= chr($id % 256);
    -        $i++;
    -
    -        foreach ($topics as $key => $topic) {
    -            $buffer .= $this->strwritestring($key, $i);
    -            $buffer .= chr($topic['qos']);
    -            $i++;
    -            $this->topics[$key] = $topic;
    -        }
    -
    -        $cmd = 0x82;
    -        //$qos
    -        $cmd += ($qos << 1);
    -
    -        $head = chr($cmd);
    -        $head .= $this->setmsglength($i);
    -        fwrite($this->socket, $head, strlen($head));
    -
    -        $this->_fwrite($buffer);
    -        $string = $this->read(2);
    -
    -        $bytes = ord(substr($string, 1, 1));
    -        $this->read($bytes);
    -    }
    -
    -    /**
    -     * Sends a keep alive ping
    -     */
    -    public function ping(): void
    -    {
    -        $head = chr(0xc0);
    -        $head .= chr(0x00);
    -        fwrite($this->socket, $head, 2);
    -        $this->timesinceping = time();
    -        $this->_debugMessage('ping sent');
    -    }
    -
    -    /**
    -     *  sends a proper disconnect cmd
    -     */
    -    public function disconnect(): void
    -    {
    -        $head = ' ';
    -        $head[0] = chr(0xe0);
    -        $head[1] = chr(0x00);
    -        fwrite($this->socket, $head, 2);
    -    }
    -
    -    /**
    -     * Sends a proper disconnect, then closes the socket
    -     */
    -    public function close(): void
    -    {
    -        $this->disconnect();
    -        stream_socket_shutdown($this->socket, STREAM_SHUT_WR);
    -    }
    -
    -    /**
    -     * Publishes $content on a $topic
    -     *
    -     * @param $topic
    -     * @param $content
    -     * @param int $qos
    -     * @param bool $retain
    -     */
    -    public function publish($topic, $content, $qos = 0, $retain = false): void
    -    {
    -        $i = 0;
    -        $buffer = '';
    -
    -        $buffer .= $this->strwritestring($topic, $i);
    -
    -        if ($qos) {
    -            $id = $this->msgid++;
    -            $buffer .= chr($id >> 8);
    -            $i++;
    -            $buffer .= chr($id % 256);
    -            $i++;
    -        }
    -
    -        $buffer .= $content;
    -        $i += strlen($content);
    -
    -        $head = ' ';
    -        $cmd = 0x30;
    -        if ($qos) {
    -            $cmd += $qos << 1;
    -        }
    -        if (empty($retain) === false) {
    -            ++$cmd;
    -        }
    -
    -        $head[0] = chr($cmd);
    -        $head .= $this->setmsglength($i);
    -
    -        fwrite($this->socket, $head, strlen($head));
    -        $this->_fwrite($buffer);
    -    }
    -
    -    /**
    -     * Writes a string to the socket
    -     *
    -     * @param $buffer
    -     *
    -     * @return bool|int
    -     */
    -    protected function _fwrite($buffer)
    -    {
    -        $buffer_length = strlen($buffer);
    -        for ($written = 0; $written < $buffer_length; $written += $fwrite) {
    -            $fwrite = fwrite($this->socket, substr($buffer, $written));
    -            if ($fwrite === false) {
    -                return false;
    -            }
    -        }
    -        return $buffer_length;
    -    }
    -
    -    /**
    -     * Processes a received topic
    -     *
    -     * @param $msg
    -     *
    -     * @retrun bool|string
    -     */
    -    public function message($msg)
    -    {
    -        $tlen = (ord($msg[0]) << 8) + ord($msg[1]);
    -        $topic = substr($msg, 2, $tlen);
    -        $msg = substr($msg, ($tlen + 2));
    -        $found = false;
    -        foreach ($this->topics as $key => $top) {
    -            if (preg_match(
    -                '/^' . str_replace(
    -                    '#',
    -                    '.*',
    -                    str_replace(
    -                        '+',
    -                        "[^\/]*",
    -                        str_replace(
    -                            '/',
    -                            "\/",
    -                            str_replace(
    -                                '$',
    -                                '\$',
    -                                $key
    -                            )
    -                        )
    -                    )
    -                ) . '$/',
    -                $topic
    -            )) {
    -                if ($top['function'] === '__direct_return_message__') {
    -                    return $msg;
    -                }
    -
    -                if (is_callable($top['function'])) {
    -                    call_user_func($top['function'], $topic, $msg);
    -                } else {
    -                    $this->_errorMessage('Message received on topic ' . $topic. ' but function is not callable.');
    -                }
    -            }
    -        }
    -
    -        if ($found === false) {
    -            $this->_debugMessage('msg received but no match in subscriptions');
    -        }
    -
    -        return $found;
    -    }
    -
    -    /**
    -     * The processing loop for an "always on" client
    -     * set true when you are doing other stuff in the loop good for
    -     * watching something else at the same time
    -     *
    -     * @param bool $loop
    -     *
    -     * @return bool | string
    -     */
    -    public function proc(bool $loop = true)
    -    {
    -        if (feof($this->socket)) {
    -            $this->_debugMessage('eof receive going to reconnect for good measure');
    -            fclose($this->socket);
    -            $this->connect_auto(false);
    -            if (count($this->topics)) {
    -                $this->subscribe($this->topics);
    -            }
    -        }
    -
    -        $byte = $this->read(1, true);
    -
    -        if ((string)$byte === '') {
    -            if ($loop === true) {
    -                usleep(100000);
    -            }
    -        } else {
    -            $cmd = (int)(ord($byte) / 16);
    -            $this->_debugMessage(
    -                sprintf(
    -                    'Received CMD: %d (%s)',
    -                    $cmd,
    -                    isset(static::$known_commands[$cmd]) === true ? static::$known_commands[$cmd] : 'Unknown'
    -                )
    -            );
    -
    -            $multiplier = 1;
    -            $value = 0;
    -            do {
    -                $digit = ord($this->read(1));
    -                $value += ($digit & 127) * $multiplier;
    -                $multiplier *= 128;
    -            } while (($digit & 128) !== 0);
    -
    -            $this->_debugMessage('Fetching: ' . $value . ' bytes');
    -
    -            $string = $value > 0 ? $this->read($value) : '';
    -
    -            if ($cmd) {
    -                switch ($cmd) {
    -                    case 3: //Publish MSG
    -                        $return = $this->message($string);
    -                        if (is_bool($return) === false) {
    -                            return $return;
    -                        }
    -                        break;
    -                }
    -            }
    -        }
    -
    -        if ($this->timesinceping < (time() - $this->keepalive)) {
    -            $this->_debugMessage('not had something in a while so ping');
    -            $this->ping();
    -        }
    -
    -        if ($this->timesinceping < (time() - ($this->keepalive * 2))) {
    -            $this->_debugMessage('not seen a packet in a while, disconnecting/reconnecting');
    -            fclose($this->socket);
    -            $this->connect_auto(false);
    -            if (count($this->topics)) {
    -                $this->subscribe($this->topics);
    -            }
    -        }
    -
    -        return true;
    -    }
    -
    -    /**
    -     * Gets the length of a msg, (and increments $i)
    -     *
    -     * @param $msg
    -     * @param $i
    -     *
    -     * @return float|int
    -     */
    -    protected function getmsglength(&$msg, &$i)
    -    {
    -        $multiplier = 1;
    -        $value = 0;
    -        do {
    -            $digit = ord($msg[$i]);
    -            $value += ($digit & 127) * $multiplier;
    -            $multiplier *= 128;
    -            $i++;
    -        } while (($digit & 128) !== 0);
    -
    -        return $value;
    -    }
    -
    -    /**
    -     * @param $len
    -     *
    -     * @return string
    -     */
    -    protected function setmsglength($len): string
    -    {
    -        $string = '';
    -        do {
    -            $digit = $len % 128;
    -            $len >>= 7;
    -            // if there are more digits to encode, set the top bit of this digit
    -            if ($len > 0) {
    -                $digit |= 0x80;
    -            }
    -            $string .= chr($digit);
    -        } while ($len > 0);
    -        return $string;
    -    }
    -
    -    /**
    -     * @param $str
    -     * @param $i
    -     *
    -     * @return string
    -     */
    -    protected function strwritestring($str, &$i): string
    -    {
    -        $len = strlen($str);
    -        $msb = $len >> 8;
    -        $lsb = $len % 256;
    -        $ret = chr($msb);
    -        $ret .= chr($lsb);
    -        $ret .= $str;
    -        $i += ($len + 2);
    -        return $ret;
    -    }
    -
    -    /**
    -     * Prints a sting out character by character
    -     *
    -     * @param $string
    -     */
    -    public function printstr($string): void
    -    {
    -        $strlen = strlen($string);
    -        for ($j = 0; $j < $strlen; $j++) {
    -            $num = ord($string[$j]);
    -            if ($num > 31) {
    -                $chr = $string[$j];
    -            } else {
    -                $chr = ' ';
    -            }
    -            printf("%4d: %08b : 0x%02x : %s \n", $j, $num, $num, $chr);
    -        }
    -    }
    -
    -    /**
    -     * @param string $message
    -     */
    -    protected function _debugMessage(string $message): void
    -    {
    -        if ($this->debug === true) {
    -            echo date('r: ') . $message . PHP_EOL;
    -        }
    -    }
    -
    -    /**
    -     * @param string $message
    -     */
    -    protected function _errorMessage(string $message): void
    -    {
    -        error_log('Error:' . $message);
    -    }
    -}
    
  • zenario/libs/manually_maintained/mit/phpmqtt/README.md+0 15 removed
    @@ -1,15 +0,0 @@
    -**2020 Update**
    
    -I am restarting the project so watch this space
    
    -
    
    -
    
    -Blue Rhinos Consulting
    
    -Andrew Milsted | andrew@bluerhinos.co.uk | http://www.bluerhinos.co.uk | @bluerhinos
    
    -
    
    -A simple php class to connect/publish/subscribe to an MQTT broker
    
    -
    
    -Documentation: Coming Soon
    
    -Source: http://github.com/bluerhinos/phpMQTT
    
    -
    
    -To install via Composer
    
    ------------------------
    
    -`composer require bluerhinos/phpmqtt=@dev`
    
    
  • zenario/libs/manually_maintained/mit/phpmqtt/zenario_modifications.txt+0 2 removed
    @@ -1,2 +0,0 @@
    -In phpMQTT.php:
    
    -	Replaced all array offsets that used curly brackets with square ones, as using curly brackets for this is deprecated
    \ No newline at end of file
    
  • zenario/modules/zenario_blog_news_list/frameworks/image_title_text_more/framework.twig.html+3 3 modified
    @@ -125,17 +125,17 @@ <h2 class="content_list_title {{item.Content_Type|e}}">
     					{% endif %}
     					
     					<div class="content_list_more">
    -						<a {{item.Link}}{{item.Target_Blank}}>{{More_Phrase|e}}</a>
    +						<a {{item.Link}}{{item.Target_Blank}}>{{More_Phrase}}</a>
     					</div>
     				</div>
     			{% endfor %}
     			{% if More %}
    -				<a class="content_list_more_link" {{More_Link}}>{{More_Link_Title|e}}</a>
    +				<a class="content_list_more_link" {{More_Link}}>{{More_Link_Title}}</a>
     			{% endif %}
     		</div>
     	{% endif %}
     	{% if No_Rows %}
    -		<h2>{{Title_With_No_Content|e}}</h2>
    +		<h2>{{Title_With_No_Content}}</h2>
     	{% endif %}
     	{% if Years %}
     		<form class="content_list_date_select">
    
  • zenario/modules/zenario_common_features/classes/admin_boxes/writer_profile.php+2 2 modified
    @@ -68,9 +68,9 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
                             $box['tabs']['details']['notices']['admin_acc_trashed']['show'] = true;
    
                         }
    
                     }
    
    -            } elseif ($values['details/type'] == 'administrator') {
    
    +            } elseif ($values['details/type'] == 'external_writer') {
    
                     //... or just show "External writer".
    
    -                $fields['details/type_span'] = ze\admin::phrase('External writer');
    
    +                $values['details/type_span'] = ze\admin::phrase('External writer');
    
                 }
    
     
    
                 $sql = "
    
    
  • zenario/modules/zenario_common_features/classes/organizer/content.php+4 2 modified
    @@ -439,6 +439,7 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     			unset($panel['item_buttons']['delete']);
     
     		} elseif (($_GET['refinerName'] ?? false) == 'find_duplicates') {
    +			unset($panel['collection_buttons']['create']);
     			$panel['title'] = ze\admin::phrase('Items with duplicate file attachments');
     			$panel['no_items_message'] = ze\admin::phrase('No items with duplicate file attachments found');
     			unset($panel['collection_buttons']['diagnostics_dropdown']);
    @@ -534,6 +535,7 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     			$panel['columns']['language_id']['hidden'] = true;
     
     		} elseif ($_GET['refiner__category'] ?? false) {
    +			unset($panel['collection_buttons']['create']);
     			$mrg = [
     				'category' => ze\category::name($_GET['refiner__category'] ?? false)];
     			$panel['title'] = ze\admin::phrase('Content items in the category "[[category]]"', $mrg);
    @@ -1019,7 +1021,7 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     		    if(isset($_REQUEST['refinerName'])  && ($_REQUEST['refinerName'] == "trash" || $_REQUEST['refinerName'] == "special_pages")){
     		        $panel['collection_buttons']['create']['hidden'] = true;
     		        $panel['collection_buttons']['new_node_dropdown']['hidden'] = true;
    -		    } 
    +		    }
     		   
     		} else {//All content items
     		    $panel['collection_buttons']['create']['hidden'] = true;
    @@ -1035,7 +1037,7 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     					$panel['collection_buttons']['new_node_'.$j]['admin_box']['path'] = 'zenario_content'; 
     					$panel['collection_buttons']['new_node_'.$j]['admin_box']['key']['target_cType'] = $content['content_type_id']; 
     				}
    -            }    
    +            }
        
     		}
     		
    
  • zenario/modules/zenario_common_features/tuix/organizer/content_items.yaml+2 1 modified
    @@ -591,7 +591,8 @@ zenario__content:
                             key:
                                 create_from_content_panel: 1
                         ord: 1
    -                            
    +                    #This button will be hidden on many refiners.
    +                    #Controlled in the PHP code.
                     delete_trashed_items:
                         priv: _PRIV_DELETE_TRASHED_CONTENT_ITEMS
                         hide_in_select_mode: true
    
  • zenario/modules/zenario_content_list/frameworks/includes/footer.twig.html+2 2 modified
    @@ -1,12 +1,12 @@
     {% if Rows %}
     		{% if More %}
    -			<a class="content_list_more_link" {{More_Link}}>{{More_Link_Title|e}}</a>
    +			<a class="content_list_more_link" {{More_Link}}>{{More_Link_Title}}</a>
     		{% endif %}
     	</div>
     {% endif %}
     {% if No_Rows %}
     	{% if Show_No_Title %}
    -		<{{Title_Tags}}>{{Title_With_No_Content|e}}</{{Title_Tags}}>
    +		<{{Title_Tags}}>{{Title_With_No_Content}}</{{Title_Tags}}>
     	{% endif %}
     {% endif %}
     {% if Years %}
    
  • zenario/modules/zenario_content_list/frameworks/includes/more.twig.html+1 1 modified
    @@ -1,3 +1,3 @@
     <div class="content_list_more">
    -	<a {{item.Link}}{{item.Target_Blank}}>{{More_Phrase|e}}</a>
    +	<a {{item.Link}}{{item.Target_Blank}}>{{More_Phrase}}</a>
     </div>
    \ No newline at end of file
    
  • zenario/modules/zenario_cookie_consent_status/description.yaml+17 9 modified
    @@ -7,15 +7,23 @@ editions: ProBusiness, Enterprise
     start_running_on_install: false
     license_info: 'Modified BSD License'
     description: |
    -    <p>
    -                    This module displays information to website visitors on whether they have consented to or rejected cookies.
    -                </p><p>
    -                    It also provides a button that lets them opt in to cookies if they have previously rejected
    -                    them, or opt out of further cookies if they have previously accepted them.
    -                </p><p>
    -                    To use this module, you must be using the Explicit consent policy.
    -                    This can be enabled by going to <em>Configuration -&gt; Site settings -&gt; Cookies</em> in Organizer.
    -                </p>
    +    <p style="font-weight: bold;">
    +        Known issue: This module does not correctly interact with several things
    +        in the CMS and we do not recommend using it.
    +    </p><p style="font-weight: bold;">
    +        This module is deprecated, and will be removed come Zenario 9.3 in
    +        favour of a new cookie management system built in to Zenario.
    +    </p><p>
    +        &nbsp;
    +    </p><p>
    +        This module displays information to website visitors on whether they have consented to or rejected cookies.
    +    </p><p>
    +        It also provides a means whereby visitors can opt in to or out of cookies,
    +        grouped by type of cookie.
    +    </p><p>
    +        To use this module, the site setting must be set to the Explicit consent policy.
    +        This can be enabled by going to <em>Configuration -&gt; Site settings -&gt; Cookies</em> in Organizer.
    +    </p>
     category: pluggable
     keywords: cookies, consent, explicit
     
    
  • zenario/modules/zenario_event_calendar/frameworks/standard/framework.twig.html+12 0 modified
    @@ -54,6 +54,12 @@ <h2>{{Year_number}}</h2>
     													</a>
     												</span>
     											{% endfor %}
    +
    +											{% if item.Other_events and item.And_x_more_events_phrase %}
    +												<span class="event">
    +													{{item.And_x_more_events_phrase|e}}
    +												</span>
    +											{% endif %}
     										</div>
     									</td>
     								{% endfor %}
    @@ -155,6 +161,12 @@ <h2>{{Full_date}}</h2>
     													</a>
     												</span>
     											{% endfor %}
    +
    +											{% if item.Other_events and item.And_x_more_events_phrase %}
    +												<span class="event">
    +													{{item.And_x_more_events_phrase|e}}
    +												</span>
    +											{% endif %}
     										</div>
     									</td>
     								{% endfor %}
    
  • zenario/modules/zenario_event_calendar/module_code.php+82 8 modified
    @@ -158,29 +158,66 @@ function showMonthView() {
     					$day_class_name_var = 'day';
     				}
     				
    -				if (ze::in($this->setting('show_event_titles'), "first_event", "all_events") || $this->setting('event_count')) {
    +				if (ze::in($this->setting('show_event_titles'), "first_event", "first_2_events", "first_3_events", "first_4_events", "first_5_events", "all_events") || $this->setting('event_count')) {
     					$dayEvents = [];
    +
    +					$eventLimit = 0;
    +					$otherEvents = 0;
    +					if (ze::in($this->setting('show_event_titles'), "first_event", "first_2_events", "first_3_events", "first_4_events", "first_5_events")) {
    +						switch ($this->setting('show_event_titles')) {
    +							case 'first_event':
    +								$eventLimit = 1;
    +								break;
    +							case 'first_2_events':
    +								$eventLimit = 2;
    +								break;
    +							case 'first_3_events':
    +								$eventLimit = 3;
    +								break;
    +							case 'first_4_events':
    +								$eventLimit = 4;
    +								break;
    +							case 'first_5_events':
    +								$eventLimit = 5;
    +								break;
    +						}
    +
    +						if ($numberOfEvents > $eventLimit) {
    +							$otherEvents = $numberOfEvents - $eventLimit;
    +						}
    +					}
    +
    +					$currentEventOrd = 0;
     					foreach ($events as $event) {
    +						$currentEventOrd++;
    +
     						if ($this->setting('show_event_titles') != "nothing") {
     							$dayEvents[] = [
     								'Title' => $event['title'],
     								'Link' => ze\link::toItem((int) $event['id'], 'event')
     							];
     						}
     						
    -						if ($this->setting('show_event_titles') == "first_event") {
    +						if ($eventLimit && ($eventLimit == $currentEventOrd)) {
     							break;
     						}
     					}
     					
    -					$mergeFields[] = [
    +					$dayMergeFields = [
     						'Anchor' => ' rel="colorbox" href="'. htmlspecialchars($this->showFloatingBoxLink("&mode=month_view&day=" . (string)(int)$j . "&month=" . (string)(int)$month . "&year=" . (string)(int)$year,1,true,300,-150,17,false,0)). '"',
     						'Day_class_name' => $day_class_name_var,
     						'Td_day_class_name' => 'event',
     						'Day_label' => (string)(int)($j++),
     						'Num_events' => $numberOfEvents,
    -						'Day_events' => $dayEvents
    +						'Day_events' => $dayEvents,
    +						'Other_events' => $otherEvents
     					];
    +
    +					if ($otherEvents) {
    +						$dayMergeFields['And_x_more_events_phrase'] = ze\lang::nPhrase('and 1 other event', 'and [[count]] other events', $otherEvents, ['count' => (int) $otherEvents]);
    +					}
    +
    +					$mergeFields[] = $dayMergeFields;
     				} elseif ($this->setting('show_event_titles') == "nothing" || !$this->setting('event_count')) {
     					$mergeFields[] = [
     						'Anchor' => ' rel="colorbox" href="'. htmlspecialchars($this->showFloatingBoxLink("&mode=month_view&day=" . (string)(int)$j . "&month=" . (string)(int)$month . "&year=" . (string)(int)$year,1,true,300,-150,17,false,0)). '"',
    @@ -263,27 +300,64 @@ public function showYearView(){
     							
     					if (ze::in($this->setting('show_event_titles'), "first_event", "all_events") || $this->setting('event_count')) {
     						$monthEvents = [];
    +
    +						$eventLimit = 0;
    +						$otherEvents = 0;
    +						if (ze::in($this->setting('show_event_titles'), "first_event", "first_2_events", "first_3_events", "first_4_events", "first_5_events")) {
    +							switch ($this->setting('show_event_titles')) {
    +								case 'first_event':
    +									$eventLimit = 1;
    +									break;
    +								case 'first_2_events':
    +									$eventLimit = 2;
    +									break;
    +								case 'first_3_events':
    +									$eventLimit = 3;
    +									break;
    +								case 'first_4_events':
    +									$eventLimit = 4;
    +									break;
    +								case 'first_5_events':
    +									$eventLimit = 5;
    +									break;
    +							}
    +
    +							if ($numberOfEvents > $eventLimit) {
    +								$otherEvents = $numberOfEvents - $eventLimit;
    +							}
    +						}
    +
    +						$currentEventOrd = 0;
     						foreach ($events as $event) {
    +							$currentEventOrd++;
    +
     							if ($this->setting('show_event_titles') != "nothing") {
     								$monthEvents[] = [
     									'Title' => $event['title'],
     									'Link' => ze\link::toItem((int) $event['id'], 'event')
     								];
     							}
     
    -							if ($this->setting('show_event_titles') == "first_event") {
    +							if ($eventLimit && ($eventLimit == $currentEventOrd)) {
     								break;
     							}
     						}
     					
    -						$mergeFields[] = [	
    +						$monthMergeFields = [
     							'Anchor' =>' rel="colorbox" href="'. htmlspecialchars($this->showFloatingBoxLink("&mode=year_view&month=" . (string)(int)$month . "&year=" . (string)(int)$year,1,true,300,-150,17,false,0)). '"',
     							'Current_month'=>$currentMonthClass,
     							'Month_with_events'=>'month_with_events',
     							'Month_label'=> $monthLabel,
     							'Num_events' => $numberOfEvents,
    -							'Month_events' => $monthEvents
    -						];		
    +							'Month_events' => $monthEvents,
    +							'Other_events' => $otherEvents
    +						];
    +
    +						if ($otherEvents) {
    +							$monthMergeFields['And_x_more_events_phrase'] = ze\lang::nPhrase('and 1 other event', 'and [[count]] other events', $otherEvents, ['count' => (int) $otherEvents]);
    +						}
    +
    +						$mergeFields[] = $monthMergeFields;
     					} elseif ($this->setting('show_event_titles') == "nothing" || !$this->setting('event_count')) {
     						$mergeFields[] = [	
     							'Anchor' => ' rel="colorbox" href="'. htmlspecialchars($this->showFloatingBoxLink("&mode=year_view&month=" . (string)(int)$month . "&year=" . (string)(int)$year,1,true,300,-150,17,false,0)). '"',
    
  • zenario/modules/zenario_event_calendar/tuix/admin_boxes/plugin_settings.yaml+11 4 modified
    @@ -110,12 +110,19 @@ plugin_settings:
                         type: select
                         values:
                             nothing:
    -                            label: |
    -                                Don't show event details
    +                            label: "Don't show event details"
                             first_event:
    -                            label: 'Title of first event in time period'
    +                            label: "First event only"
    +                        first_2_events:
    +                            label: "Up to 2 events"
    +                        first_3_events:
    +                            label: "Up to 3 events"
    +                        first_4_events:
    +                            label: "Up to 4 events"
    +                        first_5_events:
    +                            label: "Up to 5 events"
                             all_events:
    -                            label: 'Titles of all events in time period'
    +                            label: "All events"
                         value: first_event
                     event_count:
                         label: 'Show number of events'
    
  • zenario/modules/zenario_location_manager/module_code.php+1 1 modified
    @@ -2012,7 +2012,7 @@ public static function deleteLocation($locationId) {
     		ze\row::delete(ZENARIO_LOCATION_MANAGER_PREFIX . 'locations', $locationId);
     		ze\row::delete(ZENARIO_LOCATION_MANAGER_PREFIX . 'locations_custom_data', $locationId);
     
    -		ze\module::sendSignal('eventLocationDeleted', ["locationId" => $locationId]);
    +		ze\module::sendSignal('eventLocationDeleted', [$locationId]);
     	}
     
     	public static function activateLocation($locationId) {
    
  • zenario/modules/zenario_menu/module_code.php+2 2 modified
    @@ -296,7 +296,7 @@ function getMenuMergeFields(&$menuArray, $depth = 1, $parentId = false) {
     				if ($menuNodeMergeFields = $this->getMenuNodeMergeFields($depth, ++$i, $row)) {
     					
     					if (!empty($row['children']) && is_array($row['children'])) {
    -						$parentId = $row['mID'];
    +						$parentId = $row['mID'] ?? 0;
     						$menuNodeMergeFields['children'] = $this->getMenuMergeFields($row['children'], $depth + 1, $parentId);
     						
     						$menuNodeMergeFields['All_Children_Are_Hidden'] = true;
    @@ -326,7 +326,7 @@ function getMenuNodeMergeFields($depth, $i, &$row) {
     		
     		$objects = [];
     		$objects['depth'] = (int) $depth;
    -		$objects['mID'] = $row['mID'];
    +		$objects['mID'] = $row['mID'] ?? 0;
     		$objects['Hyperlink'] = $this->drawMenuItem($row);
     		
     		$objects['Class'] = 'level'. $depth. ' level'. $depth. '_'. $i;
    
  • zenario/modules/zenario_pro_features/fun/createExportFile.php+1 0 modified
    @@ -48,6 +48,7 @@
     	zenario_pro_features::openTagStart($isXML, $f, 'target');
     	zenario_pro_features::addAtt($isXML, $f, 'cID', ($targetCID ?: $cID));
     	zenario_pro_features::addAtt($isXML, $f, 'cType', ($targetCType ?: $cType));
    +	zenario_pro_features::addAtt($isXML, $f, 'pinned', $version['pinned']);
     	zenario_pro_features::openTagEnd($isXML, $encodeHTMLAtt, $f);
     	zenario_pro_features::closeTag($isXML, $f, 'target');
     	
    
  • zenario/modules/zenario_user_forms/module_code.php+17 10 modified
    @@ -3934,12 +3934,14 @@ public static function getFieldDisplayValue($field, $value, $html = false, $incl
     				break;
     			case 'attachment':
     				if ($value && ($fileId = static::getFieldStorableValue($field, $value))) {
    -					$file = ze\row::get('files', ['filename'], $fileId);
    +					$file = ze\row::get('files', ['filename', 'size'], $fileId);
     					if ($file) {
    +						$sizeFormatted = ze\file::fileSizeConvert($file['size']);
    +
     						if ($html && $includeDownloadLinks == 'visitor') {
    -							return '<a href="' . htmlspecialchars(ze\file::link($fileId)) . '" target="_blank">' . htmlspecialchars($file['filename']) . '</a>';
    +							return '<a href="' . htmlspecialchars(ze\file::link($fileId)) . '" target="_blank">' . htmlspecialchars($file['filename']) . ' (' . htmlspecialchars($sizeFormatted) . ')</a>';
     						} elseif ($html && $includeDownloadLinks == 'admin') {
    -							return '<a href="' . htmlspecialchars(ze\link::absolute()) . 'zenario/file.php?adminDownload=1&id=' . (int)$fileId . '" target="_blank">' . htmlspecialchars($file['filename']) . '</a>';
    +							return '<a href="' . htmlspecialchars(ze\link::absolute()) . 'zenario/file.php?adminDownload=1&id=' . (int)$fileId . '" target="_blank">' . htmlspecialchars($file['filename']) . ' (' . htmlspecialchars($sizeFormatted) . ')</a>';
     						} else {
     							$display = $file['filename'];
     						}
    @@ -3953,15 +3955,20 @@ public static function getFieldDisplayValue($field, $value, $html = false, $incl
     				if ($value && ($fileIds = static::getFieldStorableValue($field, $value))) {
     					$fileList = [];
     					foreach (explode(',', $fileIds) as $fileId) {
    -						$file = ze\row::get('files', ['filename'], $fileId);
    -						if ($html && $includeDownloadLinks == 'visitor') {
    -							$fileList[] = '<a href="' . htmlspecialchars(ze\file::link($fileId)) . '" target="_blank">' . htmlspecialchars($file['filename']) . '</a>';
    -						} elseif ($html && $includeDownloadLinks == 'admin') {
    -							$fileList[] = '<a href="' . htmlspecialchars(ze\link::absolute()) . 'zenario/file.php?adminDownload=1&id=' . (int)$fileId . '" target="_blank">' . htmlspecialchars($file['filename']) . '</a>';
    -						} else {
    -							$fileList[] = $file['filename'];
    +						$file = ze\row::get('files', ['filename', 'size'], $fileId);
    +						if ($file) {
    +							$sizeFormatted = ze\file::fileSizeConvert($file['size']);
    +
    +							if ($html && $includeDownloadLinks == 'visitor') {
    +								$fileList[] = '<a href="' . htmlspecialchars(ze\file::link($fileId)) . '" target="_blank">' . htmlspecialchars($file['filename']) . ' (' . htmlspecialchars($sizeFormatted) . ')</a>';
    +							} elseif ($html && $includeDownloadLinks == 'admin') {
    +								$fileList[] = '<a href="' . htmlspecialchars(ze\link::absolute()) . 'zenario/file.php?adminDownload=1&id=' . (int)$fileId . '" target="_blank">' . htmlspecialchars($file['filename']) . ' (' . htmlspecialchars($sizeFormatted) . ')</a>';
    +							} else {
    +								$fileList[] = $file['filename'];
    +							}
     						}
     					}
    +					
     					$display = implode(', ', $fileList);
     					if ($html) {
     						return $display;
    
  • zenario/modules/zenario_user_forms/tuix/organizer/user_form_responses.yaml+1 0 modified
    @@ -31,6 +31,7 @@ zenario__user_forms:
                         align_right: true
                         width: xxsmall
                         disallow_sorting: true
    +                    searchable: true
                         always_show: true
                     response_datetime:
                         title: Date/Time Responded
    
  • zenario/modules/zenario_users/classes/admin_boxes/content_privacy.php+3 1 modified
    @@ -58,7 +58,9 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     				['id', 'type', 'tag_id', 'language_id', 'equiv_id', 'alias', 'visitor_version', 'admin_version', 'status'],
     				['id' => $box['key']['cID'], 'type' => $box['key']['cType']]);
     		
    -		$box['identifier']['css_class'] = ze\contentAdm::getItemIconClass($content['id'], $content['type'], true, $content['status']);
    +		if ($content && isset($content['id'], $content['type'], $content['status'])) {
    +			$box['identifier']['css_class'] = ze\contentAdm::getItemIconClass($content['id'], $content['type'], true, $content['status']);
    +		}
     		
     		$fields['privacy/group_ids']['values'] = ze\datasetAdm::getGroupPickerCheckboxesForFAB();
     		$fields['privacy/smart_group_id']['values'] = ze\contentAdm::getListOfSmartGroupsWithCounts();
    
  • zenario/modules/zenario_users/classes/admin_boxes/user__details.php+4 1 modified
    @@ -62,7 +62,10 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     			$values['details/linked_countries'] =
     				implode(',', ze\row::getValues('user_country_link', 'country_id', ['user_id' => $box['key']['id']]));
     			
    -			$suspendedDate = date_format(new DateTime($user['suspended_date']), "d M Y H:i:s");
    +			$suspendedDate = '';
    +			if (!empty($user['suspended_date'])) {
    +				$suspendedDate = date_format(new DateTime($user['suspended_date']), "d M Y H:i:s");
    +			}
     			switch($user['status']) {
     				case 'contact':
     					$fields['details/status']['note_below'] = 
    
  • zenario/modules/zenario_videos_fea/classes/admin_boxes/plugin_settings.php+15 2 modified
    @@ -32,8 +32,22 @@ class zenario_videos_fea__admin_boxes__plugin_settings extends zenario_videos_fe
     	
     	public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     		ze\miscAdm::setupSlideDestinations($box, $fields, $values);
    +
    +		$sql = '
    +			SELECT cat.id, cat.name, COUNT(cvl.video_id) AS count
    +			FROM ' . DB_PREFIX . ZENARIO_VIDEOS_MANAGER_PREFIX . 'categories cat
    +			LEFT JOIN ' . DB_PREFIX . ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link cvl
    +				ON cvl.category_id = cat.id
    +			GROUP BY cat.id
    +			ORDER BY cat.name';
     		
    -		$fields['first_tab/category_filters']['values'] = ze\row::getAssocs(ZENARIO_VIDEOS_MANAGER_PREFIX . 'categories', 'name');
    +		$categories = ze\sql::select($sql);
    +
    +		$ord = 0;
    +		while ($row = ze\sql::fetchAssoc($categories)) {
    +			$category = ['label' => $row['name'] . ' (' . (int) ($row['count'] ?: 0) . ')', 'ord' => ++$ord];
    +			$fields['first_tab/category_filters']['values'][$row['id']] = $category;
    +		}
     		
     		$documentEnvelopesModuleIsRunning = ze\module::inc('zenario_document_envelopes_fea');
     		if (!$documentEnvelopesModuleIsRunning) {
    @@ -49,5 +63,4 @@ public function formatAdminBox($path, $settingGroup, &$box, &$fields, &$values,
             $hidden = $values['global_area/mode'] != 'list_videos' || !$values['first_tab/show_images'];
     		$this->showHideImageOptions($fields, $values, 'first_tab', $hidden, 'image_');
     	}
    -	
     }
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_fea/classes/visitor/edit_video.php+3 3 modified
    @@ -124,13 +124,13 @@ public function init() {
     			
     				//Categories
     				if ($this->mode == 'edit_video') {
    -					ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['video_id' => $videoId]);
    +					ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['video_id' => $videoId]);
     				}
     			
     				if ($this->videoCategories) {
     					if ($currentVideoCategories = ze::post('current_video_category')) {
     						foreach ($currentVideoCategories as $categoryId) {
    -							ze\row::insert(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['video_id' => $videoId, 'category_id' => $categoryId]);
    +							ze\row::insert(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['video_id' => $videoId, 'category_id' => $categoryId]);
     						}
     					}
     				}
    @@ -221,7 +221,7 @@ public function showSlot() {
     			$this->data['short_description'] = $this->video['short_description'];
     			$this->data['date'] = $this->video['date'];
     			$this->data['language_id'] = $this->video['language_id'];
    -			$this->data['current_video_categories'] = ze\row::getValues(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', 'category_id', ['video_id' => $this->videoId]);
    +			$this->data['current_video_categories'] = ze\row::getValues(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', 'category_id', ['video_id' => $this->videoId]);
     		} else {
     			$this->data['date'] = ze\date::ymd();
     		}
    
  • zenario/modules/zenario_videos_fea/classes/visitor/list_videos.php+29 9 modified
    @@ -67,8 +67,8 @@ protected function populateItemsSelect($path, &$tags, &$fields, &$values) {
     	protected function populateItemsFrom($path, &$tags, &$fields, &$values) {
     		$sql = '
     			FROM ' . DB_PREFIX . ZENARIO_VIDEOS_MANAGER_PREFIX . 'videos v
    -			LEFT JOIN ' . DB_PREFIX . ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories vc
    -				ON v.id = vc.video_id';
    +			LEFT JOIN ' . DB_PREFIX . ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link cvl
    +				ON v.id = cvl.video_id';
     		return $sql;
     	}
     	protected function populateItemsWhere($path, &$tags, &$fields, &$values) {
    @@ -77,13 +77,13 @@ protected function populateItemsWhere($path, &$tags, &$fields, &$values) {
     		
     		if ($this->scope == 'similar_videos') {
     			$categoryFilters = [];
    -			$result = ze\row::query(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['category_id'], ['video_id' => $this->videoId]);
    +			$result = ze\row::query(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['category_id'], ['video_id' => $this->videoId]);
     			while ($row = ze\sql::fetchAssoc($result)) {
     				$categoryFilters[] = $row['category_id'];
     			}
     			if ($categoryFilters) {
     				$sql .= '
    -					AND vc.category_id IN (' . ze\escape::in($categoryFilters, 'numeric') . ')';
    +					AND cvl.category_id IN (' . ze\escape::in($categoryFilters, 'numeric') . ')';
     			} else {
     				$sql .= '
     					AND FALSE';
    @@ -95,15 +95,36 @@ protected function populateItemsWhere($path, &$tags, &$fields, &$values) {
     				foreach (explode(',', $categories) as $categoryId) {
     					$categoryFilters[] = $categoryId;
     				}
    -				$sql .= '
    -					AND vc.category_id IN (' . ze\escape::in($categoryFilters, 'numeric') . ')';
    +
    +				if (ze::in($this->setting('in_any_or_all_categories'), 'any', 'all')) {
    +					$sql .= '
    +						AND cvl.category_id IN (' . ze\escape::in($categoryFilters, 'numeric') . ')';
    +					
    +				}
     			}
     		}
    +
     		return $sql;
     	}
     	protected function populateItemsGroupBy($path, &$tags, &$fields, &$values) {
    -		return '
    +		$sql = '
     			GROUP BY v.id';
    +		
    +		if ($this->scope == 'specific_categories' && ($categories = $this->setting('category_filters')) && $this->setting('in_any_or_all_categories') == 'all') {
    +			$categoryFilters = [];
    +			foreach (explode(',', $categories) as $categoryId) {
    +				$categoryFilters[] = $categoryId;
    +			}
    +
    +			$categoriesCount = count($categoryFilters);
    +			if ($categoriesCount > 0) {
    +				$sql .= '
    +					HAVING COUNT(DISTINCT cvl.category_id) = ' . (int) $categoriesCount;
    +			}
    +				
    +		}
    +
    +		return $sql;
     	}
     	protected function populateItemsOrderBy($path, &$tags, &$fields, &$values) {
     		//Order by options
    @@ -219,5 +240,4 @@ public function rapInViewVideoAnchor($innerHTML, $itemId) {
     		}
     		return $anchor;
     	}
    -
    -}
    +}
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_fea/classes/visitor/view_video.php+17 13 modified
    @@ -98,19 +98,23 @@ public function showSlot() {
     							$json['html'] = str_replace('feature=oembed', 'feature=oembed&autoplay=1&rel=0', $json['html']);
     						} else {
     							//Privacy
    -							$privacy = $videoData['privacy']['view'] ?? '';
    -							$vimeoPrivacySettingsFormattedNicely = zenario_videos_manager::getVimeoPrivacySettingsFormattedNicely();
    -							
    -							if ($privacy && array_key_exists($privacy, $vimeoPrivacySettingsFormattedNicely)) {
    -								$privacyString = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacy]['visitor_note']);
    -							} else {
    -								$privacyString = $this->phrase('Sorry, cannot show privacy setting');
    -							}
    -							$this->data['video']['privacy'] = $privacyString;
    -							
    -							if ($privacy == 'unlisted' || $privacy == 'anybody') {
    -								$this->data['video']['url'] = $this->video['url'];
    -								$this->data['video']['shareable_link'] = true;
    +							if ($this->setting('show_privacy_info')) {
    +								$this->data['show_privacy_info'] = true;
    +
    +								$privacy = $videoData['privacy']['view'] ?? '';
    +								$vimeoPrivacySettingsFormattedNicely = zenario_videos_manager::getVimeoPrivacySettingsFormattedNicely();
    +								
    +								if ($privacy && array_key_exists($privacy, $vimeoPrivacySettingsFormattedNicely)) {
    +									$privacyString = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacy]['visitor_note']);
    +								} else {
    +									$privacyString = $this->phrase('Sorry, cannot show privacy setting');
    +								}
    +								$this->data['video']['privacy'] = $privacyString;
    +								
    +								if ($privacy == 'unlisted' || $privacy == 'anybody') {
    +									$this->data['video']['url'] = $this->video['url'];
    +									$this->data['video']['shareable_link'] = true;
    +								}
     							}
     
     							//Thumbnail
    
  • zenario/modules/zenario_videos_fea/frameworks/standard/framework.twig.html+1 1 modified
    @@ -63,7 +63,7 @@
     
     			<div class="description">{{video.description}}</div>
     			<p class="date">{{video.date|e}}</p>
    -			{% if video.privacy %}
    +			{% if show_privacy_info and video.privacy %}
     				<div class="privacy">{{video.privacy}}</div>
     				{% if video.shareable_link %}
     					<div class="shareable_link">
    
  • zenario/modules/zenario_videos_fea/latest_revision_no.inc.php+1 1 modified
    @@ -1,4 +1,4 @@
     <?php
     if (!defined('NOT_ACCESSED_DIRECTLY')) exit('This file may not be directly accessed');
     
    -define(ze::moduleName(__FILE__). '_LATEST_REVISION_NO', 5);
    \ No newline at end of file
    +define(ze::moduleName(__FILE__). '_LATEST_REVISION_NO', 6);
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_fea/tuix/admin_boxes/plugin_settings.yaml+31 1 modified
    @@ -371,6 +371,17 @@ plugin_settings:
                             name: show_video_language
                         value: 0
                         type: checkbox
    +                show_privacy_info:
    +                    grouping: options
    +                    label: Show privacy info
    +                    visible_if:
    +                        lib.modeIn: 
    +                            - view_video
    +                    plugin_setting:
    +                        name: show_privacy_info
    +                    value: 0
    +                    type: checkbox
    +                
                     highlight_currently_playing_video:
                         grouping: options
                         type: checkbox
    @@ -380,8 +391,27 @@ plugin_settings:
                         visible_if:
                             lib.modeIs: list_videos
                     
    +                in_any_or_all_categories:
    +                    plugin_setting:
    +                        name: in_any_or_all_categories
    +                    grouping: filters
    +                    indent: 1
    +                    visible_if:
    +                        lib.modeIs: list_videos
    +                        lib.scopeIs: specific_categories
    +                    type: select
    +                    value: "any"
    +                    values:
    +                        any:
    +                            ord: 1
    +                            label: 'In ANY of the categories below'
    +                        all:
    +                            ord: 2
    +                            label: 'In ALL of the categories below'
    +                
                     category_filters:
                         grouping: filters
    +                    indent: 1
                         label: 'Categories:'
                         visible_if:
                             lib.modeIs: list_videos
    @@ -404,4 +434,4 @@ plugin_settings:
                                 label: Alphabetical on title
                             date:
                                 label: Most recent date first
    -                    value: alphabetic
    +                    value: alphabetic
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_manager/classes/admin_boxes/site_settings.php+6 5 modified
    @@ -11,11 +11,12 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     				ze\admin::phrase('The API key setting is available on the <a target="_blank" href="[[link]]">API Keys</a> panel.', ['link' => htmlspecialchars($link)]);
     			
     			//Set labels for privacy settings
    -			$vimeoPrivacySettingsFormattedNicely = self::getVimeoPrivacySettingsFormattedNicely();
    -			foreach ($fields['zenario_videos_manager__vimeo/vimeo_privacy_settings']['values'] as $privacySettingKey => &$privacySetting) {
    -				$privacySetting['label'] = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacySettingKey]['label']);
    -				$privacySetting['note_below'] = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacySettingKey]['note']);
    -			}
    +			//Hidden as of 12 Jan 2022. --Marcin
    +			// $vimeoPrivacySettingsFormattedNicely = self::getVimeoPrivacySettingsFormattedNicely();
    +			// foreach ($fields['zenario_videos_manager__vimeo/vimeo_privacy_settings']['values'] as $privacySettingKey => &$privacySetting) {
    +			// 	$privacySetting['label'] = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacySettingKey]['label']);
    +			// 	$privacySetting['note_below'] = $this->phrase($vimeoPrivacySettingsFormattedNicely[$privacySettingKey]['note']);
    +			// }
     			
     			$documentEnvelopesModuleIsRunning = ze\module::inc('zenario_document_envelopes_fea');
     			if ($documentEnvelopesModuleIsRunning) {
    
  • zenario/modules/zenario_videos_manager/classes/admin_boxes/video.php+4 9 modified
    @@ -68,7 +68,7 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     			$values['details/language_id'] = $video['language_id'];
     			
     			$categories = [];
    -			$result = ze\row::query(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['category_id'], ['video_id' => $box['key']['id']]);
    +			$result = ze\row::query(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['category_id'], ['video_id' => $box['key']['id']]);
     			while ($row = ze\sql::fetchAssoc($result)) {
     				$categories[] = $row['category_id'];
     			}
    @@ -89,13 +89,9 @@ public function fillAdminBox($path, $settingGroup, &$box, &$fields, &$values) {
     						if ($privacy && array_key_exists($privacy, $vimeoPrivacySettingsFormattedNicely)) {
     							$privacyString = $vimeoPrivacySettingsFormattedNicely[$privacy]['note'];
     						} else {
    -							$privacyString = $this->phrase('Sorry, cannot show privacy setting');
    +							$privacyString = $this->phrase('Sorry, cannot fetch privacy setting');
     						}
     						$fields['details/video_privacy']['snippet']['html'] = $privacyString;
    -
    -						if (ze::setting('enable_vimeo_privacy_settings')) {
    -							$fields['details/video_privacy']['hidden'] = false;
    -						}
     					}
     				}
     			}
    @@ -231,12 +227,11 @@ public function saveAdminBox($path, $settingGroup, &$box, &$fields, &$values, $c
     		
     		$box['key']['id'] = ze\row::set(ZENARIO_VIDEOS_MANAGER_PREFIX . 'videos', $videoDetails, $box['key']['id']);
     		
    -		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['video_id' => $box['key']['id']]);
    +		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['video_id' => $box['key']['id']]);
     		if ($categories = $values['details/categories']) {
     			foreach (ze\ray::explodeAndTrim($categories) as $categoryId) {
    -				ze\row::insert(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['video_id' => $box['key']['id'], 'category_id' => $categoryId]);
    +				ze\row::insert(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['video_id' => $box['key']['id'], 'category_id' => $categoryId]);
     			}
     		}
     	}
    -	
     }
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_manager/classes/organizer/videos.php+61 9 modified
    @@ -33,6 +33,10 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     		$documentEnvelopesModuleIsRunning = ze\module::inc('zenario_document_envelopes_fea');
     		$languages = ze\dataset::centralisedListValues('zenario_document_envelopes_fea::getEnvelopeLanguages');
     		
    +		//If there are Vimeo videos, Zenario will load their privacy settings.
    +		//This will be done using 1 query with multiple IDs.
    +		$vimeoVideos = [];
    +
     		foreach ($panel['items'] as $id => &$item) {
     			if (!empty($item['thumbnail_id'])) {
     				$item['traits']['has_image'] = true;
    @@ -55,17 +59,65 @@ public function fillOrganizerPanel($path, &$panel, $refinerName, $refinerId, $mo
     				if ($parsed) {
     					$url = false;
     					if (strpos($parsed['host'], 'vimeo.com') !== false) {
    -						$vimeoVideoId = (int)str_replace('/', '', $parsed['path']);
    -						$videoData = zenario_videos_manager::getVimeoVideoData($vimeoVideoId);
    -						$privacy = $videoData['privacy']['view'] ?? '';
    -						$vimeoPrivacySettingsFormattedNicely = zenario_videos_manager::getVimeoPrivacySettingsFormattedNicely();
    +						$vimeoVideoId = $parsed['path'];
    +						if (substr($vimeoVideoId, 0, 1) == '/') {
    +							$vimeoVideoId = substr($vimeoVideoId, 1);
    +						}
    +
    +						//Remember the Zenario video ID for easier processing later.
    +						$vimeoVideos[$vimeoVideoId] = $id;
    +					}
    +				}
    +			}
    +		}
    +
    +		if (ze::setting('vimeo_access_token')) {
    +			$videosCount = count($vimeoVideos);
    +			if ($videosCount > 0) {
    +				//There appears to be a limit of IDs that can be passed to Vimeo,
    +				//around 100. If the page size is set to 200, make 2 requests.
    +				if ($videosCount > 100) {
    +					$preserveKeys = true;
    +					$videoIdsArray = [array_slice($vimeoVideos, 0, 100, $preserveKeys), array_slice($vimeoVideos, 100, 100, $preserveKeys)];
    +				} else {
    +					$videoIdsArray = [$vimeoVideos];
    +				}
    +
    +				$vimeoPrivacySettingsFormattedNicely = zenario_videos_manager::getVimeoPrivacySettingsFormattedNicely();
    +
    +				foreach ($videoIdsArray as $videos) {
    +					$videoData = zenario_videos_manager::getVimeoVideoDataForMultiple(array_keys($videos));
     					
    -						if ($privacy && array_key_exists($privacy, $vimeoPrivacySettingsFormattedNicely)) {
    -							$privacyString = $vimeoPrivacySettingsFormattedNicely[$privacy]['note'];
    -						} else {
    -							$privacyString = $this->phrase('Sorry, cannot show privacy setting');
    +					if (is_array($videoData) && !empty($videoData['data']) && count($videoData['data']) > 0) {
    +						foreach ($videoData['data'] as $video) {
    +							//Match the Vimeo ID to Zenario video ID...
    +							$videoId = str_replace('/videos/', '', $video['uri']);
    +							
    +							$itemId = $vimeoVideos[$videoId];
    +							//Handle unlisted videos, which have an additional string after the URL.
    +							//Vimeo response only contains the first part.
    +							if (!$itemId) {
    +								foreach ($vimeoVideos as $vimeoId => $zenarioId) {
    +									if (stristr($vimeoId, $videoId) === false) {
    +										continue;
    +									} else {
    +										$itemId = $zenarioId;
    +										break;
    +									}
    +								}
    +							}
    +
    +							$privacy = $video['privacy']['view'] ?? '';
    +						
    +							if ($privacy && array_key_exists($privacy, $vimeoPrivacySettingsFormattedNicely)) {
    +								$privacyString = $vimeoPrivacySettingsFormattedNicely[$privacy]['note'];
    +							} else {
    +								$privacyString = $this->phrase('Sorry, cannot show privacy setting');
    +							}
    +
    +							//... and populate the value.
    +							$panel['items'][$itemId]['video_privacy'] = $privacyString;
     						}
    -						$item['video_privacy'] = $privacyString;
     					}
     				}
     			}
    
  • zenario/modules/zenario_videos_manager/db_updates/updates.inc.php+12 0 modified
    @@ -18,6 +18,11 @@
     , <<<_sql
     	DROP TABLE IF EXISTS `[[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]video_categories`
     _sql
    +
    +, <<<_sql
    +	DROP TABLE IF EXISTS `[[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]category_video_link`
    +_sql
    +
     , <<<_sql
     	CREATE TABLE `[[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]video_categories` (
     		`video_id` int(10) unsigned NOT NULL,
    @@ -99,4 +104,11 @@
     	ADD COLUMN `language_id` varchar(10) DEFAULT NULL
     _sql
     
    +//Rename a table to have a less confusing name
    +); ze\dbAdm::revision(13
    +, <<<_sql
    +	RENAME TABLE `[[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]video_categories`
    +	TO `[[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]category_video_link`
    +_sql
    +
     );
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_manager/latest_revision_no.inc.php+1 1 modified
    @@ -27,4 +27,4 @@
      * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      */
     
    -define(ze::moduleName(__FILE__). '_LATEST_REVISION_NO', 12);
    +define(ze::moduleName(__FILE__). '_LATEST_REVISION_NO', 13);
    
  • zenario/modules/zenario_videos_manager/module_code.php+29 3 modified
    @@ -48,12 +48,12 @@ public static function deleteVideo($videoId) {
     		
     		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'videos', $videoId);
     		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'videos_custom_data', $videoId);
    -		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['video_id' => $videoId]);
    +		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['video_id' => $videoId]);
     	}
     	
     	public static function deleteCategory($categoryId) {
     		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'categories', $categoryId);
    -		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'video_categories', ['category_id' => $categoryId]);
    +		ze\row::delete(ZENARIO_VIDEOS_MANAGER_PREFIX . 'category_video_link', ['category_id' => $categoryId]);
     	}
     	
     	public static function getVimeoVideoData($vimeoVideoId) {
    @@ -74,6 +74,32 @@ public static function getVimeoVideoData($vimeoVideoId) {
     		$result = json_decode($result, true);
     		return $result;
     	}
    +
    +	public static function getVimeoVideoDataForMultiple($vimeoVideoIds) {
    +		$vimeoAccessToken = ze::setting('vimeo_access_token');
    +
    +		if (is_array($vimeoVideoIds) && count($vimeoVideoIds) > 0) {
    +			//Example of the format:
    +			//https://api.vimeo.com/videos?uris=/videos/111,/videos/222,/videos/333
    +			$link = 'https://api.vimeo.com/videos?uris=/videos/' . implode(',/videos/', $vimeoVideoIds);
    +			$params = [
    +				"Content-Type: application/json",
    +				"Authorization: Bearer " . $vimeoAccessToken
    +			];
    +			$options = [
    +				CURLOPT_CUSTOMREQUEST => 'GET',
    +				CURLOPT_HTTPHEADER => $params,
    +				CURLOPT_SSL_VERIFYPEER => 0,
    +				CURLOPT_SSL_VERIFYHOST => 0,
    +			];
    +			$result = ze\curl::fetch($link, false, $options);
    +
    +			$result = json_decode($result, true);
    +			return $result;
    +		}
    +
    +		return [];
    +	}
     	
     	public static function getVimeoVideoThumbnail($vimeoVideoUrl) {
     		$vimeoAccessToken = ze::setting('vimeo_access_token');
    @@ -103,7 +129,7 @@ public static function getVimeoPrivacySettingsFormattedNicely() {
     			],
     			'disable' => [
     				'label' => "Disable",
    -				'note' => "Hide video from <a href='vimeo.com' target='_blank'>vimeo.com</a>, but the video can still be embedded on external sites. Non-shareable.",
    +				'note' => "Hide video from vimeo.com, but the video can still be embedded on external sites. Non-shareable.",
     				'visitor_note' => "You may not share the link to this video"
     			],
     			'nobody' => [
    
  • zenario/modules/zenario_videos_manager/tuix/admin_boxes/site_settings__videos.yaml+5 1 modified
    @@ -23,6 +23,8 @@ site_settings:
                         redraw_onchange: true
                         pre_field_html: |
                             <div class="title"><label>Vimeo privacy settings:</label></div><br />
    +                    #Hidden as of 12 Jan 2022. --Marcin
    +                    hidden: true
                     vimeo_privacy_settings:
                         site_setting:
                             name: vimeo_privacy_settings
    @@ -39,7 +41,9 @@ site_settings:
                             unlisted:
                                 ord: 4
                         #Labels are set in php.
    -                    visible_if: lib.value('enable_vimeo_privacy_settings')
    +                    #Hidden as of 12 Jan 2022. --Marcin
    +                    hidden: true
    +                    #visible_if: lib.value('enable_vimeo_privacy_settings')
                         validation:
                             required_if_not_hidden: 'Please select at least 1 privacy setting.'
                     video_language_is_mandatory:
    
  • zenario/modules/zenario_videos_manager/tuix/admin_boxes/video.yaml+1 2 modified
    @@ -40,7 +40,6 @@ zenario_videos_manager__video:
                         label: "Privacy (Vimeo only):"
                         snippet:
                             html: ""
    -                    hidden: true
                     image:
                         label: 'Image:'
                         upload:
    @@ -87,4 +86,4 @@ zenario_videos_manager__video:
                         show_as_a_span: true
                         read_only: true
                         hidden: true
    -                    value: 'No categories found'
    +                    value: 'No categories found'
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_manager/tuix/organizer/categories.yaml+4 5 modified
    @@ -19,9 +19,9 @@ zenario_videos_manager:
                     number_of_videos:
                         title: No. of videos
                         table_join: |
    -                        [[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]video_categories AS vc
    -                        ON c.id = vc.category_id
    -                    db_column: COUNT(vc.video_id)
    +                        [[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]category_video_link AS cvl
    +                        ON c.id = cvl.category_id
    +                    db_column: COUNT(cvl.video_id)
                         always_show: true
                         align_right: true
                 item_buttons:
    @@ -50,5 +50,4 @@ zenario_videos_manager:
                         css_class: zenario_create_a_new
                         label: Create a category
                         admin_box:
    -                        path: zenario_videos_manager__category
    -            
    \ No newline at end of file
    +                        path: zenario_videos_manager__category
    \ No newline at end of file
    
  • zenario/modules/zenario_videos_manager/tuix/organizer/videos.yaml+4 5 modified
    @@ -49,10 +49,10 @@ zenario_videos_manager:
                     categories:
                         title: Categories
                         table_join: |
    -                        [[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]video_categories vc
    -                            ON v.id = vc.video_id
    +                        [[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]category_video_link cvl
    +                            ON v.id = cvl.video_id
                             LEFT JOIN [[DB_PREFIX]][[ZENARIO_VIDEOS_MANAGER_PREFIX]]categories c
    -                            ON vc.category_id = c.id
    +                            ON cvl.category_id = c.id
                         db_column: GROUP_CONCAT(c.name ORDER BY c.name SEPARATOR ', ')
                         width: xlarge
                         always_show: true
    @@ -104,5 +104,4 @@ zenario_videos_manager:
                         css_class: zenario_create_a_new
                         label: Add a video by URL
                         admin_box:
    -                        path: zenario_videos_manager__video
    -            
    +                        path: zenario_videos_manager__video
    \ No newline at end of file
    
  • zenario/styles/admin_grid_maker.css+11 0 modified
    @@ -51,6 +51,16 @@ ul.zenario_grids {
     	height: auto;
     }
     
    +.zenario_overflow_wrap {
    +    min-width: 100%;
    +    overflow-x: hidden;
    +}
    +
    +.zenario_overflow_wrap > .zenario_grids {
    +    background: white top left repeat-y;
    +    background-size: auto 25px;
    +}
    +
     .zenario_overflow_wrap > ul.zenario_grids:first-child {
     	min-height:400px;
     }
    @@ -72,6 +82,7 @@ li.zenario_grid_cell {
     .zenario_grid_sortable_target div {
     	height: 100%;
     	border: 2px dotted #008000;
    +	background-position: 0.5px 0;
     }
     
     .zenario_grids a.zenario_grid_sortable_target {
    
  • zenario/styles/admin_grid_maker.min.css+4 2 modified
    @@ -1,9 +1,11 @@
     body{margin:0;overflow:hidden}body.iframe{margin:0;padding:0;overflow-x:auto;overflow-y:hidden;background:#dfe7ec}.grid_maker_wrap{background:#333;font-family:'Verdana',​Arial;font-size:12px;color:#e2e2e2;padding:6px}
     #settings .ui-spinner-disabled{opacity:.7}#settings .ui-spinner-disabled a{display:none}#settings .ui-spinner span.zenario_grid_unit{position:relative;right:25px;top:2px}
     span.zenario_grid_setting_warning,span.zenario_grid_setting_warning input{background-image:none;background-color:pink}ul.zenario_grids{float:left;list-style-type:none;margin:0;padding:0 0 30px 0;height:auto}
    +.zenario_overflow_wrap{min-width:100%;overflow-x:hidden}.zenario_overflow_wrap>.zenario_grids{background:white top left repeat-y;background-size:auto 25px}
     .zenario_overflow_wrap>ul.zenario_grids:first-child{min-height:400px}li.zenario_grid_add,li.zenario_grid_cell{position:relative;float:left;min-height:50px;padding:0}
    -li.zenario_grid_add{cursor:pointer}li.zenario_grid_cell{cursor:move}.zenario_grid_sortable_target div{height:100%;border:2px dotted #008000}.zenario_grids a.zenario_grid_sortable_target{display:inline-block;float:left;margin-top:10px}
    -body.webkit .zenario_grids a.zenario_grid_sortable_target{height:60px}.zenario_grids a.zenario_grid_sortable_target div{display:block;width:100%;height:58px;padding:0;border:2px dotted #008000;background:#f6f6f6;box-sizing:border-box}
    +li.zenario_grid_add{cursor:pointer}li.zenario_grid_cell{cursor:move}.zenario_grid_sortable_target div{height:100%;border:2px dotted #008000;background-position:.5px 0}
    +.zenario_grids a.zenario_grid_sortable_target{display:inline-block;float:left;margin-top:10px}body.webkit .zenario_grids a.zenario_grid_sortable_target{height:60px}
    +.zenario_grids a.zenario_grid_sortable_target div{display:block;width:100%;height:58px;padding:0;border:2px dotted #008000;background:#f6f6f6;box-sizing:border-box}
     .zenario_grid_cell_size{color:#333}.zenario_grids .zenario_grids{background:url('../admin/images/10.png');outline:grey 1px solid}.zenario_grids .zenario_grid_cell .ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none;width:11px;height:18px;margin-right:2px;margin-top:-6px;background:url('../admin/images/grid_maker/icon-resize.png');cursor:e-resize}
     .zenario_grids .zenario_grid_resp_child .ui-resizable-handle{visibility:hidden}.ui-resizable-helper{text-align:center;font-family:'Trebuchet MS',​Arial;font-size:12px}
     body.zenario_grid_resizing_nest .ui-resizable-helper div.zenario_resizing_border,body.zenario_grid_resizing_space_cell .ui-resizable-helper div.zenario_resizing_border{border:2px dotted black}
    
  • zenario/styles/admin_organizer.css+0 1 modified
    @@ -5882,7 +5882,6 @@ table.table-bordered td
     	background-size: 14px 16px;
     	padding-right: 2px;
     	background-position: left center;
    -	float:left;
     }
     
     
    
  • zenario/styles/admin_organizer.min.css+1 1 modified
    @@ -554,7 +554,7 @@ table.table-bordered td{padding:4px}.organizer_item_image.zenario_file_item{back
     #organizer__box_wrap.zenario__content__panels__image_library #organizer__box_inner #organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row div.organizer_cell.listicon .organizer_list_view_icon{background-size:contain}
     .two_line_list_panel #organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row div.organizer_cell.listicon>div{height:100%}.two_line_list_panel #organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row div.organizer_cell.listicon .organizer_list_view_icon{height:30px}
     #organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row.organizer_tall_row_with_small_icon div.organizer_cell.listicon .organizer_inline_buttons,#organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row.organizer_tall_row_with_small_icon div.organizer_cell.listicon .organizer_inline_buttons div,#organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row.organizer_tall_row_with_small_icon div.organizer_cells_items .organizer_inline_buttons,#organizer_rightColumnContent .organizer_list_view_with_tall_rows div.organizer_row.organizer_tall_row_with_small_icon div.organizer_cells_items .organizer_inline_buttons div{margin:0;padding:0}
    -#organizer_rightColumnContent div.organizer_row div.organizer_cell span.listicon{display:inline-block;padding-left:16px;height:16px;background-size:14px 16px;padding-right:2px;background-position:left center;float:left}
    +#organizer_rightColumnContent div.organizer_row div.organizer_cell span.listicon{display:inline-block;padding-left:16px;height:16px;background-size:14px 16px;padding-right:2px;background-position:left center}
     .organizer_slidedown_view table td .slidedown_tags_title{width:40px;margin:0 0 10px 20px;display:block;float:left;color:#202020;margin:0 0 10px 20px}.organizer_slidedown_view table td .organizer_image_tags.slidedown_view{display:block;float:left}
     #row__module_description .zfab_row_inner .module_description *{color:#fff;font-size:11px}#row__module_description .zfab_row_inner .module_description ul{margin:15px 0 15px 30px;list-style-position:inside}
     #row__module_description .zfab_row_inner .module_description ul li{list-style:disc;margin:5px 0 5px 0}#row__module_description .zfab_row_inner .module_description p{margin-top:10px;margin-bottom:10px}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.