<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 1/1/16
 * Time: 8:35 PM
 */

const EXT_KEY = 'qfq';

// Feature Flags
const FEATURE_FORM_FILE_SYNC = false; // Enable automatic form sync between database and form files.

const PROJECT_PATH_PHP_FILE = 'qfq.project.path.php';

const CONFIG_QFQ_PHP = "config.qfq.php";   // QFQ configuration file: db access - deprecated
const CONFIG_QFQ_JSON = "qfq.json"; // QFQ configuration file: db access + what used to be in LocalConfig.php
const CONFIG_QFQ_JSON_EXAMPLE = "example.qfq.json";
const CONFIG_T3 = 'LocalConfiguration.php'; // T3 config file
const QFQ_DUMMY_PDF_PATH = 'typo3conf/ext/qfq/Resources/Public/dummyFiles/dummy.pdf';
const QFQ_DUMMY_EXCEL_PATH = 'typo3conf/ext/qfq/Resources/Public/dummyFiles/dummy.xlsx';
const QFQ_DUMMY_PNG_PATH = 'typo3conf/ext/qfq/Resources/Public/dummyFiles/dummy.png';
const QFQ_ICON_PATH = 'typo3conf/ext/qfq/Resources/Public/icons/';
const QFQ_ICON_DEFAULT_THUMBNAIL = 'no-image-icon.png';
const QFQ_IMG_BS_ZERO_COL_WIZARD_PATH = 'typo3conf/ext/qfq/Resources/Public/img/bsZeroColumnCheckExample.png';

const CONFIG_QFQ_IMAP = "imap.php";

const QFQ_TEMP_FILE_PATTERN = 'qfq.split.XXXXX';
const QFQ_TEMP_SOURCE = '.temp.source';

const QFQ_PREPEND_HIDDEN_ORIG = ".qfq.orig";

const MAX_LENGTH_IPV6 = 45;
const LENGTH_HEX_COLOR = 6; // 'ffeedd'
const SESSION_NAME = 'qfq';
const SESSION_FE_USER_UID = 'feUserUid';
const SESSION_FE_USER = 'feUser';
const SESSION_FE_USER_GROUP = 'feUserGroup';
const SESSION_BE_USER = 'beUser';
const SESSION_PAGE_LANGUAGE = 'pageLanguage';
const SESSION_PAGE_LANGUAGE_PATH = 'pageLanguagePath';
const SESSION_PAGE_ID = 'pageId';
const SESSION_STORE_PREFIX = 'store';
const TABLE_NAME_FORM = 'Form';
const TABLE_NAME_FORM_ELEMENT = 'FormElement';
const TABLE_NAME_SPLIT = 'Split';
const TABLE_NAME_FORM_SUBMIT_LOG = 'FormSubmitLog';

const TABLE_NAME_RECENT = 'Recent';
const TABLE_NAME_DIRTY = 'Dirty';
const API_MODE = 'mode';

// Form Mode
const FORM_LOAD = 'form_load';
const FORM_SAVE = 'form_save';
const FORM_UPDATE = 'form_update';
const FORM_DELETE = 'form_delete';
const FORM_DRAG_AND_DROP = 'form_drag_and_drop';
const FORM_REST = 'form_rest';

const FORM_PERMISSION_SIP = 'sip';
const FORM_PERMISSION_LOGGED_IN = 'logged_in';
const FORM_PERMISSION_LOGGED_OUT = 'logged_out';
const FORM_PERMISSION_ALWAYS = 'always';
const FORM_PERMISSION_NEVER = 'never';
const FORM_PERMISSION_REST = 'rest';
const FORM_BUTTON_NEW = 'new';
const FORM_BUTTON_DELETE = 'delete';
const FORM_BUTTON_CLOSE = 'close';
const FORM_BUTTON_SAVE = 'save';
const FORM_BUTTON_ISSUE = 'issue';
const FORM_BUTTON_FORM_EDIT = 'formEdit';
const FORM_BUTTON_FORM_VIEW = 'formView';
const FORM_BUTTON_FORM_ELEMENT_EDIT = 'formElementEdit';
const FORM_BUTTON_HISTORY = 'history';


const REPORT_SAVE = 'reportSave';
const REPORT_SAVE_FILE = 'reportSaveFile'; // 0|1 whether report is saved in file instead of DB

const F_BS_COLUMNS = 'bsColumns';

const F_BS_LABEL_COLUMNS = 'bsLabelColumns';
const F_BS_INPUT_COLUMNS = 'bsInputColumns';
const F_BS_NOTE_COLUMNS = 'bsNoteColumns';

const RETURN_URL = 'return_url';
const RETURN_SIP = 'return_sip';
const RETURN_ARRAY = 'return_array';

const SQL_FORM_ELEMENT_BY_ID = "SELECT * FROM `FormElement` AS fe WHERE `fe`.`id` = ?";
const SQL_FORM_ELEMENT_RAW = "SELECT * FROM `FormElement` AS `fe` WHERE `fe`.`formId` = ? AND `fe`.`deleted` = 'no' AND `fe`.`enabled`='yes' ORDER BY `fe`.`ord`, `fe`.`id`";
const SQL_FORM_ELEMENT_SPECIFIC_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM `FormElement` AS fe WHERE `fe`.`formId` = ? AND `fe`.`deleted` = 'no' AND FIND_IN_SET(`fe`.`class`, ? ) AND `fe`.`feIdContainer` = ? AND `fe`.`enabled`='yes' ORDER BY `fe`.`ord`, `fe`.`id`";
const SQL_FORM_ELEMENT_ALL_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM `FormElement` AS `fe` WHERE `fe`.`formId` = ? AND `fe`.`deleted` = 'no' AND FIND_IN_SET(`fe`.`class`, ? ) AND `fe`.`enabled`='yes' ORDER BY `fe`.`ord`, `fe`.`id`";
const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT `fe`.`id`, `fe`.`feIdContainer`, `fe`.`name`, `fe`.`value`, `fe`.`label`, `fe`.`type`, `fe`.`encode`, `fe`.`checkType`, `fe`.`checkPattern`, `fe`.`mode`, `fe`.`modeSql`, `fe`.`parameter`, `fe`.`dynamicUpdate` FROM `FormElement` AS fe, `Form` AS f WHERE `f`.`name` = ? AND `f`.`id` = `fe`.`formId` AND `fe`.`deleted` = 'no' AND `fe`.`class` = 'native' AND `fe`.`enabled`='yes' ORDER BY `fe`.`ord`, `fe`.`id`";
const SQL_FORM_ELEMENT_CONTAINER_TEMPLATE_GROUP = "SELECT `fe`.`id`, `fe`.`name`, `fe`.`label`, `fe`.`maxLength`, `fe`.`parameter` FROM `FormElement` AS fe, `Form` AS f WHERE `f`.`name` = ? AND `f`.`id` = `fe`.`formId` AND `fe`.`deleted` = 'no' AND `fe`.`class` = 'container' AND `fe`.`type`='templateGroup' AND `fe`.`enabled`='yes' ORDER BY `fe`.`ord`, `fe`.`id`";
const SQL_FORM_ELEMENT_TEMPLATE_GROUP_FE_ID = "SELECT * FROM `FormElement` AS fe WHERE `fe`.`id` = ? AND `fe`.`deleted` = 'no' AND `fe`.`class` = 'container' AND `fe`.`type`='templateGroup' AND `fe`.`enabled`='yes' ";
//const SQL_FORM_ELEMENT_NATIVE_TG_COUNT = "SELECT fe.*, IFNULL(feTg.maxLength,0) AS _tgCopies FROM FormElement AS fe LEFT JOIN FormElement AS feTg ON fe.feIdContainer=feTg.id AND feTg.deleted = 'no' AND feTg.class = 'container' AND feTg.type='templateGroup' AND feTg.enabled='yes' WHERE fe.formId = ? AND fe.deleted = 'no' AND fe.class = 'native' AND fe.enabled='yes'";
const SQL_FORM_ELEMENT_NATIVE_TG_COUNT = "SELECT `fe`.*, IFNULL(`feTg`.`maxLength`,0) AS _tgCopies FROM `FormElement` AS fe LEFT JOIN `FormElement` AS feTg ON `fe`.`feIdContainer`=`feTg`.`id` AND `feTg`.`deleted` = 'no' AND `feTg`.`class` = 'container' AND `feTg`.`type`='templateGroup' AND `feTg`.`enabled`='yes' WHERE `fe`.`formId` = ? AND `fe`.`deleted` = 'no' AND (`fe`.`class` = 'native' OR (`fe`.`class` = 'container' AND `fe`.`type`='pill')) AND `fe`.`enabled`='yes'";

const SQL_CHECK_CREATE_TABLE_PERMISSION = "CREATE TEMPORARY TABLE IF NOT EXISTS _perm_check (id INT);";
const SQL_CHECK_DROP_TABLE_PERMISSION = "DROP TABLE IF EXISTS _perm_check;";
const SQL_CHECK_DROP_FUNCTION_PERMISSION = "DROP FUNCTION IF EXISTS can_create_function_check;";
const SQL_CHECK_CREATE_FUNCTION_PERMISSION = "CREATE FUNCTION can_create_function_check() RETURNS INT BEGIN RETURN 1; END;";

const NAME_TG_COPIES = '_tgCopies';  // Number of templatesGroup copies to create on the fly. Also used in SQL_FORM_ELEMENT_NATIVE_TG_COUNT.
const FE_TG_INDEX = '_tgIndex'; // Index of the current copy of a templateGroup FE.


// Index wrap setup table
const WRAP_SETUP_TITLE = 'title';
const WRAP_SETUP_ELEMENT = 'element';
const WRAP_SETUP_LABEL = 'label';
const WRAP_SETUP_INPUT = 'input';
const WRAP_SETUP_NOTE = 'note';
const WRAP_SETUP_SUBRECORD = 'subrecord';
const WRAP_SETUP_IN_FIELDSET = 'inFieldset';
const WRAP_SETUP_IN_TEMPLATE_GROUP = 'inTemplateGroup';
const WRAP_SETUP_START = 'start';
const WRAP_SETUP_CLASS = 'class';
const WRAP_SETUP_END = 'end';

// dbQuerySimple
const ROW_REGULAR = "regular";
const ROW_IMPLODE_ALL = "implode_all";
const ROW_EXPECT_0 = "expect_0";
const ROW_EXPECT_1 = "expect_1";
const ROW_EXPECT_0_1 = "expect_0_1";
const ROW_EXPECT_GE_1 = "expect_ge_1";
const ROW_KEYS = "keys";

// KeyValueParser
const KVP_IF_VALUE_EMPTY_COPY_KEY = 'if_value_empty_copy_key';
const KVP_VALUE_GIVEN = 'value_given';
const KVP_MODE_ASSOC = 'assoc';
const KVP_MODE_ALL = 'all';

// https://lib2.colostate.edu/wildlife/atoz.php?letter=ALL
// JSON encoded messages thrown through an exception:
const ERROR_MESSAGE_TO_USER = 'toUser'; // always shown to the user.
const ERROR_MESSAGE_TO_DEVELOPER = 'support'; // Message to help the developer to understand the problem.
const ERROR_MESSAGE_TO_DEVELOPER_SANITIZE = 'support_sanitize'; // Typically 'true' or missing. If 'false' then content of 'support' won't be html encoded.
const ERROR_MESSAGE_OS = 'os'; // Error message from the OS - like 'file not found' or specific SQL problem
const ERROR_MESSAGE_HTTP_STATUS = 'httpStatus'; // HTTP Status Code to report
const ERROR_MESSAGE_LOG_ERROR = 'logError'; // Indicates if the error should be logged (boolean)
const ERROR_MESSAGE_DB_INDEX = 'dbIndex'; // Indicates the used DB where the exception has been thrown.

// QFQ Error Codes
const ERROR_UNKNOW_SANITIZE_CLASS = 1001;
const ERROR_WIPE_NOT_IMPLEMENTED_FOR_STORE = 1002;
const ERROR_CODE_SHOULD_NOT_HAPPEN = 1003;
const ERROR_QUIT_QFQ_REGULAR = 1004;
const ERROR_PHP_VERSION = 1005;
const ERROR_SIP_INVALID = 1006;
const ERROR_MISSING_RECORD_ID = 1007;
const ERROR_IN_SQL_STATEMENT = 1008;
const ERROR_MISSING_REQUIRED_PARAMETER = 1009;
const ERROR_FE_NESTED_TOO_MUCH = 1010;
const ERROR_BROKEN_PARAMETER = 1011;
const ERROR_FE_USER_UID_CHANGED = 1012;
const ERROR_SIP_NOT_FOUND = 1013;
const ERROR_SIP_NOT_ALLOWED_AS_PARAM = 1014;
const ERROR_SIP_NEEDED_FOR_THIS_FORM = 1015;
const ERROR_SIP_EXIST_BUT_OTHER_PARAM_GIVEN_BY_CLIENT = 1016;
const ERROR_USER_NOT_LOGGED_IN = 1017;
const ERROR_USER_LOGGED_IN = 1018;
const ERROR_FORM_FORBIDDEN = 1019;
const ERROR_FORM_UNKNOWN_PERMISSION_MODE = 1020;
const ERROR_FORMELEMENT_EDITOR_TYPE = 1021;
const ERROR_TOKEN_MISSING = 1022;
const ERROR_RECURSION_TOO_DEEP = 1023;
const ERROR_CHECKBOXMODE_UNKNOWN = 1024;
const ERROR_MISSING_SQL1 = 1025;
const ERROR_CHECKBOX_EQUAL = 1026;
const ERROR_MISSING_ITEM_LIST = 1027;
const ERROR_UNKNOWN_FORM_RENDER = 1028;
const ERROR_NAME_LABEL_EMPTY = 1029;
const ERROR_BROKEN_JSON_STRUCTURE = 1030;
const ERROR_DEBUG = 1031;
const ERROR_UNKNOWN_MODE = 1032;
const ERROR_NOT_IMPLEMENTED = 1033;
const ERROR_RESERVED_KEY_NAME = 1034;
const ERROR_MISSING_FORM = 1035;
const ERROR_UNKNOWN_FORWARD_MODE = 1036;
const ERROR_MISSING_MESSAGE_FAIL = 1037;
const ERROR_MISSING_EXPECT_RECORDS = 1038;
const ERROR_MISSING_HIDDEN_FIELD_IN_SIP = 1039;
const ERROR_MISSING_PARAMETER_FILE = 1040;
const ERROR_NO_BE_USER_LOGGED = 1041;
const ERROR_UNKNOWN_CHECKTYPE = 1042;
const ERROR_PATTERN_VIOLATION = 1043;
const ERROR_RECORDID_0_FORBIDDEN = 1044;
const ERROR_LOG_NOT_WRITABLE = 1045;
const ERROR_UNNOWN_STORE = 1046;
const ERROR_GET_INVALID_STORE = 1047;
const ERROR_SET_STORE_ZERO = 1048;
const ERROR_INVALID_OR_MISSING_PARAMETER = 1050;
const ERROR_UNKNOWN_SQL_LOG_MODE = 1051;
const ERROR_FORM_NOT_FOUND = 1052;
const ERROR_DATE_TIME_FORMAT_NOT_RECOGNISED = 1053;
const ERROR_SANITIZE_INVALID_VALUE = 1054;
const ERROR_REQUIRED_VALUE_EMPTY = 1055;
const ERROR_DATE_UNEXPECTED_FORMAT = 1056;
const ERROR_UNEXPECTED_TYPE = 1057;
const ERROR_NOT_APPLICABLE = 1058;
const ERROR_FORMELEMENT_TYPE = 1059;
const ERROR_MISSING_OPEN_DELIMITER = 1060;
const ERROR_MISSING_CLOSE_DELIMITER = 1061;
const ERROR_EXPECTED_ARRAY = 1062;
const ERROR_REPORT_FAILED_ACTION = 1063;
const ERROR_MISSING_CONTENT = 1064;
const ERROR_MISSING_TABLE_NAME = 1065;
const ERROR_MISSING_TABLE = 1066;
const ERROR_RECORD_NOT_FOUND = 1067;
const ERROR_INVALID_EDITOR_PROPERTY_NAME = 1068;
const ERROR_UNKNOWN_ESCAPE_MODE = 1069;
const ERROR_MISSING_CONFIG_INI_VALUE = 1070;
const ERROR_SENDMAIL = 1071;
const ERROR_SENDMAIL_MISSING_VALUE = 1072;
const ERROR_OVERWRITE_RECORD_ID = 1073;
const ERROR_MISSING_SLAVE_ID_DEFINITION = 1074;
const ERROR_MISSING_INTL = 1075;
const ERROR_HTML_TOKEN_TOO_SHORT = 1076;
const ERROR_MISSING_PRINTF_ARGUMENTS = 1077;
const ERROR_MISSING_DEFINITON = 1078;
const ERROR_QFQ_VERSION = 1079;
const ERROR_PLAY_SQL_FILE = 1080;
const ERROR_MISSING_FILE_NAME = 1081;
const ERROR_MAX_FILE_SIZE_TOO_BIG = 1082;
const ERROR_SMALLER_THAN_MIN = 1083;
const ERROR_LARGER_THAN_MAX = 1084;
const ERROR_INVALID_DECIMAL_FORMAT = 1085;
const ERROR_INVALID_DATE = 1086;
const ERROR_PLAY_SQL_MULTIQUERY = 1087;
const ERROR_QFQ_UPDATE_API = 1088;
const ERROR_UNPROTECTED_FOLDER = 1089;
const ERROR_INVALID_WGET_CMD = 1090;
const ERROR_MISSING_KEY_VALUE = 1091;
const ERROR_MISSING_ALERT = 1092;
const ERROR_DOUBLE_USAGE_ALERT_AND_MESSAGE_FAIL = 1093;
const ERROR_IMPORT_REGION_NOT_SUPPORTED = 1094;
const ERROR_IMAP = 1095;
const ERROR_IMAP_OAUTH_REAUTH = 1096; // delegated OAuth2 refresh rejected: interactive re-auth needed

// Subrecord
const SUBRECORD_MESSAGE = 'subrecord_message';
const ERROR_SUBRECORD_MISSING_COLUMN_ID = 1100;
const ERROR_SUBRECORD_DETAIL_COLUMN_NOT_FOUND = 'Column not found in primary record or current row (or missed & to indicate a constant?)';

// Store
const ERROR_STORE_VALUE_ALREADY_CODPIED = 1200;
const ERROR_STORE_KEY_EXIST = 1201;

// I/O Error
const ERROR_IO_COPY = 1300;
const ERROR_IO_ZIP_OPEN = 1301;
const ERROR_IO_RMDIR = 1302;
const ERROR_IO_WRITE = 1303;
const ERROR_IO_OPEN = 1304;
const ERROR_IO_UNLINK = 1305;
const ERROR_IO_FILE_EXIST = 1306;
const ERROR_IO_RENAME = 1307;
const ERROR_IO_INVALID_LINK = 1308;
const ERROR_IO_DIR_EXIST_AS_FILE = 1309;
const ERROR_IO_CHDIR = 1310;
const ERROR_IO_CREATE_FILE = 1311;
const ERROR_IO_COPY_FILE = 1312;
const ERROR_IO_FILE_NOT_FOUND = 1313;
const ERROR_IO_CHMOD = 1314;
const ERROR_IO_READ_FILE = 1315;
const ERROR_IO_WRITE_FILE = 1316;

const ERROR_PATH_INVALID = 1317;

const ERROR_PDF_SPLIT = 1320;
const ERROR_PDF2JPEG = 1321;

//Report
const ERROR_UNKNOWN_LINK_QUALIFIER = 1400;
const ERROR_UNDEFINED_RENDER_CONTROL_COMBINATION = 1401;
const ERROR_MISSING_REQUIRED_DELETE_QUALIFIER = 1402;
const ERROR_MISSING_VALUE = 1403;
const ERROR_INVALID_VALUE = 1404;
const ERROR_MULTIPLE_DEFINITION = 1405;
const ERROR_MULTIPLE_URL_PAGE_MAILTO_DEFINITION = 1406;
const ERROR_UNKNOWN_TOKEN = 1407;
const ERROR_TOO_FEW_PARAMETER_FOR_SENDMAIL = 1408;
const ERROR_TOO_MANY_PARAMETER = 1409;
const ERROR_INVALID_SAVE_PDF_FILENAME = 1410;
const ERROR_TWIG_COLUMN_NOT_UNIQUE = 1411;
const ERROR_DOUBLE_DEFINITION = 1412;
const ERROR_INVALID_SAVE_ZIP_FILENAME = 1413;
const ERROR_NUMERIC_ALIAS = 1414;

// Upload
const ERROR_UPLOAD = 1500;
const ERROR_UPLOAD_TOO_BIG = 1501;
const ERROR_UPLOAD_FILE_TYPE = 1502;
const ERROR_UPLOAD_GET_MIME_TYPE = 1503;
const ERROR_UPLOAD_UNKNOWN_ACTION = 1504;
const ERROR_NO_TARGET_PATH_FILE_NAME = 1505;
const ERROR_UPLOAD_FILES_BROKEN = 1506;
const ERROR_UNKNOWN_EXCEL_IMPORT_TYPE = 1507;

// LDAP / typeahead
const ERROR_LDAP_CONNECT = 1600;
const ERROR_MISSING_TYPE_AHEAD_LDAP_SEARCH = 1601;
const ERROR_MISSING_TYPE_AHEAD_LDAP_SEARCH_PREFETCH = 1602;
const ERROR_LDAP_BIND = 1603;
const ERROR_MISSING_TYPE_AHEAD_SQL_PREFETCH = 1604;

// Download
const ERROR_DOWNLOAD_CREATE_NEW_FILE = 1700;
const ERROR_DOWNLOAD_NO_FILES = 1701;
const ERROR_DOWNLOAD_NOTHING_TO_DO = 1702;
const ERROR_DOWNLOAD_UNEXPECTED_MIME_TYPE = 1703;
const ERROR_DOWNLOAD_UNEXPECTED_NUMBER_OF_SOURCES = 1704;
const ERROR_DOWNLOAD_FILE_NOT_READABLE = 1705;
const ERROR_DOWNLOAD_FOPEN_BLOCKED = 1706;
const ERROR_DOWNLOAD_JSON_CONVERT = 1707;
const ERROR_DOWNLOAD_MERGE_FAILED = 1708;
const ERROR_DOWNLOAD_CONVERT_FAILED = 1709;

// Excel
const ERROR_EXCEL_POSITION_ARGUMENT_EMPTY = 1800;
const ERROR_EXCEL_INVALID_COORDINATES = 1801;
const ERROR_EXCEL_JOIN_EXCEEDS_TABLE = 1802;
const ERROR_EXCEL_NO_PRIMARY_KEY_ID = 1802;

// KeyValueParser
const ERROR_KVP_VALUE_HAS_NO_KEY = 1900;

// DB Errors
const ERROR_DB_OPEN = 2000;
const ERROR_DB_EXECUTE = 2001;
const ERROR_DB_PREPARE = 2002;
const ERROR_DB_BIND = 2003;
const ERROR_DB_QUERY = 2004;
const ERROR_DB_GENERIC_CHECK = 2005;
const ERROR_DB_TOO_FEW_ROWS = 2006;
const ERROR_DB_TOO_MANY_ROWS = 2007;
const ERROR_DB_COUNT_DO_NOT_MATCH = 2008;
const ERROR_DB_CLOSE_MYSQLI_RESULT = 2009;
const ERROR_DB_CLOSE_MYSQLI_STMT = 2010;
const ERROR_DB_UNKNOWN_COLUMN = 2011;
const ERROR_DB_UNKNOWN_COMMAND = 2012;

const ERROR_DB_COLUMN_NOT_FOUND_IN_TABLE = 2014;
const ERROR_DB_SET_CHARSET = 2015;
const ERROR_DB_MULTI_QUERY_FAILED = 2016;

const ERROR_DB_HISTORY_DATA = 2017;

// onArray
const ERROR_SUBSTITUTE_FOUND = 2100;

// Dirty
const ERROR_DIRTY_MISSING_FORM_IN_SIP = 2200;
const ERROR_DIRTY_DELETE_RECORD = 2201;
const ERROR_DIRTY_UNKNOWN_ACTION = 2202;
const ERROR_DIRTY_MISSING_LOCK = 2203;
const ERROR_DIRTY_ALREADY_LOCKED = 2204;
const ERROR_DIRTY_RECORD_MODIFIED = 2205;

// Language
const ERROR_LANGUAGE_NOT_CONFIGURED_IN_QFQ = 2300;

// Session
const ERROR_MISSING_SESSIONNAME = 2400;
const ERROR_QFQ_SESSION_MISSING = 2401;
const ERROR_SESSION_BROKEN_SCRIPT_PATH = 2402;
const ERROR_MISSING_COOKIE = 2403;
const ERROR_SESSION_EXPIRED = 2404;

const ERROR_HTML2PDF_MISSING_CONFIG = 2500;
const ERROR_HTML2PDF_WKHTML_NOT_EXECUTABLE = 2501;
const ERROR_HTML2PDF_WKHTML_FAILED = 2502;

// Thumbnail
const ERROR_THUMBNAIL_RENDER = 2600;

// Drag and Drop
const ERROR_DND_EMPTY_REORDER_SQL = 2700;

// Form
const ERROR_FORM_RESERVED_NAME = 2800;
const ERROR_FORM_INVALID_NAME = 2801;
const ERROR_FORM_INVALID_COLUMN_TYPE = 2802;

// Import (Excel, ODS, ...)
const ERROR_IMPORT_MISSING_EXPLICIT_TYPE = 2900;
const ERROR_IMPORT_LIST_SHEET_NAMES = 2901;

// REST
const ERROR_FORM_REST = 3000;
const ERROR_REST_AUTHORIZATION = 3001;
const ERROR_REST_INVALID_ID = 3002;
const ERROR_REST_API_CALL = 3010;

// Tablesorter
const ERROR_TABLESORTER_SIP_NOT_FOUND = 3100;
const ERROR_TABLESORTER_INVALID_CHAR = 3101;
const ERROR_TABLESORTER_NAME_TOO_LONG = 3102;
const ERROR_SETTING_RECORD_TOO_MUCH = 3103;
const ERROR_SETTING_SYSTEM = 3104;

// Encryption
const ERROR_MISSING_ENCRYPTION_KEY = 3105;
const ERROR_INVALID_DATABASE_FIELD_TYPE = 3106;
const ERROR_DATABASE_FIELD_TO_SMALL = 3107;
const ERROR_INVALID_ENCRYPTION_METHOD = 3108;
const ERROR_VARIABLE_INVALID_ENCRYPTION_METHOD = 3109;
const ERROR_NO_STORE_FOUND = 3110;
const ERROR_ENCRYPT_CLASS = 3111;

const ERROR_MSG_TOO_BIG = "** Data removed: too big **";

// Chat
const ERROR_MISSING_CHAT_DATA = 3200;
const ERROR_INVALID_CHAT_DATA = 3201;
const ERROR_CREATE_MESSENGER_TOKEN = 3202;

// Renderer

const ERROR_RENDERER_MISSING_ARGUMENT = 4001;

// SQL Caching
const ERROR_SQL_CACHE_UNKNOWN_PARAMETER = 4200;
const ERROR_SQL_CACHE_UNKNOWN_STORE = 4201;
const ERROR_SQL_CACHE_UNKNOWN_STORE_KEY = 4202;


//
// Store Names: Identifier
//
const STORE_ADDITIONAL_FORM_ELEMENTS = "AF"; // Internal Store to collect FormElements. Typically for 'hidden' elements of radio and checkbox. Helps render those elements at the end of the whole form rendering.
const STORE_BEFORE = "B"; // selected record from primary table before any modifcations.
const STORE_CLIENT = "C"; // Client: POST variable, if not found: GET variable
const STORE_TABLE_DEFAULT = "D"; // definition of primary table.
const STORE_DEFAULT = STORE_TABLE_DEFAULT; // definition of default values
const STORE_EMPTY = "E"; // value: '', might helpful if variable is not defined and should result in an empty string instead of {{...}} (cause not replaced)
const STORE_FORM = "F";  // form, still not saved in database
const STORE_LDAP = "L";
const STORE_TABLE_COLUMN_TYPES = "M"; // column types of primary table.
const STORE_PARENT_RECORD = "P"; // on autoCron, copy/paste & multi forms the recent record of the outer query (multi).
const STORE_RECORD = "R"; // selected record from primary table.
const STORE_SIP = "S"; // SIP
const STORE_TYPO3 = "T"; // Typo3 > Page content record > bodytext
const STORE_USER = "U"; // Like STORE_EXTRA, but for user use.
const STORE_VAR = "V"; // Generic Vars
#const STORE_WIPE_SIP = "W"; // Like SIP, but will remove the entry after reading from STORE_SIP as well as from SESSION-SIP table.
const STORE_EXTRA = "X"; // Persistent Store: contains arrays! Used by QFQ system - not used by user.
const STORE_SYSTEM = "Y"; // various system values like db connection credentials
const STORE_ZERO = "0"; // value: 0, might helpful if variable is empty but used in an SQL statement, which might produce a SQL error otherwise if substituted with an empty string
const STORE_ACCESS = 'A';
const STORE_WEB = 'W';
const STORE_USE_DEFAULT = "FSRVD";
const STORE_EXTRA_INITIAL_STORE = 'initial_store';  // A dedicated key for initials data of stores


// SANITIZE Classifier
const SANITIZE_ALLOW_AUTO = "auto"; // Default for FormElements
const SANITIZE_ALLOW_ALNUMX = "alnumx";
const SANITIZE_ALLOW_DIGIT = "digit";
const SANITIZE_ALLOW_NUMERICAL = "numerical";
const SANITIZE_ALLOW_EMAIL = "email";
const SANITIZE_ALLOW_PATTERN = "pattern";
const SANITIZE_ALLOW_ALLBUT = "allbut";
const SANITIZE_ALLOW_ALL = "all";
const SANITIZE_DEFAULT = SANITIZE_ALLOW_DIGIT; // for {{variable}} expressions without checkType
const SANITIZE_DEFAULT_OF_STORE = [
    STORE_FORM => SANITIZE_ALLOW_DIGIT,
    STORE_SIP => SANITIZE_ALLOW_ALL,
    STORE_RECORD => SANITIZE_ALLOW_ALL,
    STORE_BEFORE => SANITIZE_ALLOW_ALL,
    STORE_PARENT_RECORD => SANITIZE_ALLOW_ALL,
    STORE_TABLE_DEFAULT => SANITIZE_ALLOW_ALL,
    STORE_TABLE_COLUMN_TYPES => SANITIZE_ALLOW_ALL,
    STORE_CLIENT => SANITIZE_ALLOW_DIGIT,
    STORE_TYPO3 => SANITIZE_ALLOW_ALL,
    STORE_VAR => SANITIZE_ALLOW_ALL,
    STORE_ZERO => SANITIZE_ALLOW_ALL,
    STORE_EMPTY => SANITIZE_ALLOW_ALL,
    STORE_SYSTEM => SANITIZE_ALLOW_ALL,
    STORE_EXTRA => SANITIZE_ALLOW_ALL,
    STORE_USER => SANITIZE_ALLOW_ALL,
    STORE_ACCESS => SANITIZE_ALLOW_ALL,
    STORE_WEB => SANITIZE_ALLOW_ALL,
    STORE_LDAP => SANITIZE_ALLOW_ALL,
    STORE_ADDITIONAL_FORM_ELEMENTS => SANITIZE_ALLOW_ALL,
];

const SANITIZE_EXCEPTION = 'exception';
const SANITIZE_EMPTY_STRING = 'empty string';

const SANITIZE_VIOLATE = '!!';

const SANITIZE_ALLOW_ALNUMX_MESSAGE = 'Allowed characters: 0...9, [latin character] (incl accents), *@-_.m;: /()';
const SANITIZE_ALLOW_DIGIT_MESSAGE = 'Allowed characters: 0...9';
const SANITIZE_ALLOW_NUMERICAL_MESSAGE = 'Allowed characters: 0...9 and .+-';
const SANITIZE_ALLOW_EMAIL_MESSAGE = 'Invalid email format';
const SANITIZE_ALLOW_ALLBUT_MESSAGE = 'Forbidden characters: ^[]{}%\#';

const SANITIZE_TYPE_MESSAGE_VIOLATE_EMPTY = 'e';
const SANITIZE_TYPE_MESSAGE_VIOLATE_ZERO = '0';
const SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS = 'c';

const PATTERN_ALNUMX = '^[@*\-_\.,;: \/\(\)a-zA-Z0-9ÀÈÌÒÙàèìòùÁĆÉÍÓÚÝáćéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçČčĐđŠšŽžßø]*$';
const PATTERN_DIGIT = '^[\d]*$';
const PATTERN_NUMERICAL = '^[\d.+-]*$';
const PATTERN_EMAIL = '^$|^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$';
const PATTERN_ALLBUT = '^[^\[\]{}%\\\\#]*$';
const PATTERN_ALL = '.*';

const PATTERN_IMAGE_TAG_AND_SOURCE = '/<img[^>]+src=["\']([^"\']+)["\']/';

//
// Store: Definitions / Members
//

// URL variables
const CLIENT_FORM = 'form';
const CLIENT_SIP = 's';
const CLIENT_RECORD_ID = 'r';
const CLIENT_PAGE_ID = 'id';
const CLIENT_PAGE_TYPE = 'type';
const CLIENT_PAGE_LANGUAGE = 'L';
const CLIENT_UPLOAD_FE_NAME = 'name';

const CLIENT_SIP_FOR_FORM = '_sipForForm';
const CLIENT_FE_NAME = '_feName';
const CLIENT_TYPO3VARS = '_sipForTypo3Vars';

// ALL $_SERVER variables: http://php.net/manual/en/reserved.variables.server.php
// The following exist and might be the most used ones.
const CLIENT_SCRIPT_URL = 'SCRIPT_URL';
const CLIENT_SCRIPT_URI = 'SCRIPT_URI';
const CLIENT_HTTP_COOKIE = 'HTTP_COOKIE';
const CLIENT_HTTP_HOST = 'HTTP_HOST';
const CLIENT_HTTP_USER_AGENT = 'HTTP_USER_AGENT';
const CLIENT_SERVER_NAME = 'SERVER_NAME';
const CLIENT_SERVER_ADDRESS = 'SERVER_ADDR';
const CLIENT_SERVER_PORT = 'SERVER_PORT';
const CLIENT_REMOTE_ADDRESS = 'REMOTE_ADDR';
const CLIENT_HTTP_X_REAL_IP = 'HTTP_X_REAL_IP';
const CLIENT_REQUEST_SCHEME = 'REQUEST_SCHEME';
const CLIENT_REQUEST_METHOD = 'REQUEST_METHOD';
const CLIENT_SCRIPT_FILENAME = 'SCRIPT_FILENAME';
const CLIENT_QUERY_STRING = 'QUERY_STRING';
const CLIENT_REQUEST_URI = 'REQUEST_URI';
const CLIENT_SCRIPT_NAME = 'SCRIPT_NAME';
const CLIENT_PHP_SELF = 'PHP_SELF';

const REQUEST_METHOD_GET = 'GET';
const REQUEST_METHOD_POST = 'POST';
const REQUEST_METHOD_PUT = 'PUT';
const REQUEST_METHOD_DELETE = 'DELETE';

// _COOKIE
const CLIENT_COOKIE_QFQ = 'cookieQfq';

// T3 Bodytext Keywords
const TYPO3_FORM = CLIENT_FORM;
const TYPO3_RECORD_ID = CLIENT_RECORD_ID;
const TYPO3_BE_USER_LOGGED_IN = 'beUserLoggedIn';   // 'yes' | 'no'
const TYPO3_BE_USER = 'beUser';   // 'yes' | 'no'
const TYPO3_BE_USER_EMAIL = 'beUserEmail';
const TYPO3_BE_USER_UID = 'beUserUid';
const TYPO3_FE_USER = 'feUser';
const TYPO3_FE_USER_EMAIL = 'feUserEmail';
const TYPO3_FE_USER_UID = 'feUserUid';
const TYPO3_FE_USER_GROUP = 'feUserGroup';
const TYPO3_TT_CONTENT_UID = 'ttcontentUid';
const TYPO3_TT_CONTENT_SUBHEADER = 'ttcontentSubheader';

const TYPO3_PAGE_ID = 'pageId';
const TYPO3_PAGE_ALIAS = 'pageAlias';
const TYPO3_PAGE_SLUG = 'pageSlug';
const TYPO3_PAGE_TITLE = 'pageTitle';
const TYPO3_PAGE_TYPE = 'pageType';
const TYPO3_PAGE_ABSTRACT = 'pageAbstract';
const TYPO3_PAGE_DESCRIPTION = 'pageDescription';
const TYPO3_PAGE_KEYWORDS = 'pageKeywords';
const TYPO3_PAGE_NAV_TITLE = 'pageNavTitle';
const TYPO3_VERSION = 't3Version';
const TYPO3_TOKEN_REPORT_LINE = 'parsed';

const TYPO3_PAGE_LANGUAGE = SESSION_PAGE_LANGUAGE;
const TYPO3_PAGE_LANGUAGE_PATH = SESSION_PAGE_LANGUAGE_PATH;
const TYPO3_DEBUG_SHOW_BODY_TEXT = 'debugShowBodyText';
const TYPO3_SQL_LOG_ABSOLUTE = 'sqlLog';
const TYPO3_SQL_LOG_MODE = 'sqlLogMode';

// TYPO3 LocalConfiguration DB keys
const TYPO3_DB_USER = 'user';
const TYPO3_DB_PASSWORD = 'password';
const TYPO3_DB_HOST = 'host';
const TYPO3_DB_NAME = 'dbname';

// TYPO3 LocalConfiguration structure keys
const TYPO3_CONF_DB = 'DB';
const TYPO3_CONF_SYS = 'SYS';
const TYPO3_CONF_EXTENSIONS = 'EXTENSIONS';
const TYPO3_CONF_CONNECTIONS = 'Connections';
const TYPO3_CONF_DEFAULT = 'Default';
const TYPO3_CONF_SYSTEM_MAINTAINERS = 'systemMaintainers';
const TYPO3_CONF_SITENAME = 'sitename';

// TYPO3 PackageStates.php keys
const TYPO3_PACKAGES = 'packages';
const TYPO3_PACKAGE_PATH = 'packagePath';

// TODO: Check OIDC Constants with kputyr
const TYPO3_OIDC_BE_UID = 'oidcBeUid';
const TYPO3_OIDC_BE_PROVIDER = 'oidcBeProvider';
const TYPO3_OIDC_BE_PROVIDER_ID = 'oidcBeProviderId';
const TYPO3_OIDC_BE_RESOURCE_ID = 'oidcBeResourceId';
const TYPO3_OIDC_BE_SUB = 'oidcBeSub';
const TYPO3_OIDC_BE_EMAIL = 'oidcBeEmail';
const TYPO3_OIDC_BE_EMAIL_VERIFIED = 'oidcBeEmailVerified';
const TYPO3_OIDC_BE_NAME = 'oidcBeName';
const TYPO3_OIDC_BE_GIVEN_NAME = 'oidcBeGivenName';
const TYPO3_OIDC_BE_FAMILY_NAME = 'oidcBeFamilyName';

const TYPO3_OIDC_FE_UID = 'oidcFeUid';
const TYPO3_OIDC_FE_PROVIDER = 'oidcFeProvider';
const TYPO3_OIDC_FE_PROVIDER_ID = 'oidcFeProviderId';
const TYPO3_OIDC_FE_RESOURCE_ID = 'oidcFeResourceId';
const TYPO3_OIDC_FE_SUB = 'oidcFeSub';
const TYPO3_OIDC_FE_EMAIL = 'oidcFeEmail';
const TYPO3_OIDC_FE_EMAIL_VERIFIED = 'oidcFeEmailVerified';
const TYPO3_OIDC_FE_NAME = 'oidcFeName';
const TYPO3_OIDC_FE_GIVEN_NAME = 'oidcFeGivenName';
const TYPO3_OIDC_FE_FAMILY_NAME = 'oidcFeFamilyName';

const TYPO3_OIDC_PROVIDER = 'oidcProvider';
const TYPO3_OIDC_RESOURCE_ID = 'oidcResourceId';
const TYPO3_OIDC_SUB = 'oidcSub';
const TYPO3_OIDC_EMAIL = 'oidcEmail';

const TYPO3_OIDC_EMAIL_VERIFIED = 'oidcEmailVerified';
const TYPO3_OIDC_GIVEN_NAME = 'oidcGivenName';
const TYPO3_OIDC_FAMILY_NAME = 'oidcFamilyName';

// Deprecated: legacy config - still used to read old configuration file.
const SYSTEM_DB_USER = 'DB_USER';
const SYSTEM_DB_SERVER = 'DB_SERVER';
const SYSTEM_DB_PASSWORD = 'DB_PASSWORD';
const SYSTEM_DB_NAME = 'DB_NAME';

// Recent DB config
const SYSTEM_DB_1_USER = 'DB_1_USER';
const SYSTEM_DB_1_SERVER = 'DB_1_SERVER';
const SYSTEM_DB_1_PASSWORD = 'DB_1_PASSWORD';
const SYSTEM_DB_1_NAME = 'DB_1_NAME';

const SYSTEM_ENCRYPTION_KEY = 'ENCRYPTION_KEY';
const SYSTEM_ENCRYPTION_METHOD = 'encryptionMethod';

const SYSTEM_DB_INIT = 'init';

const SYSTEM_DB_INDEX_DATA = "indexData";
const SYSTEM_DB_INDEX_QFQ = "indexQfq";

// Automatically filled by QFQ
const SYSTEM_DB_NAME_DATA = 'dbNameData';
const SYSTEM_DB_NAME_QFQ = 'dbNameQfq';
const SYSTEM_DB_NAME_T3 = 'dbNameT3';

const SYSTEM_QFQ_LOG_PATHFILENAME = 'qfqLog'; // absolute or relative to app
const SYSTEM_MAIL_LOG_PATHFILENAME = 'mailLog';  // absolute or relative to app
const SYSTEM_MERGE_LOG_PATHFILENAME = 'mergeLog';  // absolute or relative to app
const SYSTEM_SQL_LOG_PATHFILENAME = 'sqlLog';  // absolute or relative to app
const SYSTEM_IMAP_LOG_PATHFILENAME = 'imapLog';  // absolute or relative to app

const SYSTEM_SQL_LOG_MODE = 'sqlLogMode'; // Mode, which statements to log.
const SYSTEM_SQL_LOG_MODE_AUTOCRON = 'sqlLogModeAutoCron'; // Mode, which statements to log in AutoCron Environments.

const SYSTEM_MISSING_FILE_MODE = 'missingFile'; // user dummy or Throw error when missing PDF
const SYSTEM_MISSING_FILE_MODE_AUTO = 'auto';
const SYSTEM_MISSING_FILE_MODE_DUMMY = 'dummy';
const SYSTEM_MISSING_FILE_MODE_ERROR = 'error';

const SYSTEM_IMAP_LOG_MODE = 'imapLogMode'; // Mode, which statements to log.

const SYSTEM_SIP_ERROR_LOG_MODE = 'sipErrorLogMode'; // Mode, which statements to log.
const SYSTEM_SIP_ERROR_LOG_MODE_ALL = 'all';
const SYSTEM_SIP_ERROR_LOG_MODE_NONE = 'none';
const SYSTEM_SIP_ERROR_LOG_MODE_FE_USER = 'fe_user';

const FORCE_RUN_PAGE_SLUG_MIGRATION_CHECK = 'FORCE_RUN_PAGE_SLUG_MIGRATION_CHECK';

const SYSTEM_FORM_SUBMIT_LOG_MODE = 'formSubmitLogMode';
const FORM_SUBMIT_LOG_MODE_ALL = 'all';
const FORM_SUBMIT_LOG_MODE_NONE = 'none';
const FORM_SUBMIT_LOG_MODE_MODIFY = 'modify';

const SYSTEM_DATE_FORMAT = 'dateFormat';
const SYSTEM_DATE_TIME_PICKER_TYPE = 'dateTimePickerType';
const SYSTEM_REDIRECT_ALL_MAIL_TO = 'redirectAllMailTo';
const SYSTEM_PID_USER = 'pIdUser';
const SYSTEM_EMAIL_USER = 'emailUser';

const SYSTEM_UPLOAD_TYPE = 'uploadType';

const SYSTEM_UPLOAD_ACTION = 'uploadAction';
const SYSTEM_UPLOAD_ACTION_DENY_PROTECT = 'denyProtect';
const SYSTEM_UPLOAD_ACTION_DENY_ACROBAT = 'denyAcrobatOnly';
const SYSTEM_UPLOAD_ACTION_UN_PROTECT = 'unProtect';
const SYSTEM_UPLOAD_ACTION_NONE = 'none';

const SYSTEM_THROW_GENERAL_ERROR = 'throwExceptionGeneralError';
const SYSTEM_FLAG_PRODUCTION = 'flagProduction';
const SYSTEM_RENDER = 'render';
const SYSTEM_RENDER_SINGLE = 'single';
const SYSTEM_RENDER_BOTH = 'both';
const SYSTEM_RENDER_API = 'api';
const SYSTEM_REPORT_AS_FILE_AUTO_EXPORT = 'reportAsFileAutoExport';
const SYSTEM_FORCE_SMTP_SENDER = 'forceSmtpSender';

const SYSTEM_SHOW_DEBUG_INFO = 'showDebugInfo';
const SYSTEM_SHOW_DEBUG_INFO_YES = 'yes';
const SYSTEM_SHOW_DEBUG_INFO_AUTO = 'auto'; // Remains on value 'auto' as long as there is no BE User logged in. In other words: 'auto'='no'. #5031
const SYSTEM_SHOW_DEBUG_INFO_DOWNLOAD = 'download';

const SYSTEM_REPORT_MIN_PHP_VERSION = 'reportMinPhpVersion';
const SYSTEM_REPORT_MIN_PHP_VERSION_YES = 'yes';
const SYSTEM_REPORT_MIN_PHP_VERSION_AUTO = 'auto'; // Remains on value 'auto' as long as there is no BE User logged in. In other words: 'auto'='no'.
const MIN_PHP_VERSION = "7.2.0"; // Currently the PHP Spreadsheet library needs at least 7.2
const SYSTEM_CSS_CLASS_QFQ_CONTAINER = 'cssClassQfqContainer';
const SYSTEM_CSS_CLASS_QFQ_FORM = 'cssClassQfqForm';
const SYSTEM_CSS_CLASS_QFQ_FORM_PILL = 'cssClassQfqFormPill';
const SYSTEM_CSS_CLASS_QFQ_FORM_BODY = 'cssClassQfqFormBody';

const SYSTEM_CSS_CLASS_COLUMN_ID = 'cssClassColumnId';

// Textmessages used for Form validation.
const SYSTEM_FORM_DATA_PATTERN_ERROR = 'formDataPatternError';
const SYSTEM_FORM_DATA_REQUIRED_ERROR = 'formDataRequiredError';
const SYSTEM_FORM_DATA_MATCH_ERROR = 'formDataMatchError';
const SYSTEM_FORM_DATA_ERROR = 'formDataError';

const SYSTEM_FORM_BS_COLUMNS = 'formBsColumns';

const SYSTEM_FORM_BS_LABEL_COLUMNS = 'formBsLabelColumns';
const SYSTEM_FORM_BS_INPUT_COLUMNS = 'formBsInputColumns';
const SYSTEM_FORM_BS_NOTE_COLUMNS = 'formBsNoteColumns';

const SYSTEM_BASE_URL = 'baseUrl';
const SYSTEM_HTTP_ORIGIN = 'httpOrigin';
const SYSTEM_BASE_URL_LANG = 'baseUrlLang';
const SYSTEM_QFQ_VERSION_API_TOKEN = 'qfqVersionApiToken';
const SYSTEM_T3_SITE_NAME = 't3SiteName';
const SYSTEM_QFQ_VERSION = 'qfqVersion';

const FAILED_TO_SET_BASE_URL = 'failed.to.set.baseUrl';

const SYSTEM_PASWORD_HASH_TYPE = 'PASSWORD_HASH_TYPE';

const SYSTEM_SEND_E_MAIL_OPTIONS = 'sendEMailOptions';

const SYSTEM_EDIT_FORM_PAGE = 'editFormPage';

const SYSTEM_LDAP_1_RDN = 'LDAP_1_RDN'; // Credentials to access LDAP
const SYSTEM_LDAP_1_PASSWORD = 'LDAP_1_PASSWORD'; // Credentials to access LDAP

const SYSTEM_ESCAPE_TYPE_DEFAULT = 'escapeTypeDefault';
const SYSTEM_SECURITY_VARS_HONEYPOT = 'securityVarsHoneypot'; // Fake variables
const SYSTEM_SECURITY_VARS_HONEYPOT_NAMES = 'email,username,password'; // Fake variables

const SYSTEM_SECURITY_ATTACK_DELAY = 'securityAttackDelay'; // Detected attack causes x seconds delay
const SYSTEM_SECURITY_ATTACK_DELAY_DEFAULT = 5; // Detected attack causes x seconds delay
const SYSTEM_SECURITY_SHOW_MESSAGE = 'securityShowMessage'; // Detected attack shows an error message
const SYSTEM_SECURITY_GET_MAX_LENGTH = 'securityGetMaxLength'; // Trim every character (before conversion) to SECURITY_GET_MAX_LENGTH chars;
const SYSTEM_SECURITY_GET_MAX_LENGTH_DEFAULT = 50; // Default max length for get variables
const SYSTEM_SECURITY_FAILED_AUTH_DELAY = 'securityFailedAuthDelay'; // Failed auth causes x seconds delay

const GET_EXTRA_LENGTH_TOKEN = '_';

const SYSTEM_LABEL_ALIGN = 'labelAlign';
const SYSTEM_LABEL_ALIGN_LEFT = 'left';

const SYSTEM_FIELDSET_CLASS = 'fieldsetClass';
const SYSTEM_FIELDSET_CLASS_DEFAULT = 'qfq-fieldset';

const SYSTEM_EXTRA_BUTTON_INFO_INLINE = 'extraButtonInfoInline';
const SYSTEM_EXTRA_BUTTON_INFO_BELOW = 'extraButtonInfoBelow';
const SYSTEM_EXTRA_BUTTON_INFO_POSITION = 'extraButtonInfoPosition';
const SYSTEM_EXTRA_BUTTON_INFO_POSITION_AUTO = 'auto';
const SYSTEM_EXTRA_BUTTON_INFO_POSITION_BELOW = 'below';
const SYSTEM_EXTRA_BUTTON_INFO_CLASS = 'extraButtonInfoClass';

const SYSTEM_FORM_EDIT_BUTTON_DEFAULT = 'formEditButtonDefault';

const SYSTEM_FORM_VIEW_BUTTON_DEFAULT = 'formViewButtonDefault';
const SYSTEM_FORM_HISTORY_BUTTON_DEFAULT = 'formHistoryButtonDefault';

const SYSTEM_SAVE_BUTTON_DEFAULT = 'saveButtonDefault';
const SYSTEM_SAVE_BUTTON_TEXT = 'saveButtonText';
const SYSTEM_SAVE_BUTTON_TOOLTIP = 'saveButtonTooltip';
const SYSTEM_SAVE_BUTTON_CLASS = 'saveButtonClass';
const SYSTEM_SAVE_BUTTON_GLYPH_ICON = 'saveButtonGlyphIcon';
const SYSTEM_SAVE_BUTTON_CLASS_ON_CHANGE = 'saveButtonClassOnChange';

const SYSTEM_CLOSE_BUTTON_DEFAULT = 'closeButtonDefault';
const SYSTEM_CLOSE_BUTTON_TEXT = 'closeButtonText';
const SYSTEM_CLOSE_BUTTON_TOOLTIP = 'closeButtonTooltip';
const SYSTEM_CLOSE_BUTTON_CLASS = 'closeButtonClass';
const SYSTEM_CLOSE_BUTTON_GLYPH_ICON = 'closeButtonGlyphIcon';

const SYSTEM_DELETE_BUTTON_DEFAULT = 'deleteButtonDefault';
const SYSTEM_DELETE_BUTTON_TEXT = 'deleteButtonText';
const SYSTEM_DELETE_BUTTON_TOOLTIP = 'deleteButtonTooltip';
const SYSTEM_DELETE_BUTTON_CLASS = 'deleteButtonClass';
const SYSTEM_DELETE_BUTTON_GLYPH_ICON = 'deleteButtonGlyphIcon';

const SYSTEM_NEW_BUTTON_DEFAULT = 'newButtonDefault';
const SYSTEM_NEW_BUTTON_TEXT = 'newButtonText';
const SYSTEM_NEW_BUTTON_TOOLTIP = 'newButtonTooltip';
const SYSTEM_NEW_BUTTON_CLASS = 'newButtonClass';
const SYSTEM_NEW_BUTTON_GLYPH_ICON = 'newButtonGlyphIcon';

const SYSTEM_NOTE_BUTTON_TEXT = 'noteButtonText';
const SYSTEM_NOTE_BUTTON_CLASS = 'noteButtonClass';


const SYSTEM_DB_UPDATE = 'update';
const SYSTEM_DB_UPDATE_ALWAYS = 'always';
const SYSTEM_DB_UPDATE_ONCE = 'once';
const SYSTEM_DB_UPDATE_NEVER = 'never';
const SYSTEM_DB_UPDATE_AUTO = 'auto';

const SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS = 'recordLockTimeoutSeconds';
const SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS_DEFAULT = 900; // 15 mins

const SYSTEM_SESSION_TIMEOUT_SECONDS = 'sessionTimeoutSeconds';

const SYSTEM_FILE_MAX_FILE_SIZE = 'maxFileSize';
const SYSTEM_MAX_IMAGE_DIMENSION = 'maxImageDimension';

const SYSTEM_COOKIE_LIFETIME = 259200; // 3 days. Should be more than  SYSTEM_SESSION_TIMEOUT_SECONDS_DEFAULT, in case the user setup's a higher value.

// Deprecated, replaced by SYSTEM_FILL_STORE_SYSTEM_BY_SQ
const SYSTEM_VAR_ADD_BY_SQL = 'VAR_ADD_BY_SQL'; // since 1.12.17

const SYSTEM_FILL_STORE_SYSTEM_CUSTOM = 'custom';
const SYSTEM_FILL_STORE_SYSTEM_BY_SQL = 'fillStoreSystemBySql';
const SYSTEM_FILL_STORE_SYSTEM_ERROR_MSG = 'fillStoreSystemBySqlErrorMsg';
const SYSTEM_FILL_STORE_SYSTEM_BY_SQL_ROW = 'fillStoreSystemBySqlRow';
const SYSTEM_FILL_STORE_SYSTEM_BY_SQL_ROW_ERROR_MSG = 'fillStoreSystemBySqlRowErrorMsg';

const SYSTEM_FILL_STORE_SYSTEM_BY_SQL_ROW_VARIABLE = 'fillStoreSystemBySqlRowVariable';

const SYSTEM_FILL_STORE_SYSTEM_BY_SQL_ROW_VARIABLE_ERROR_MSG = 'fillStoreSystemBySqlRowVariableErrorMsg';
const SYSTEM_FILL_STORE_SYSTEM_KEYWORD_NAME = 'name';
const SYSTEM_FILL_STORE_SYSTEM_KEYWORD_VALUE = 'value';


const SYSTEM_FORM_LANGUAGE = 'formLanguage';

const SYSTEM_FORM_LANGUAGE_A_ID = 'formLanguageAId';
const SYSTEM_FORM_LANGUAGE_A_LABEL = 'formLanguageALabel';

const SYSTEM_FORM_LANGUAGE_B_ID = 'formLanguageBId';
const SYSTEM_FORM_LANGUAGE_B_LABEL = 'formLanguageBLabel';

const SYSTEM_FORM_LANGUAGE_C_ID = 'formLanguageCId';
const SYSTEM_FORM_LANGUAGE_C_LABEL = 'formLanguageCLabel';

const SYSTEM_FORM_LANGUAGE_D_ID = 'formLanguageDId';
const SYSTEM_FORM_LANGUAGE_D_LABEL = 'formLanguageDLabel';

const SYSTEM_ENTER_AS_SUBMIT = 'enterAsSubmit';
const SYSTEM_SHOW_ID_IN_FORM_TITLE = 'showIdInFormTitle';
const SYSTEM_INPUT_CLEAR_ME = 'clearMe';
const SYSTEM_REMEMBER_LAST_PILL = 'rememberLastPill';
const SYSTEM_SHOW_HISTORY = 'showHistory';
const SYSTEM_VALIDATE_FORM_ELEMENT = 'validateFormElementParameter';
const SYSTEM_CMD_WKHTMLTOPDF = 'cmdWkhtmltopdf';
const SYSTEM_CMD_QFQPDF = 'cmdQfqpdf';
const SYSTEM_CMD_INKSCAPE = 'cmdInkscape';
const SYSTEM_CMD_CONVERT = 'cmdConvert';
const SYSTEM_CMD_PDF2SVG = 'cmdPdf2svg';
const SYSTEM_CMD_PDFTOCAIRO = 'cmdPdftocairo';
const SYSTEM_CMD_QPDF = 'cmdQpdf';
const SYSTEM_CMD_GS = 'cmdGs';
const SYSTEM_CMD_PDFUNITE = 'cmdPdfunite';
const SYSTEM_CMD_IMG2PDF = 'cmdImg2pdf';
const SYSTEM_CMD_HEIF_CONVERT = 'cmdHeifConvert';
const SYSTEM_CMD_PDF2PS = 'cmdPdf2ps';
const SYSTEM_CMD_PS2PDF = 'cmdPs2pdf';
const SYSTEM_CMD_WGET = 'cmdWget';
const SYSTEM_CMD_PDF_INFO = 'cmdPdfInfo';
const SYSTEM_CMD_PDF_TO_TEXT = 'cmdPdfToText';

const SYSTEM_EMAIL_SYNC = 'emailSync';
const SYSTEM_DO_NOT_LOG_COLUMN_DEFAULT = 'password';
// Thumbnail
const SYSTEM_THUMBNAIL_DIR_SECURE_REL_TO_APP = 'thumbnailDirSecure';
const SYSTEM_THUMBNAIL_DIR_PUBLIC_REL_TO_APP = 'thumbnailDirPublic';

const SYSTEM_DOCUMENTATION_QFQ = 'documentation';
const SYSTEM_DOCUMENTATION_QFQ_URL = 'http://docs.qfq.io';

const SYSTEM_IMAGE_UPLOAD_DIR = 'imageUploadDir';
const SYSTEM_CACHE_DIR_SECURE = 'cacheDirSecure';
const SYSTEM_CACHE_DIR_SECURE_DEFAULT = 'fileadmin/protected/cache';
const SYSTEM_CACHE_PURGE_FILES_OLDER_DAYS = 'cachePurgeFilesOlderDays';
const SYSTEM_CACHE_PURGE_FILES_OLDER_DAYS_DEFAULT = '365';

const SYSTEM_UPLOAD_DIR_SECURE_DEFAULT = 'fileadmin/protected/upload';
const PROTECTED_UPLOAD_DIR = 'fileadmin/protected';

const MARKER_ONCE_A_DAY = 'qfq.markerOncePerDay';


// Not stored in config.qfq.php, but used in STORE_SYSTEM
// Information for: Log / Debug / Exception
const SYSTEM_SQL_RAW = 'sqlRaw';  // Type: SANITIZE_ALL / String. SQL Query (before substitute). Useful for error reporting.
const SYSTEM_SQL_FINAL = 'sqlFinal'; //  Type: SANITIZE_ALL / String. SQL Query (after substitute). Useful for error reporting.
const SYSTEM_SQL_COUNT = 'sqlCount'; //  Type: SANITIZE_DIGIT / Int.Number of rows in SQL ResultSet. Useful for error reporting.
const SYSTEM_SQL_PARAM_ARRAY = 'sqlParamArray'; //  Type: SANITIZE_ALL / Parameter of prepared SQL Statement. Useful for error reporting.
const SYSTEM_FORM = CLIENT_FORM;                        // '<formName> / <formId>'
const SYSTEM_FORM_ELEMENT = 'formElement';              // '<formElementName> / <formElementeId>'
const SYSTEM_FORM_ELEMENT_ID = 'formElementId';              // '<formElementName> / <formElementeId>'
const SYSTEM_FORM_ELEMENT_COLUMN = 'formElementColumn'; // '<columnname of current processed formElement>'
const SYSTEM_FORM_ELEMENT_MESSAGE = 'formElementMessage'; // '<columnname of current processed formElement>'
const SYSTEM_REPORT_COLUMN_INDEX = 'reportColumnIndex'; // Index of SQL-column processed at the moment.
const SYSTEM_REPORT_COLUMN_NAME = 'reportColumnName'; // Name of SQL-column processed at the moment.
const SYSTEM_REPORT_COLUMN_VALUE = 'reportColumnValue'; // Value of SQL-column processed at the moment.
const SYSTEM_REPORT_FULL_LEVEL = 'reportFullLevel'; // Full level of current report row. E.g.: 10.20.1. Used for error reports.
const SYSTEM_MESSAGE_DEBUG = 'messageDebug';
const SYSTEM_DOWNLOAD_POPUP = 'hasDownloadPopup'; // Marker which is set to 'true' if there is at least one Download Link rendered
const SYSTEM_REPORT_LINE = 'reportLine';
const DOWNLOAD_POPUP_REQUEST = 'true';
const DOWNLOAD_POPUP_REPLACE_TEXT = '#downloadPopupReplaceText#';
const DOWNLOAD_POPUP_REPLACE_TITLE = '#downloadPopupReplaceTitle#';
const DOWNLOAD_POPUP_REPLACE_MODE = '#downloadPopupReplaceMode#';
const SYSTEM_DRAG_AND_DROP_JS = 'hasDragAndDropJS';
const SYSTEM_SQL_DIRECT_DOWNLOAD = 'sqlDirect'; // INI textarea: token = "SQL Query"
const DIRECT_DOWNLOAD_TOKEN_PREFIX = 'd/';
const DIRECT_DOWNLOAD_SQL = 'sql';
const DIRECT_DOWNLOAD_ERROR = 'error';
const DIRECT_DOWNLOAD_PARAMS = 'params';
const SYSTEM_EDIT_INLINE_REPORTS = 'editInlineReports';
const SYSTEM_EDIT_INLINE_REPORT_DARK_THEME = 'editInlineReportDarkTheme';
const SYSTEM_UNIT_TEST_FORM_CONTENT = 'unitTestFormContent';

const SYSTEM_PARAMETER_LANGUAGE_FIELD_NAME = 'parameterLanguageFieldName';
const CSS_REQUIRED_RIGHT = 'required-right';
const CSS_REQUIRED_LEFT = 'required-left';

// die folgenden Elemente sind vermutlich nicht noetig, wenn Store Klassen globale Vars benutzt.
//const SYSTEM_FORM_DEF = 'formDefinition'; // Type: SANITIZE_ALNUMX / AssocArray. Final form to process. Useful for error reporting.
//const SYSTEM_FORM_ELEMENT_DEF = 'formElementDefinition'; // Type: SANITIZE_ALL / AssocArray. Formelement which are processed at the moment. Useful for error reporting.
//const SYSTEM_FORM_ELEMENT_FIELD = 'formElementField'; // Type: SANITIZE_ALNUMX / String. Fieldname of processed Formelement. Useful for error reporting.

const SYSTEM_QFQ_PROJECT_PATH = 'qfqProjectPath';
const SYSTEM_DO_NOT_LOG_COLUMN = 'doNotLogColumn';
const SYSTEM_PROTECTED_FOLDER_CHECK = 'protectedFolderCheck';
const SYSTEM_WEBSOCKET_URL = 'websocketUrl';
const SYSTEM_MESSENGER_GROUP = 'messengerGroup';
const SYSTEM_MESSENGER_PUBLISH_URL = 'messengerPublishUrl';
const SYSTEM_JITSI_BASE_URL = 'jitsiBaseUrl';
const MESSENGER_DEFAULT_GROUP = 'qfq';
const MESSENGER_TOKEN_FIELD_PUB = 'pub';
const MESSENGER_TOKEN_FIELD_SUB = 'sub';
const MESSENGER_TOKEN_FIELD_GROUP = 'group';

// AI gateway (self hosted LLM behind LiteLLM/vLLM) - see Documentation-develop/AI_INFRASTRUCTURE.md
const SYSTEM_AI_ENABLED = 'aiEnabled';
const SYSTEM_AI_GATEWAY_URL = 'aiGatewayUrl';
const SYSTEM_AI_GATEWAY_API_KEY = 'aiGatewayApiKey';
const SYSTEM_AI_MODEL_DEFAULT = 'aiModelDefault';
const SYSTEM_AI_TIMEOUT_SECONDS = 'aiTimeoutSeconds';
// Max generated (completion) tokens per request. For reasoning models this also covers the
// 'thinking' tokens, so it caps a runaway reasoning loop. Per request, not per chat/session.
const SYSTEM_AI_MAX_TOKENS = 'aiMaxTokens';
// Hard wall-clock cap (seconds) for one streaming generation. The stream read 'timeout' is only
// an IDLE timeout; a continuously streaming reasoning loop never goes idle, so this bounds it.
const SYSTEM_AI_MAX_STREAM_SECONDS = 'aiMaxStreamSeconds';
const AI_MODEL_DEFAULT = 'qfq-default';
const AI_TIMEOUT_SECONDS_DEFAULT = 60;
const AI_MAX_TOKENS_DEFAULT = 8192;
const AI_MAX_STREAM_SECONDS_DEFAULT = 300;
// RAG retrieval service (chatbot context). See Documentation-develop/AI_INFRASTRUCTURE.md
const SYSTEM_AI_RAG_URL = 'aiRagUrl';
// Optional separate virtual key for the RAG service (use when it runs on a different gateway VM
// than the LLM). Empty -> reuse SYSTEM_AI_GATEWAY_API_KEY (same-VM setup). The retrieval service
// validates the key against its own LiteLLM.
const SYSTEM_AI_RAG_API_KEY = 'aiRagApiKey';
const AI_RAG_DEFAULT_K = 8;
// AI defaults set in the extension config and inherited down to the FormElement. The
// FE.parameter overrides by PRESENCE of the key (even an empty value), so e.g. 'aiPrompt='
// on the FE clears an inherited global prompt. Same key strings as the FE_AI_* params.
const SYSTEM_AI_RAG_SOURCE = 'aiRagSource';
const SYSTEM_AI_RAG_ACL = 'aiRagAcl';
const SYSTEM_AI_RAG_K = 'aiRagK';
const SYSTEM_AI_PROMPT = 'aiPrompt';
const SYSTEM_AI_CHAT_ALLOW_GENERAL = 'aiChatAllowGeneralKnowledge';
const SYSTEM_AI_THINKING = 'aiThinking';

const SYSTEM_RENDERER = 'renderer';

const SYSTEM_SUBRECORD_EMPTY = 'subrecordEmpty';

const SYSTEM_RECENT_LOG = 'recentLog';
const SYSTEM_FILE_NAME_TO_LOWER = 'fileNameToLower';

const RECENT_TYPE_FORM_OPEN = 'form open';
const RECENT_TYPE_SWITCH_USER = 'switch user';
const EXTRA_ENABLE_SWITCH = 'enableSwitch';
const EXTRA_COLUMN_NAME_AlIAS_SLUG = 'columnNameAliasSlug';
const EXTRA_FORM_SUBMIT_LOG_ID = 'formSubmitLogId';
const MODE_HTML = 'html';
const MODE_JSON = 'json';

const MSG_HEADER = 'header';
const MSG_CONTENT = 'content';
const MSG_ERROR_CODE = 'errorCode';

const SIP_TOKEN_LENGTH = 13; // length of string returned by `uniqid()`
const SIP_SIP = CLIENT_SIP;  // s
const SIP_RECORD_ID = CLIENT_RECORD_ID; // r
const SIP_TARGET_URL = '_targetUrl'; // URL where to jump after delete()
const SIP_MODE_ANSWER = '_modeAnswer'; // Mode how delete() will answer to client: MODE_HTML, MODE_JSON
const SIP_FORM = CLIENT_FORM;
const SIP_FORM_ID = 'formId';
const SIP_SHOW_HISTORY_FE_USER_SET = 'showHistoryFeUserSet';
const SIP_TABLE = 'table'; // delete a record from 'table'
const SIP_URLPARAM = 'urlparam';
const SIP_SIP_URL = 'sipUrl';
const SIP_MAKE_URLPARAM_UNIQ = '_makeUrlParamUniq'; // SIPs for 'new records' needs to be uniq per TAB! Therefore add a uniq parameter
const SIP_DOWNLOAD_PARAMETER = '_b64_download'; // Parameter name, filled in SIP, to hold all download element parameter.

const SIP_PREFIX_BASE64 = '_b64';

const SIP_EXCLUDE_ID = 'id';
const SIP_EXCLUDE_TYPE = 'type';
const SIP_EXCLUDE_L = 'L';
const SIP_EXCLUDE_XDEBUG_SESSION_START = 'XDEBUG_SESSION_START';

const SIP_MODE_SAVE = 'mode';
const SAVE_MODE_DB_UPDATE = 'modeDbUpdate';
const DB_UPDATE_INPUT_PREFIX = 'qfq_table_';
// FURTHER: all extracted params from 'urlparam
const SIP_DB_INDEX_USED = '_dbIndexUsed';

const ACTION_KEYWORD_SLAVE_ID = 'slaveId';
const VAR_RANDOM = 'random';
const VAR_FILE_DESTINATION = 'fileDestination';
const VAR_FILE_KEY = 'pathFileNameKey';
const VAR_SLAVE_ID = ACTION_KEYWORD_SLAVE_ID;
const VAR_FILENAME = 'filename'; // Original filename of an uploaded file.
const VAR_FILENAME_ONLY = 'filenameOnly'; // Original filename of an uploaded file, without directories.
const VAR_FILENAME_BASE = 'filenameBase'; // Original filename of an uploaded file, without the extension.
const VAR_FILENAME_EXT = 'filenameExt'; // Extension of the original filename of an uploaded file, .
const VAR_FILE_MIME_TYPE = 'mimeType';
const VAR_FILE_SIZE = 'fileSize';
const VAR_ALL_REQUIRED_GIVEN = 'allRequiredGiven'; // If all required FE are given: 1, else: 0. If there is no required FE: 1
const VAR_TAG_ID = 'tagId';
const VAR_TAG_VALUE = 'tagValue';
const VAR_AUTH_RESULT = 'authResult';

// PHP class AiHandler / Api/aiHandler.php
const AI_API_SIP = 'sip';
const AI_API_MODE = '_ai_mode';
const AI_API_INPUT = '_ai_input';
const AI_API_TARGET_LANGUAGE = '_ai_target_language';
const AI_API_REFERENCE = '_ai_reference';
const AI_API_FORMAT = '_ai_format';
const AI_API_HISTORY = '_ai_history';
const AI_API_PRIOR_SOURCES = '_ai_sources';
const AI_API_STREAM = '_ai_stream';
const AI_API_THINKING = '_ai_thinking';
const AI_FORMAT_HTML = 'html';
const AI_FORMAT_TEXT = 'text';
const API_AI_CONTENT = 'content';
const API_AI_SOURCES = 'sources';

const AI_MODE_IMPROVE = 'improve';
const AI_MODE_GENERATE = 'generate';
const AI_MODE_TRANSLATE = 'translate';
const AI_MODE_CHAT = 'chat';
const AI_INPUT_MAX_LENGTH = 100000;
const AI_CONTEXT_MAX_LENGTH = 60000;
const AI_CHAT_HISTORY_MAX_MESSAGES = 8;
const AI_CHAT_HISTORY_MAX_CHARS = 6000;
const AI_CHAT_SOURCES_MAX = 40;
const AI_RAG_QUERY_MAX_CHARS = 2000;

// --- Internal & wire keys shared across the AI classes (AiHandler / RagService / AiService) ---
// AI gateway (OpenAI-compatible) request/response JSON keys, role values, chat path.
const AI_GW_MODEL = 'model';
const AI_GW_MESSAGES = 'messages';
const AI_GW_ROLE = 'role';
const AI_GW_CONTENT = 'content';
const AI_GW_MESSAGE = 'message';
const AI_GW_CHOICES = 'choices';
const AI_GW_DELTA = 'delta';
const AI_GW_FINISH_REASON = 'finish_reason';
const AI_GW_FINISH_LENGTH = 'length';
const AI_GW_REASONING_CONTENT = 'reasoning_content';
const AI_GW_USAGE = 'usage';
const AI_GW_COMPLETION_TOKENS = 'completion_tokens';
const AI_GW_TOTAL_TOKENS = 'total_tokens';
const AI_GW_STREAM = 'stream';
const AI_GW_STREAM_OPTIONS = 'stream_options';
const AI_GW_INCLUDE_USAGE = 'include_usage';
const AI_GW_MAX_TOKENS = 'max_tokens';
const AI_GW_CHAT_TEMPLATE_KWARGS = 'chat_template_kwargs';
const AI_GW_ENABLE_THINKING = 'enable_thinking';
const AI_GW_ROLE_SYSTEM = 'system';
const AI_GW_ROLE_USER = 'user';
const AI_GW_ROLE_ASSISTANT = 'assistant';
const AI_GW_PATH_CHAT = '/v1/chat/completions';
// SSE wire tokens (gateway upstream stream + the aiHandler.php SSE output).
const AI_SSE_DATA_PREFIX = 'data:';
const AI_SSE_DONE = '[DONE]';
const AI_SSE_EVENT_PREFIX = 'event: ';
// Internal stream delta / SSE event types (AiService onDelta -> AiHandler -> endpoint emit).
const AI_STREAM_REASONING = 'reasoning';
const AI_STREAM_CONTENT = 'content';
const AI_STREAM_DONE = 'done';
const AI_STREAM_ERROR = 'error';
const AI_STREAM_TOKENS = 'tokens';
// RAG retrieval service /retrieve request + response keys.
const AI_RAG_REQ_QUERY = 'query';
const AI_RAG_REQ_ACL = 'acl';
const AI_RAG_REQ_K = 'k';
const AI_RAG_REQ_USER_LOGIN = 'user_login';
const AI_RAG_RESP_CHUNKS = 'chunks';
// RAG chunk / cited-source fields.
const AI_RAG_CHUNK_TITLE = 'title';
const AI_RAG_CHUNK_URL = 'url';
const AI_RAG_CHUNK_EXTERNAL_ID = 'external_id';
const AI_RAG_CHUNK_CONTENT = 'content';
const AI_RAG_CHUNK_SIMILARITY = 'similarity';
const AI_RAG_CHUNK_UPDATED_ON = 'updated_on';
// ACL resolve structure (RagService::parseAcl / AiHandler::resolveRagTargets).
const AI_ACL_TARGETS = 'targets';
const AI_ACL_MODE = 'mode';
const AI_ACL_LOGIN = 'login';
// Shared source-name + project-scope keys (retrieve payload, ACL target, chunk field).
const AI_RAG_SOURCE = 'source';
const AI_RAG_PROJECTS = 'projects';

// PHP class Typeahead
const TYPEAHEAD_API_QUERY = '_ta_query';  // Name of parameter in API call of typeahead.php?query=...&s=... - See also FE_TYPE_AHEAD_SQL
const TYPEAHEAD_API_PREFETCH = '_ta_prefetch';  // Name of parameter in API call of typeahead.php?prefetch=...&s=... - See also FE_TYPE_AHEAD_SQL
const TYPEAHEAD_API_SIP = 'sip';  // Name of parameter in API call of typeahead.php?query=...&s=...
const TYPEAHEAD_DEFAULT_LIMIT = 20;
const TYPEAHEAD_SQL_KEY_NAME = 'id';
const TYPEAHEAD_API_MAX_LENGTH = 512;

const DEFAULT_LDAP_TIME_LIMIT = 3;

const SINGLE_TICK = "'";
const DOUBLE_TICK = '"';
const BACK_TICK = '`';
const LESS_SIGN = '<';
const GREATER_SIGN = '>';

// TOKEN evaluate - already used: "-AcCdDEhHlLmPpsStTwX"
const TOKEN_ESCAPE_CONFIG = 'c';
const TOKEN_ESCAPE_SINGLE_TICK = 's';
const TOKEN_ESCAPE_DOUBLE_TICK = 'd';
const TOKEN_ESCAPE_COLON = 'C';
const TOKEN_ESCAPE_LDAP_FILTER = 'l';
const TOKEN_ESCAPE_LDAP_DN = 'L';
const TOKEN_ESCAPE_MYSQL = 'm';
const TOKEN_ESCAPE_PASSWORD_T3FE = 'p';
const TOKEN_ESCAPE_NONE = '-';
const TOKEN_ESCAPE_WIPE = 'w';
const TOKEN_ESCAPE_TIMEZONE = 't';
const TOKEN_ESCAPE_HTML_SPECIAL_CHAR = 'h';
const TOKEN_ESCAPE_HTML_ENTITY = 'H';
const TOKEN_ESCAPE_STRIP_HTML_TAGS = 'T';

const TOKEN_ESCAPE_STOP_REPLACE = 'S';
const TOKEN_ESCAPE_EXCEPTION = 'X';
#const TOKEN_ESCAPE_ACTION = 'A';

const TOKEN_ESCAPE_ENCRYPT = 'E';
const TOKEN_ESCAPE_DECRYPT = 'D';
const TOKEN_ESCAPE_FIND = 'f';
const TOKEN_ESCAPE_PIPE = 'P';

// Workaround for PHP < 5.6.0
if (!function_exists('ldap_escape')) {
    define('LDAP_ESCAPE_FILTER', 0x01);
    define('LDAP_ESCAPE_DN', 0x02);
}

const TOKEN_FOUND_IN_STORE_QUERY = 'query';
const TOKEN_FOUND_AS_COLUMN = 'column';
const TOKEN_FOUND_AS_DEFAULT = 'default';
const TOKEN_FOUND_STOP_REPLACE = 'stopReplace';

const VAR_INDEX_VALUE = 0;
const VAR_INDEX_STORE = 1;
const VAR_INDEX_SANITIZE = 2;
const VAR_INDEX_ESCAPE = 3;
const VAR_INDEX_DEFAULT = 4;
const VAR_INDEX_MESSAGE = 5;

const RANDOM_LENGTH = 32;

// FORM - copy from table 'form' of processed form
//const DEF_FORM_NAME = CLIENT_FORM;

// FORMELEMENT - copy of all formElements of processed form
//const DEF_FORM_ELEMENT_ID = 'id';

// SQL logging Modes
const SQL_LOG_MODE_ALL = 'all';
const SQL_LOG_MODE_MODIFY = 'modify';
const SQL_LOG_MODE_NONE = 'none';
const SQL_LOG_MODE_ERROR = 'error';

// SQL aliases (SQL_*)
const SQL_ALIAS_COUNT = 'cnt';

const MODE_LDAP_PREFETCH = 'ldapPrefetch';
const MODE_LDAP_SINGLE = 'ldapSingle';
const MODE_LDAP_MULTI = 'ldapMulti';

// api/save.php, api/delete.php, api/load.php
const API_DELETE_PHP = 'delete.php';
const API_DIRTY_PHP = 'dirty.php';
const API_SAVE_PHP = 'save.php';
const API_LOAD_PHP = 'load.php';
const API_FILE_PHP = 'file.php';
const API_DOWNLOAD_PHP = 'download.php';
const API_DIRECT_DOWNLOAD_PHP = 'd.php';
const API_DRAG_AND_DROP_PHP = 'dragAndDrop.php';
const API_TYPEAHEAD_PHP = 'typeahead.php';
const API_AI_HANDLER_PHP = 'aiHandler.php';

const API_STATUS = 'status';
const API_MESSAGE = 'message';
const API_REDIRECT = 'redirect';
const API_REDIRECT_URL = 'redirect-url';
const API_LOCK_ACTION = 'action';
const API_LOCK_TIMEOUT = 'lock_timeout';
const API_FIELD_NAME = 'field-name';
const API_FIELD_MESSAGE = 'field-message';
const API_FORM_UPDATE = 'form-update';
const API_FORM_UPDATE_FORM_ELEMENT = 'form-element';
const API_FORM_UPDATE_VALUE = 'value';
const API_FORM_UPDATE_HIDDEN = 'hidden';
const API_FORM_UPDATE_DISABLED = 'disabled';
const API_FORM_UPDATE_REQUIRED = 'required';
const API_HEADER_VARIABLE_KEY = 'apiResponseHeader';

const API_CHAT_UPDATE_DISABLED = API_FORM_UPDATE_DISABLED;

const API_ELEMENT_UPDATE = 'element-update';
const API_ELEMENT_ATTRIBUTE = 'attr';
const API_ELEMENT_CONTENT = 'content';

const API_CHANGED_ELEMENTS = 'changed-elements';
const API_CHANGED_ELEMENTS_DELETE_BUTTONS = 'delete-buttons';
const API_CHANGED_ELEMENTS_ID = 'id';
const API_CHANGED_ELEMENTS_HTML_NAME = 'htmlName';
const API_CHANGED_ELEMENTS_HTML = 'html';
const API_CHANGED_ELEMENTS_FORM_TYPE = 'formType';
const API_CHANGED_ELEMENTS_FORM_TYPE_MULTI = 'multi';

const API_CHAT_UPDATE = 'chat-update';

const API_SUBMIT_REASON = 'submit_reason';
const API_SUBMIT_REASON_SAVE = 'save';
const API_SUBMIT_REASON_SAVE_CLOSE = 'save,close';
const API_SUBMIT_REASON_SAVE_FORCE = 'save,force';

const API_LOCK_ACTION_LOCK = 'lock';
const API_LOCK_ACTION_EXTEND = 'extend';
const API_LOCK_ACTION_RELEASE = 'release';
const API_LOCK_ACTION_CHECK = 'check';

const API_ANSWER_STATUS_SUCCESS = 'success';
const API_ANSWER_STATUS_CONFLICT = 'conflict';
const API_ANSWER_STATUS_CONFLICT_ALLOW_FORCE = 'conflict_allow_force';
const API_ANSWER_STATUS_ERROR = 'error';
const API_ANSWER_REDIRECT_AUTO = 'auto';
const API_ANSWER_REDIRECT_CLOSE = 'close';
const API_ANSWER_REDIRECT_NO = 'no';
const API_ANSWER_REDIRECT_URL = 'url';
const API_ANSWER_REDIRECT_URL_SKIP_HISTORY = 'url-skip-history';

const API_TYPEAHEAD_KEY = 'key';
const API_TYPEAHEAD_VALUE = 'value';
const API_RECORD_HISTORY_DATA = 'record-history-data';
const API_SUB_ELEMENTS = 'subElements';
const API_ELEMENT_TO_REPLACE = 'typeToReplace';

const DATA_REQUIRED_OFF_BUT_MARK = 'data-required-off-but-mark';

const DATA_HIDDEN = 'data-hidden';
const DATA_DISABLED = 'data-disabled';
const DATA_REQUIRED = 'data-required';
const DATA_SIP = 'data-sip';
const CLASS_IGNORE_HISTORY = 'data-ignore-history';
const CLASS_TYPEAHEAD = 'qfq-typeahead';
const DATA_TYPEAHEAD_SIP = 'data-typeahead-sip';
const ID_NEXT_FORM = 'form-button-next';
const ID_PREVIOUS_FORM = 'form-button-previous';
const CLASS_NOTE = 'qfq-note';
const CLASS_TRIGGER_STICKY_TOOLTIP = 'tooltip-trigger';
const CLASS_SKIP_DIRTY = 'qfq-skip-dirty';
const CLASS_PULL_RIGHT = 'pull-right';
const CLASS_BTN_GROUP = 'btn-group';
const CLASS_DROPDOWN_TOGGLE = 'dropdown-toggle';
const CLASS_BTN = 'btn';
const CLASS_BTN_DEFAULT = 'btn-default';
const CLASS_DROPDOWN_MENU_RIGHT = 'dropdown-menu-right';
const CLASS_DROPDOWN_MENU = 'dropdown-menu';
const CLASS_CLEARFIX = 'clearfix';

// HTML Attributes
const FLAG_OMIT_EMPTY = 'flagOmitEmpty';
const MODE_ESCAPE = 'modeEscape';
const ATTRIBUTE_STYLE = 'style';
const ATTRIBUTE_COLS = 'cols';
const ATTRIBUTE_ROWS = 'rows';
const ATTRIBUTE_PATTERN = 'pattern';
const ATTRIBUTE_DISABLED = 'disabled';
const DATA_ENABLE_SAVE_BUTTON = 'data-enable-save-button';
const CSS_CLASS = 'class';

// HTML Element

const HTML_LABEL = 'label';
const HTML_BR = 'br';

//const CLASS_TYPEAHEAD = 'qfq-type-ahead';
//const DATA_TYPEAHEAD_SIP = 'data-sip'; // Used for typeAhead

const DATA_TYPEAHEAD_LIMIT = 'data-typeahead-limit';
const DATA_TYPEAHEAD_MINLENGTH = 'data-typeahead-minlength';
const DATA_TYPEAHEAD_PEDANTIC = 'data-typeahead-pedantic';
const DATA_TYPEAHEAD_INITIAL_SUGGESTION = 'data-typeahead-initial-suggestion';
const DATA_TYPEAHEAD_TAG = 'data-typeahead-tags';
const DATA_TYPEAHEAD_TAG_DELIMITER = 'data-typeahead-tag-delimiters';
const DATA_TYPEAHEAD_URL = 'data-typeahead-url';

const CLASS_AI_ASSIST = 'qfq-ai-assist';
const DATA_AI_SIP = 'data-ai-sip';
const DATA_AI_URL = 'data-ai-url';
const DATA_AI_THINKING = 'data-ai-thinking';
const CLASS_AI_CHAT = 'qfq-ai-chat';
const DATA_AI_CHAT_PLACEHOLDER = 'data-ai-chat-placeholder';
const DATA_AI_ASSIST = 'data-ai-assist';
const DATA_AI_TRANSLATE_LANGUAGES = 'data-ai-translate-languages';

const CLASS_CHARACTER_COUNT = 'qfq-character-count';
const DATA_CHARACTER_COUNT_ID = 'data-character-count-id';

const CLASS_ICJ = 'qfq-icj';
const DATA_IJC_TEMPLATE = 'data-icj-template';

const CLASS_FORM_ELEMENT_EDIT = 'qfq-form-element-edit';
const CLASS_FORM_TITLE = 'qfq-form-title';

const CLASS_FORM_ELEMENT_AUTO_GROW = 'qfq-auto-grow';
const ATTRIBUTE_DATA_MAX_HEIGHT = 'data-max-height';

//CHECKBOX
const ALIGN_HORIZONTAL = 'horizontal';
const ALIGN_VERTICAL = 'vertical';
const MULTI_STATE_CHECKBOX_VALUE = 'value';
const MULTI_STATE_CHECKBOX_LABEL = 'label';
const MULTI_STATE_CHECKBOX_ICON = 'icon';
const MULTI_STATE_CHECKBOX_ICON_COLOR = 'iconColor';
const MULTI_STATE_CHECKBOX_BACKGROUND_COLOR = 'color';
const MULTI_STATE_CHECKBOX_COLOR_BLUE = '#2196f3';
const MULTI_STATE_CHECKBOX_COLOR_WHITE = 'white';
const FONT_AWESOME_ICON_CHECKMARK = 'fa-check';
const QUESTION_DELETE = 'Do you really want to delete the record?';
// Subrecord
const SUBRECORD_COLUMN_DEFAULT_MAX_LENGTH = 20;
const SUBRECORD_COLUMN_TITLE_EDIT = 'subrecordColumnTitleEdit';
const SUBRECORD_COLUMN_TITLE_DELETE = 'subrecordColumnTitleDelete';
const SUBRECORD_EMPTY_TEXT = 'subrecordEmptyText';
const SUBRECORD_DEFAULT_EMPTY_TEXT = 'Currently no records exist.';
const FORM_ELEMENTS_NATIVE = 'native';

const FORM_ELEMENTS_ACTION = 'action';
const FORM_ELEMENTS_SUBRECORD = 'subrecord';
const FORM_ELEMENTS_NATIVE_SUBRECORD = 'native_subrecord';
//const FORM_ELEMENTS_DYNAMIC_UPDATE = 'native_dynamic_update';
const SUBRECORD_NEW = 'new';
const SUBRECORD_EDIT = 'edit';
const SUBRECORD_DELETE = 'delete';
const SUBRECORD_PARAMETER_FORM = CLIENT_FORM;
const SUBRECORD_PARAMETER_NEW = 'new';
const SUBRECORD_PARAMETER_PAGE = 'page';
const SUBRECORD_PARAMETER_DETAIL = 'detail';

const SUBRECORD_COLUMN_TITLE = 'title';
const SUBRECORD_COLUMN_MAX_LENGTH = 'maxLength';
const SUBRECORD_COLUMN_NO_STRIP = 'nostrip';
const SUBRECORD_COLUMN_ICON = 'icon';
const SUBRECORD_COLUMN_LINK = 'link';
const SUBRECORD_COLUMN_URL = 'url';
const SUBRECORD_COLUMN_MAILTO = 'mailto';
const SUBRECORD_COLUMN_TH_CLASS = 'thClass';
const SUBRECORD_COLUMN_ROW_CLASS = '_rowClass';
const SUBRECORD_COLUMN_ROW_TITLE = '_rowTitle';
const SUBRECORD_COLUMN_ROW_TOOLTIP = '_rowTooltip';
const SUBRECORD_COLUMN_ROW_EDIT = '_rowEdit';
const SUBRECORD_COLUMN_ROW_DELETE = '_rowDelete';

const SUBRECORD_TABLE_CLASS_DEFAULT = 'table table-hover qfq-subrecord-table qfq-color-grey-2';
const SUBRECORD_FLAG_DELETE = 'flagDelete';
const SUBRECORD_FLAG_EDIT = 'flagEdit';
const SUBRECORD_FLAG_CHECKBOX = 'flagCheckbox';
const SUBRECORD_FLAG_NEW = 'flagNew';
const SUBRECORD_PRIMARY_RECORD = 'primaryRecord';
const SUBRECORD_HAS_DRAG_AND_DROP = 'hasDragAndDrop';
const SUBRECORD_CONTROL = 'control';
const SUBRECORD_NAME_COLUMN_ID = 'nameColumnId';
const SUBRECORD_CSS_CLASS_COLUMN_ID = 'cssClassColumnId';
const SUBRECORD_LINK_NEW = 'subrecordLinkNew';
const SUBRECORD_LINK_NEW_TOOLTIP = 'subrecordLinkNewTooltip';

const SUBRECORD_EMPTY_HIDE = 'hide';
const SUBRECORD_EMPTY_MUTE = 'mute';
const SUBRECORD_EMPTY_SHOW = 'show';

const GLYPH_ICON = 'glyphicon';
const GLYPH_ICON_EDIT = 'glyphicon-pencil';
const GLYPH_ICON_NEW = 'glyphicon-plus';
const GLYPH_ICON_DELETE = 'glyphicon-trash';
const GLYPH_ICON_HELP = 'glyphicon-question-sign';
const GLYPH_ICON_INFO = 'glyphicon-info-sign';
const GLYPH_ICON_SHOW = 'glyphicon-search';
const GLYPH_ICON_TOOL = 'glyphicon-wrench';
const GLYPH_ICON_CHECK = 'glyphicon-ok';
const GLYPH_ICON_CLOSE = 'glyphicon-remove';
const GLYPH_ICON_TASKS = 'glyphicon-tasks';
const GLYPH_ICON_DUPLICATE = 'glyphicon-duplicate';
const GLYPH_ICON_VIEW = 'glyphicon-eye-open';
const GLYPH_ICON_FILE = 'glyphicon-file';
const GLYPH_ICON_COPY = 'glyphicon-copy';
const GLYPH_ICON_OPTION_VERTICAL = 'glyphicon-option-vertical';
const GLYPH_ICON_PAPERCLIP = 'glyphicon-paperclip';
const GLYPH_ICON_BACKWARD = 'glyphicon-backward';
const GLYPH_ICON_PASTE = 'glyphicon-paste';


// CodeMirror parameters
const CODEMIRROR_MODE_QFQ = 'qfq';
const CODEMIRROR_MODE = 'mode';
const CODEMIRROR_LINE_NUMBERS = 'lineNumbers';
const CODEMIRROR_LINE_WRAPPING = 'lineWrapping';
const CODEMIRROR_TAB_SIZE = 'tabSize';
const CODEMIRROR_STYLE_ACTIVE_LINE = 'styleActiveLine';
const CODEMIRROR_MATCH_BRACKETS = 'matchBrackets';
const CODEMIRROR_AUTO_CLOSE_BRACKETS = 'autoCloseBrackets';

// BuildForm
const SYMBOL_NEW = GLYPH_ICON_NEW;
const SYMBOL_EDIT = GLYPH_ICON_EDIT;
const SYMBOL_SHOW = GLYPH_ICON_SHOW;
const SYMBOL_DELETE = GLYPH_ICON_DELETE;

// FORM columns: real
const F_ID = 'id';
const F_NAME = 'name';

const F_NAME_ONLY_FORM_ELEMENT = '_onlyFormElement';
const F_DELETED = 'deleted';
const F_TITLE = 'title';
const F_TABLE_NAME = 'tableName';
const F_PRIMARY_KEY = 'primaryKey';
const F_PRIMARY_KEY_DEFAULT = 'id';
const F_REST_METHOD = 'restMethod';
const F_REQUIRED_PARAMETER_NEW = 'requiredParameterNew';
const F_REQUIRED_PARAMETER_EDIT = 'requiredParameterEdit';
const F_EXTRA_DELETE_FORM = 'extraDeleteForm';
const F_FINAL_DELETE_FORM = 'finalDeleteForm'; # Internal use only - typically copy of F_EXTRA_DELETE_FORM
const F_DIRTY_MODE = 'dirtyMode';
const F_NOTE_INTERNAL = 'noteInternal';
const F_MULTI_SQL = 'multiSql';
const F_MULTI_SQL_RESULT = 'multiSqlResult';
const F_MULTI_SQL_ID_NAME = 'multiSqlIdName'; # The name of the column that is used as id (either 'id' or '_id')
const F_MULTI_MODE = 'multiMode';
const F_MULTI_MODE_NONE = 'none';
const F_MULTI_MODE_VERTICAL = 'vertical';
const F_MULTI_COL_ID = 'id';
const F_MULTI_WRAP = 'multiFormWrap';
const F_MULTI_CELL_WRAP = 'multiFormCellWrap';
const F_MULTI_TABLE_CLASS = 'multiFormTableClass';
const F_MODIFIED = 'modified';
const F_FILE_STATS = 'fileStats';
const F_SUBMIT_BUTTON_TEXT = 'submitButtonText';
const F_BUTTON_ON_CHANGE_CLASS = 'buttonOnChangeClass';

const F_ESCAPE_TYPE_DEFAULT = SYSTEM_ESCAPE_TYPE_DEFAULT;

const F_CLASS = 'class';
const F_CLASS_PILL = 'classPill';
const F_CLASS_BODY = 'classBody';
const F_CLASS_TITLE = 'classTitle';

const F_SHOW_BUTTON = 'showButton';

const F_FORWARD_MODE = 'forwardMode';
const F_FORWARD_PAGE = 'forwardPage';

const F_FORWARD_MODE_AUTO = API_ANSWER_REDIRECT_AUTO;
const F_FORWARD_MODE_CLOSE = API_ANSWER_REDIRECT_CLOSE;
const F_FORWARD_MODE_NO = API_ANSWER_REDIRECT_NO;
const F_FORWARD_MODE_URL = API_ANSWER_REDIRECT_URL;
const F_FORWARD_MODE_URL_SKIP_HISTORY = API_ANSWER_REDIRECT_URL_SKIP_HISTORY;
const F_FORWARD_MODE_URL_SIP = 'url-sip';
const F_FORWARD_MODE_URL_SIP_SKIP_HISTORY = 'url-sip-skip-history';

const F_RECORD_LOCK_TIMEOUT_SECONDS = SYSTEM_RECORD_LOCK_TIMEOUT_SECONDS;
const F_SESSION_TIMEOUT_SECONDS = SYSTEM_SESSION_TIMEOUT_SECONDS;

const F_FE_DATA_PATTERN_ERROR = 'data-pattern-error';
const F_FE_DATA_PATTERN_ERROR_SYSTEM = 'data-pattern-error-system'; // only used to determine final text

const F_FE_DATA_REQUIRED_ERROR = 'data-required-error';
const F_FE_DATA_MATCH_ERROR = 'data-match-error'; // contains id of the sibling input to check that i
const F_FE_DATA_ERROR = 'data-error';
const F_FE_DATA_ERROR_DEFAULT = 'Error';

const F_FE_DATA_PATTERN_ERROR_DEFAULT = 'Pattern mismatch'; // Attention: the default is also defined in ext_conf_template.txt
const F_FE_DATA_REQUIRED_ERROR_DEFAULT = 'Required'; // Attention: the default is also defined in ext_conf_template.txt
const F_FE_DATA_MATCH_ERROR_DEFAULT = 'Fields do not match'; // Attention: the default is also defined in ext_conf_template.txt

const FE_LABEL_2 = 'label2';
const F_FE_LABEL_ALIGN = SYSTEM_LABEL_ALIGN;
const F_FE_LABEL_ALIGN_DEFAULT = 'default';
const F_FE_REQUIRED_POSITION = 'requiredPosition';
const F_FE_REQUIRED_POSITION_LABEL_LEFT = 'label-left';
const F_FE_REQUIRED_POSITION_LABEL_RIGHT = 'label-right';
const F_FE_REQUIRED_POSITION_INPUT_LEFT = 'input-left';
const F_FE_REQUIRED_POSITION_INPUT_RIGHT = 'input-right';
const F_FE_REQUIRED_POSITION_NOTE_LEFT = 'note-left';
const F_FE_REQUIRED_POSITION_NOTE_RIGHT = 'note-right';

const F_FE_MIN_WIDTH = 'minWidth';
const F_FE_MIN_WIDTH_DEFAULT = '80';
const F_FE_FIELDSET_CLASS = SYSTEM_FIELDSET_CLASS;

const F_FE_INPUT_CLEAR_ME = SYSTEM_INPUT_CLEAR_ME;
const F_PARAMETER = 'parameter';    // valid for F_ and FE_

// Form columns: via parameter field
const F_DB_INDEX = 'dbIndex';
const DB_INDEX_DEFAULT = "1";
const DB_INDEX_T3 = DB_INDEX_DEFAULT;
const PARAM_DB_INDEX_DATA = '__dbIndexData'; // Submitted via SIP to make record locking DB aware.
const F_FORM_SUBMIT_LOG_MODE = 'formSubmitLogMode';

// Recent Log constant

const F_LDAP_SERVER = 'ldapServer';
const F_LDAP_BASE_DN = 'ldapBaseDn';
const F_LDAP_SEARCH = 'ldapSearch';
const F_LDAP_ATTRIBUTES = 'ldapAttributes';
const F_LDAP_TIME_LIMIT = 'ldapTimeLimit';
const F_LDAP_USE_BIND_CREDENTIALS = 'ldapUseBindCredentials';
const F_TYPEAHEAD_LIMIT = 'typeAheadLimit';
const F_TYPEAHEAD_MINLENGTH = 'typeAheadMinLength';
const F_TYPEAHEAD_PEDANTIC = 'typeAheadPedantic';
const F_TYPEAHEAD_LDAP_VALUE_PRINTF = 'typeAheadLdapValuePrintf';
const F_TYPEAHEAD_LDAP_ID_PRINTF = 'typeAheadLdapIdPrintf';
const F_TYPEAHEAD_LDAP_SEARCH = 'typeAheadLdapSearch';
const F_TYPEAHEAD_LDAP_SEARCH_PREFETCH = 'typeAheadLdapSearchPrefetch';
const F_TYPEAHEAD_LDAP_SEARCH_PER_TOKEN = 'typeAheadLdapSearchPerToken';

const F_MODE_READONLY = 'readonly';
const F_MODE_REQUIRED_OFF = 'requiredOff';
const F_MODE_REQUIRED_OFF_BUT_MARK = 'requiredOffButMark';
const F_MODE_SKIP_REQUIRED_CHECK = 'skipRequiredCheck'; // deprecated since third revision of #9617
const F_MODE_GLOBAL = 'formModeGlobal';

const F_PROCESS_ROW = 'processRow';
const F_PROCESS_ROW_COLUMN = '_processRow';

const F_NOTE_BUTTON_TEXT = SYSTEM_NOTE_BUTTON_TEXT;

const F_NOTE_BUTTON_CLASS = SYSTEM_NOTE_BUTTON_CLASS;


const F_SAVE_BUTTON_ACTIVE = 'saveButtonActive';

const F_SAVE_BUTTON_TEXT = SYSTEM_SAVE_BUTTON_TEXT;
const F_SAVE_BUTTON_TOOLTIP = SYSTEM_SAVE_BUTTON_TOOLTIP;
const F_SAVE_BUTTON_CLASS = SYSTEM_SAVE_BUTTON_CLASS;
const F_SAVE_BUTTON_GLYPH_ICON = SYSTEM_SAVE_BUTTON_GLYPH_ICON;
// the following submitButton variables are only for internal use;
// externally they are defined by the saveButton variables
const F_SUBMIT_BUTTON_CLASS = 'submitButtonClass';
const F_SUBMIT_BUTTON_GLYPH_ICON = 'submitButtonGlyphIcon';
const F_SUBMIT_BUTTON_TOOLTIP = 'submitButtonToolTip';

const F_CLOSE_BUTTON_TEXT = SYSTEM_CLOSE_BUTTON_TEXT;
const F_CLOSE_BUTTON_TOOLTIP = SYSTEM_CLOSE_BUTTON_TOOLTIP;
const F_CLOSE_BUTTON_CLASS = SYSTEM_CLOSE_BUTTON_CLASS;
const F_CLOSE_BUTTON_GLYPH_ICON = SYSTEM_CLOSE_BUTTON_GLYPH_ICON;

const F_DELETE_BUTTON_TEXT = SYSTEM_DELETE_BUTTON_TEXT;
const F_DELETE_BUTTON_TOOLTIP = SYSTEM_DELETE_BUTTON_TOOLTIP;
const F_DELETE_BUTTON_CLASS = SYSTEM_DELETE_BUTTON_CLASS;
const F_DELETE_BUTTON_GLYPH_ICON = SYSTEM_DELETE_BUTTON_GLYPH_ICON;

const F_NEW_BUTTON_TEXT = SYSTEM_NEW_BUTTON_TEXT;
const F_NEW_BUTTON_TOOLTIP = SYSTEM_NEW_BUTTON_TOOLTIP;
const F_NEW_BUTTON_CLASS = SYSTEM_NEW_BUTTON_CLASS;
const F_NEW_BUTTON_GLYPH_ICON = SYSTEM_NEW_BUTTON_GLYPH_ICON;

const F_FIELDSET_CLASS = SYSTEM_FIELDSET_CLASS;

const F_ENTER_AS_SUBMIT = SYSTEM_ENTER_AS_SUBMIT;
const F_ACTIVATE_FIRST_REQUIRED_TAB = 'activateFirstRequiredTab';

const F_DRAG_AND_DROP_ORDER_SQL = 'dragAndDropOrderSql';
const F_ORDER_INTERVAL = 'orderInterval';
const F_ORDER_COLUMN = 'orderColumn';
const F_ORDER_COLUMN_NAME = 'ord';

const F_SHOW_ID_IN_FORM_TITLE = SYSTEM_SHOW_ID_IN_FORM_TITLE;
const F_FILE_NAME_TO_LOWER = SYSTEM_FILE_NAME_TO_LOWER;
const F_MULTI_MSG_NO_RECORD = 'multiMsgNoRecord';
const F_MULTI_MSG_NO_RECORD_TEXT = 'No data';
const F_DATE_TIME_PICKER_TYPE = SYSTEM_DATE_TIME_PICKER_TYPE;

const F_REST_SQL_LIST = 'restSqlList';
const F_REST_SQL_DATA = 'restSqlData';
const F_REST_SQL_POST_PUT = 'restSqlPostPut';
const F_REST_PARAM = 'restParam';
const F_REST_TOKEN = 'restToken';
const CLIENT_REST_ID = '_id';
const CLIENT_REST_FORM = '_form';

const F_MAX_VISIBLE_PILL = 'maxVisiblePill';
const F_REMEMBER_LAST_PILL = SYSTEM_REMEMBER_LAST_PILL;
const F_MESSAGE = 'message';
const F_MESSAGE_TYPE = 'type';
const F_MESSAGE_TYPE_PAGE = 'page';
const F_MESSAGE_TYPE_MESSAGE = 'message';
const F_MESSAGE_SLUG = 'slug';
const F_MESSAGE_CHANNEL = 'channel';
const F_MESSAGE_ACTION = 'action';
const F_MESSAGE_ACTION_REPORT = 'report';
const F_MESSAGE_PAYLOAD = 'payload';
const F_MESSAGE_WS_GROUP = 'wsGroup';
const F_MESSAGE_NAME = 'name';
const F_SHOW_HISTORY = SYSTEM_SHOW_HISTORY;
const F_SHOW_HISTORY_TITLE = 'showHistoryTitle';
const F_SHOW_HISTORY_FE_USER_SET = SIP_SHOW_HISTORY_FE_USER_SET;
const F_DO_NOT_LOG_COLUMN = SYSTEM_DO_NOT_LOG_COLUMN;

const F_UNEVALUATED_TITLE = 'unevaluatedTitle';

const F_BTN_PREVIOUS_NEXT_SQL = 'btnPreviousNextSql';
const F_BTN_PREVIOUS_NEXT_LOOP = 'btnPreviousNextLoop';
const F_BTN_PREVIOUS_NEXT_WRAP = 'btnPreviousNextWrap';
const F_BTN_PREVIOUS_NEXT_SQL_ID = 'id';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_PREVIOUS = 'btnPrevious';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_NEXT = 'btnNext';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_CURRENT = 'btnCurrent';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_PREVIOUS_GLYPHICON = 'glyphicon glyphicon-arrow-left';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_NEXT_GLYPHICON = 'glyphicon glyphicon-arrow-right';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_PREVIOUS_TOOLTIP = 'No previous record available.';
const F_BTN_PREVIOUS_NEXT_SQL_BTN_NEXT_TOOLTIP = 'No next record available.';


const F_BTN_TOP = 'top';
const F_BTN_TOP_WRAP = 'btnTopWrap';
const F_BTN_TOP_RIGHT = 'btnTopRight';
const F_BTN_TOP_RIGHT_WRAP = 'btnTopRightWrap';
const F_BTN_TOP_RIGHT_ORDER = 'btnTopRightOrder';

const F_BTN_TOP_LEFT = 'btnTopLeft';
const F_BTN_TOP_LEFT_WRAP = 'btnTopLeftWrap';
const F_BTN_TOP_LEFT_ORDER = 'btnTopLeftOrder';

const F_BTN_FOOTER = 'footer';
const F_BTN_FOOTER_WRAP = 'btnFooterWrap';
const F_BTN_FOOTER_RIGHT = 'btnFooterRight';
const F_BTN_FOOTER_RIGHT_WRAP = 'btnFooterRightWrap';
const F_BTN_FOOTER_RIGHT_ORDER = 'btnFooterRightOrder';

const F_BTN_FOOTER_LEFT = 'btnFooterLeft';
const F_BTN_FOOTER_LEFT_WRAP = 'btnFooterLeftWrap';
const F_BTN_FOOTER_LEFT_ORDER = 'btnFooterLeftOrder';


// Form Columns: Only in form file
const F_FILE_FORM_ELEMENT = 'FormElement_ff'; // Key for FormElements array saved in Form File

const F_SUBRECORD_EMPTY = SYSTEM_SUBRECORD_EMPTY;

const F_RECENT_LOG = SYSTEM_RECENT_LOG;
const F_FE_MAX_IMAGE_DIMENSION = SYSTEM_MAX_IMAGE_DIMENSION;
const MAX_IMAGE_DIMENSION_HEIGHT = 'maxImageHeight';
const MAX_IMAGE_DIMENSION_WIDTH = 'maxImageWidth';

// FORM_ELEMENT_STATI
const FE_MODE_SHOW = 'show';
const FE_MODE_READONLY = 'readonly';
const FE_MODE_REQUIRED = 'required';
const FE_MODE_SHOW_REQUIRED = 'showRequired';
const FE_MODE_HIDDEN = 'hidden';

// Inline filter mode: used to indicate FormElement is rendered as inline filter (shows counts)
const FE_INLINE_FILTER = 'inlineFilter';
const FE_INLINE_EDIT = 'inlineEdit';

// Allow parameter overwrite: used to allow token values to override DB parameter values (for inline filter/edit)
const FE_ALLOW_PARAMETER_OVERWRITE = 'allowParameterOverwrite';

const FE_CLASS_NATIVE = 'native';
const FE_CLASS_ACTION = 'action';
const FE_CLASS_CONTAINER = 'container';

// FormElement columns: real
const FE_ID = 'id';
const FE_ID_CONTAINER = 'feIdContainer';
const FE_FORM_ID = 'formId';
const FE_NAME = 'name';
const FE_TYPE = 'type';
const FE_MODE = 'mode';
const FE_MODE_SQL = 'modeSql';
const FE_DYNAMIC_UPDATE = 'dynamicUpdate';
const FE_VALUE = 'value';
const FE_CLASS = 'class';
const FE_LABEL = 'label';
const FE_NOTE = 'note';
const FE_INPUT = 'input';
const FE_BS_LABEL_COLUMNS = F_BS_LABEL_COLUMNS;
const FE_BS_INPUT_COLUMNS = F_BS_INPUT_COLUMNS;
const FE_BS_NOTE_COLUMNS = F_BS_NOTE_COLUMNS;
const FE_WRAP_ROW_LABEL_INPUT_NOTE = 'rowLabelInputNote';
const FE_MAX_LENGTH = 'maxLength';
const FE_MAX_LENGTH_COLUMN = 'maxLengthColumn';
const FE_PARAMETER = 'parameter';
const FE_CLIENT_JS = 'clientJs';
const FE_ENCODE = 'encode';
const FE_CHECK_TYPE = 'checkType';
const FE_CHECK_PATTERN = 'checkPattern';
const FE_TOOLTIP = 'tooltip';
const FE_SIZE = 'size';
const FE_SUBRECORD_OPTION = 'subrecordOption';
const FE_SQL1 = 'sql1';
const FE_PLACEHOLDER = 'placeholder';
const FE_ICJ_TEMPLATE = 'icjTemplate';
const FE_DATA_REFERENCE = 'dataReference';
const FE_ADMIN_NOTE = 'adminNote';
const FE_ORD = 'ord';
const FE_SUBRECORD_APPEND_SQL = 'subrecordAppendSql';
const FE_SUBRECORD_APPEND_CLASS = 'subrecordAppendClass';
const FE_SUBRECORD_APPEND_FORM = 'subrecordAppendForm';
const FE_SUBRECORD_APPEND_EXTRA_DELETE_FORM = 'subrecordAppendExtraDeleteForm';
const FE_SUBRECORD_COPY_RULE = 'copyRule';
const FE_SUBRECORD_COPY_RULE_IMPORT = 'copyRuleImport';

const FE_ENCRYPTION = 'encryption';

// FormElement columns: via parameter field
const FE_DATE_FORMAT = SYSTEM_DATE_FORMAT;  // value: FORMAT_DATE_INTERNATIONAL | FORMAT_DATE_GERMAN
const FE_DECIMAL_FORMAT = 'decimalFormat'; // value: 10,2
const FE_SHOW_SECONDS = 'showSeconds';  // value: 0|1
const FE_TIME_IS_OPTIONAL = 'timeIsOptional'; // value: 0|1
const FE_SHOW_ZERO = 'showZero';  // 0|1 - Used for 'date/datime/time': in case of fe.value='0' shows corresponding '00-00-0000'|'00:00:00'
const FE_HIDE_ZERO = 'hideZero';  // 0|1 - In case of fe.value=0|'0', an empty string is shown.
const FE_FILE_DESTINATION = 'fileDestination'; // Target pathFileName for an uploaded file.
const FE_FILE_DESTINATION_SPLIT = 'fileDestinationSplit'; // Target pathFileName for split files
const FE_FILE_REPLACE_MODE = 'fileReplace'; // Flag if a) QFQ throw an error if there is already a file with the same pathFileName or b) if QFQ should overwrite it.
const FE_FILE_REPLACE_MODE_ALWAYS = 'always'; // Value for flag FE_FILE_REPLACE_MODE
const FE_FILE_MIME_TYPE_ACCEPT = 'accept'; // Comma separated list of mime types
const FE_FILE_MAX_FILE_SIZE = SYSTEM_FILE_MAX_FILE_SIZE; // Max upload file size
const FE_FILE_UNZIP = 'fileUnzip'; // 0|1|dir|{{SELECT ...}}
const FE_FILE_UNPACK_DIR = 'unpack'; // default dir if not specified
const FE_FILE_NOTE = 'fileNote';
const FE_FILE_NOTE_TEXT = 'fileNoteText';
const FE_FILE_NOTE_INPUT_NAME = 'fileNoteInputName';
const FE_FILE_NOTE_TARGET = 'fileNoteTarget';
const FILE_NOTE_COLUMN_EXTENSION = 'Note';

const FE_FILE_KEY = 'fileKey';
const FE_FILE_CAPTURE = 'capture'; // On a smartphone opens the camera
const FE_FILE_SPLIT = 'fileSplit';
const FE_FILE_SPLIT_SVG = 'svg';
const FE_FILE_SPLIT_JPEG = 'jpeg';
const FE_FILE_SPLIT_OPTIONS = 'fileSplitOptions';
const FE_FILE_SPLIT_OPTIONS_JPEG = '-density 150 -quality 90';
const FE_FILE_SPLIT_TABLE_NAME = 'tableNameSplit';
const FE_FILE_DOWNLOAD_BUTTON = 'downloadButton';

const FE_FILE_DOWNLOAD_BUTTON_HTML_INTERNAL = 'htmlDownloadButton'; // Internal use
const FE_FILE_AUTO_ORIENT = 'autoOrient';
const FE_FILE_AUTO_ORIENT_CMD = 'autoOrientCmd';
const FE_FILE_AUTO_ORIENT_CMD_DEFAULT = 'convert -auto-orient {{fileDestination:V}} {{fileDestination:V}}.new; mv {{fileDestination:V}}.new {{fileDestination:V}}';
const FE_FILE_AUTO_ORIENT_MIME_TYPE = 'autoOrientMimeType';
const FE_FILE_CHMOD_FILE = 'chmodFile';
const FE_FILE_CHMOD_DIR = 'chmodDir';
const FE_TRIM = 'trim'; // 'none' | list of characters
const FE_TRIM_NONE = 'none';
const FE_FILE_TRASH = 'fileTrash';
const FE_FILE_TRASH_TEXT = 'fileTrashText';

const FE_DATE_LOCALE = "dateLocale";
const FE_DATE_DAYS_OF_WEEK_ENABLED = "dateDaysOfWeekEnabled";
const FE_DATE_VIEWMODE_DEFAULT = "dateViewModeDefault";
const FE_DATE_SHOW_CALENDAR_WEEKS = "dateShowCalendarWeeks";
const FE_DATE_CURRENT_DATETIME = "dateUseCurrentDatetime";
const FE_DATE_DATETIME_SIDE_SIDE_BY_SIDE = "datetimeSideBySide";

const FE_DATE_FORMAT_SAVE = 'dateFormatSave';

const FMT_DATE_DD = 'dd';
const FMT_DATE_DD_LAST = 'dd-last';
const FMT_DATE_DD_TODAY = 'dd-today';
const FMT_DATE_DD_MM = 'dd.mm';
const FMT_DATE_DD_MM_YYYY = 'dd.mm.yyyy';
const FMT_DATE_MM = 'mm';
const FMT_DATE_MM_TODAY = 'mm-today';
const FMT_DATE_MM_YYYY = 'mm.yyyy';
const FMT_DATE_YYYY = 'yyyy';
const FMT_DATE_YYYY_TODAY = 'yyyy-today';

const IDX_DAY = 0;
const IDX_MONTH = 1;
const IDX_YEAR = 2;


// FormElement Datepicker parameter
const FE_DATEPICKER_MONTH_YEAR = 'MM-YYYY';
const FE_DATEPICKER_DATE_DB = 'yyyy-mm-dd';
const FE_DATEPICKER_YEAR = 'YYYY';
const FE_DATEPICKER_YEAR_SHORT = 'YY';
const FE_DATEPICKER_MONTH = 'MM';
const FE_DATEPICKER_MONTH_LOWER = 'mm';
const FE_DATEPICKER_DAY = 'DD';
const FE_DATEPICKER_DATE_STANDARD = 'dd.mm.yyyy';
const FIELD_DATE_MODE = 'dateMode';
const FIELD_DATE_TYPE_DATETIME = 'datetime';
const DATE_TIME_PICKER_QFQ = 'qfq';
const DATE_TIME_PICKER_BROWSER = 'browser';
const DATE_TIME_PICKER_NO = 'no';

// FormElement Columns: Only in form file
const FE_FILE_CONTAINER_NAME = 'containerName_ff'; // key for referencing container FormElements by name in form file

// Excel Import
const FE_IMPORT_TO_TABLE = 'importToTable';
const FE_IMPORT_TO_COLUMNS = 'importToColumns';
const FE_IMPORT_FROM_COLUMNS = 'importFromColumns';
const FE_IMPORT_REGION = 'importRegion';
const FE_IMPORT_MODE = 'importMode';
const FE_IMPORT_MODE_APPEND = 'append';
const FE_IMPORT_MODE_REPLACE = 'replace';
const FE_IMPORT_TYPE = 'importType';
const FE_IMPORT_TYPE_AUTO = 'auto';
const FE_IMPORT_TYPE_XLS = 'xls';
const FE_IMPORT_TYPE_XLSX = 'xlsx';
const FE_IMPORT_TYPE_ODS = 'ods';
const FE_IMPORT_TYPE_CSV = 'csv';
const FE_IMPORT_NAMED_SHEETS_ONLY = 'importNamedSheetsOnly';
const FE_IMPORT_READ_DATA_ONLY = 'importSetReadDataOnly';
const FE_IMPORT_LIST_SHEET_NAMES = 'importListSheetNames';
const FE_IMPORT_REGION_APPEND = FE_IMPORT_MODE_APPEND;
const FE_IMPORT_REGION_JOIN = 'join';
const FE_IMPORT_FLAG_INSERTED = 'flagInserted';
const FE_IMPORT_COLUMN_COUNT = 'columnCount';
const FE_IMPORT_START_ID_COUNT = 'startIdCount';
const FE_IMPORT_INSERTED_IDS = 'insertedIds';
const FE_IMPORT_FIRST_INSERTED_ID = 'firstInsertedId';

// Annotate
const FE_TEXT_SOURCE = 'textSource';
const FE_IMAGE_SOURCE = 'imageSource'; // Image source for a fabric element
const FE_DEFAULT_PEN_COLOR = 'defaultPenColor'; // Default pen color for a fabric element
const FE_ANNOTATE_TYPE = 'annotateType'; // Annotate type: graphic|code
const FE_ANNOTATE_TYPE_GRAPHIC = 'graphic';
const FE_ANNOTATE_TYPE_TEXT = 'text';
const FE_ANNOTATE_USER_NAME = 'annotateUserName';
const FE_ANNOTATE_USER_UID = 'annotateUserUid';
const FE_ANNOTATE_USER_AVATAR = 'annotateUserAvatar';
const FE_HIGHLIGHT = 'highlight';
const FE_HIGHLIGHT_OFF = 'off';
const FE_HIGHLIGHT_AUTO = 'auto';
const FE_HIGHLIGHT_JAVASCRIPT = 'javascript';
const FE_HIGHLIGHT_QFQ = 'qfq';
const FE_HIGHLIGHT_PYTHON = 'python';
const FE_HIGHLIGHT_MATLAB = 'matlab';

const FE_CAPTCHA_API_ENDPOINT = 'captchaApiEndpoint'; // Captcha API Endpoint
const FE_CAPTCHA_KEY_SECRET = 'captchaKeySecret'; // Captcha Secret per Endpoint to verify captcha token

const FE_SQL_VALIDATE = 'sqlValidate'; // Action: Query to validate form load
const FE_EXPECT_RECORDS = 'expectRecords'; // Action: expected number of rows of FE_SQL_VALIDATE
const FE_MESSAGE_FAIL = 'messageFail'; // Action: Message to display, if FE_SQL_VALIDATE fails.
const FE_REQUIRED_LIST = 'requiredList'; // Optional list of FormElements which have to be non-empty to make this 'action'-FormElement active.
const FE_QFQ_LOG = 'qfqLog';
const FE_ALERT = 'alert'; // Action: Replacement of messageFail with additional functionality
const FE_ALERT_INDEX_TEXT = 0;
const FE_ALERT_INDEX_LEVEL = 1;
const FE_ALERT_INDEX_BUTTON_OK = 2;
const FE_ALERT_INDEX_BUTTON_FORCE = 3;
const FE_ALERT_INDEX_TIMEOUT = 4;
const FE_ALERT_INDEX_FLAG_MODAL = 5;
const FE_ALERT_TEXT = 'text';
const FE_ALERT_LEVEL = 'level';
const FE_ALERT_BUTTON_OK = 'ok';
const FE_ALERT_BUTTON_FORCE = 'force';
const FE_ALERT_TIMEOUT = 'timeout';
const FE_ALERT_FLAG_MODAL = 'flagModal';
const DEFAULT_ALERT_LEVEL = 'info';
const DEFAULT_ALERT_BUTTON_OK = 'Ok';
const DEFAULT_ALERT_TIMEOUT = '0';
const DEFAULT_ALERT_FLAG_MODAL = '1';
const FE_SLAVE_ID = 'slaveId'; // Action; Value or Query to compute id of slave record.
const FE_SQL_AFTER = 'sqlAfter'; // Action: Always fired
const FE_SQL_BEFORE = 'sqlBefore'; // Action: Always fired
const FE_SQL_UPDATE = 'sqlUpdate'; // Action: Update Statement for slave record
const FE_SQL_INSERT = 'sqlInsert'; // Action: Insert Statement to create slave record.
const FE_SQL_DELETE = 'sqlDelete'; // Action: Delete Statement to delete unused slave record.
const FE_SQL_HONOR_FORM_ELEMENTS = 'sqlHonorFormElements'; // Action: Honor given list of FormElements for sqlInsert|Update|Delete
const ACTION_REQUIRING_BRACES = [FE_SQL_BEFORE, FE_SQL_INSERT, FE_SQL_UPDATE, FE_SQL_DELETE, FE_SQL_AFTER]; // List of FE.parameter Actions that require to be enclosed by {{ }}
const FE_EDITOR_PREFIX = 'editor-'; // TinyMCE configuration settings.
const FE_EDITOR_PLUGINS = FE_EDITOR_PREFIX . 'plugins';
const FE_EDITOR_TOOLBAR = FE_EDITOR_PREFIX . 'toolbar';
const FE_EDITOR_STATUSBAR = FE_EDITOR_PREFIX . 'statusbar';
const FE_EDITOR_FORCED_ROOT_BLOCK = FE_EDITOR_PREFIX . 'forced_root_block';
const FE_EDITOR_EXTENDED_VALID_ELEMENTS = FE_EDITOR_PREFIX . 'extended_valid_elements';
const FE_EDITOR_CONTENTS_CSS = FE_EDITOR_PREFIX . 'content_css';
const FE_EDITOR_RELATIVE_URLS = FE_EDITOR_PREFIX . 'relative_urls';
const FE_EDITOR_DEFAULT_IMAGE_CLASS = 'defaultImageClass';
const FE_EDITOR_IMAGE_CONFIG_TITLE = 'title';
const FE_EDITOR_IMAGE_CONFIG_VALUE = 'value';
const FE_EDITOR_DEFAULT_IMAGE_BORDER = 'imageBorderDefault';
const FE_CODEMIRROR_PREFIX = 'codemirror-'; // CodeMirror configuration settings.
const FE_CODEMIRROR_MODE = FE_CODEMIRROR_PREFIX . 'mode';
const FE_CODEMIRROR_LINE_NUMBERS = FE_CODEMIRROR_PREFIX . 'lineNumbers';
const FE_CODEMIRROR_LINE_WRAPPING = FE_CODEMIRROR_PREFIX . 'lineWrapping';
const FE_CODEMIRROR_TAB_SIZE = FE_CODEMIRROR_PREFIX . 'tabSize';
const FE_CODEMIRROR_STYLE_ACTIVE_LINE = FE_CODEMIRROR_PREFIX . 'styleActiveLine';
const FE_CODEMIRROR_MATCH_BRACKETS = FE_CODEMIRROR_PREFIX . 'matchBrackets';
const FE_CODEMIRROR_AUTO_CLOSE_BRACKETS = FE_CODEMIRROR_PREFIX . 'autoCloseBrackets';
const FE_CODEMIRROR_KEYWORDS_QFQ_BASE = FE_CODEMIRROR_PREFIX . 'keywords-qfq-base';
const FE_EDITOR_TYPE = 'editorType'; // tinymce | codemirror
const FE_EDITOR_TYPE_TINYMCE = 'tinymce';
const FE_EDITOR_TYPE_CODEMIRROR = 'codemirror';
const FE_EDITOR_FILE_UPLOAD_PATH = 'fileUploadPath';
const FE_EDITOR_READ_ONLY = 'readOnly';
const FE_DEFAULT_VALUE = 'defaultValue';

const FE_SENDMAIL_TO = 'sendMailTo'; // Receiver email adresses. Separate multiple by comma.
const FE_SENDMAIL_CC = 'sendMailCc'; // CC Receiver email adresses. Separate multiple by comma.
const FE_SENDMAIL_BCC = 'sendMailBcc'; // BCC Receiver email adresses. Separate multiple by comma.
const FE_SENDMAIL_FROM = 'sendMailFrom'; // Sender email address.
const FE_SENDMAIL_SUBJECT = 'sendMailSubject'; // Email subject
const FE_SENDMAIL_REPLY_TO = 'sendMailReplyTo'; // Reply to email address
const FE_SENDMAIL_FLAG_AUTO_SUBMIT = 'sendMailFlagAutoSubmit'; // on|off - if 'on', suppresses OoO answers from receivers.
const FE_SENDMAIL_GR_ID = 'sendMailGrId'; // gr_id: used to classify mail log entries ind table mailLog
const FE_SENDMAIL_X_ID = 'sendMailXId'; // x_id: used to classify mail log entries ind table mailLog
const FE_SENDMAIL_X_ID2 = 'sendMailXId2'; // x_id: used to classify mail log entries ind table mailLog
const FE_SENDMAIL_X_ID3 = 'sendMailXId3'; // x_id: used to classify mail log entries ind table mailLog
const FE_SENDMAIL_SUBJECT_HTML_ENTITY = 'sendMailSubjectHtmlEntity'; // encode|decode|none  >> DECODE, ENCODE, NONE
const FE_SENDMAIL_BODY_HTML_ENTITY = 'sendMailBodyHtmlEntity'; // encode|decode|none  >> DECODE, ENCODE, NONE
const FE_SENDMAIL_ATTACHMENT = 'sendMailAttachment';
const FE_SENDMAIL_BODY_MODE = 'sendMailMode'; // html >> render body as html
const FE_AUTOFOCUS = 'autofocus'; // value: <none>|0|1  , <none>==1, this element becomes the focus during form load.
const FE_RETYPE = 'retype'; // value: <none>|0|1  , <none>==1, this element becomes the focus during form load.
const FE_RETYPE_LABEL = 'retypeLabel'; // value: label text for retype FormElement
const FE_RETYPE_NOTE = 'retypeNote'; // value: note text for retype FormElement
const FE_RETYPE_SOURCE_NAME = '_retypeSourceName'; // QFQ internal reference to name of source FormElement.
const FE_RETYPE_NAME_EXTENSION = 'RETYPE';
const FE_WRAP_ROW = 'wrapRow';
const FE_WRAP_LABEL = 'wrapLabel';
const FE_WRAP_INPUT = 'wrapInput';
const FE_WRAP_NOTE = 'wrapNote';
const FE_HTML_BEFORE = 'htmlBefore';
const FE_HTML_AFTER = 'htmlAfter';
const FE_TEMPLATE_GROUP_ADD_CLASS = 'tgAddClass';
const FE_TEMPLATE_GROUP_ADD_TEXT = 'tgAddText';
const FE_TEMPLATE_GROUP_REMOVE_CLASS = 'tgRemoveClass';
const FE_TEMPLATE_GROUP_REMOVE_TEXT = 'tgRemoveText';
const FE_TEMPLATE_GROUP_CLASS = 'tgClass';
const FE_TEMPLATE_GROUP_DEFAULT_MAX_LENGTH = 5;
const FE_TEMPLATE_GROUP_NAME_PATTERN = '%d';
const FE_TEMPLATE_GROUP_NAME_PATTERN_0 = '%D';
const FE_TEMPLATE_GROUP_CURRENT_IDX = 'tgCurentIndex';
const FE_BUTTON_CLASS = 'buttonClass';
const FE_BUTTON_CUSTOM = 'btnCustom';
const FE_LDAP_SERVER = F_LDAP_SERVER;
const FE_LDAP_BASE_DN = F_LDAP_BASE_DN;
const FE_LDAP_SEARCH = F_LDAP_SEARCH;
const FE_LDAP_ATTRIBUTES = F_LDAP_ATTRIBUTES;
const FE_LDAP_TIME_LIMIT = F_LDAP_TIME_LIMIT;
const FE_LDAP_USE_BIND_CREDENTIALS = F_LDAP_USE_BIND_CREDENTIALS;
const FE_TYPEAHEAD_LIMIT = F_TYPEAHEAD_LIMIT;
const FE_TYPEAHEAD_MINLENGTH = F_TYPEAHEAD_MINLENGTH;
const FE_TYPEAHEAD_PEDANTIC = F_TYPEAHEAD_PEDANTIC;
const FE_TYPEAHEAD_INITIAL_SUGGESTION = 'typeAheadInitialSuggestion';
const FE_TYPEAHEAD_TAG = 'typeAheadTag';
const FE_TYPEAHEAD_TAG_DELIMITER = 'typeAheadTagDelimiter';
const FE_TYPEAHEAD_GLUE_INSERT = 'typeAheadGlueInsert';
const FE_TYPEAHEAD_GLUE_DELETE = 'typeAheadGlueDelete';
const FE_TYPEAHEAD_TAG_INSERT = 'typeAheadTagInsert';
const FE_TYPEAHEAD_GLUE_UPDATE = 'typeAheadGlueUpdate';

const FE_TYPEAHEAD_SQL = 'typeAheadSql';
const FE_TYPEAHEAD_SQL_PREFETCH = 'typeAheadSqlPrefetch';

// AI assist (Input / Editor FormElements). See Documentation-develop/AI_INFRASTRUCTURE.md
const FE_AI_ASSIST = 'aiAssist';
const FE_AI_PROMPT = SYSTEM_AI_PROMPT;
const FE_AI_CONTEXT = 'aiContext';
const FE_AI_MODEL = 'aiModel';
// RAG chatbot FormElement (native type FE_TYPE_AI_CHAT). The parameters below configure
// the retrieval; see Documentation-develop/AI_INFRASTRUCTURE.md. Empty aiRagSource -> the
// chatbot answers without document retrieval (plain LLM chat).
const FE_AI_RAG_SOURCE = SYSTEM_AI_RAG_SOURCE;
const FE_AI_CHAT_ALLOW_GENERAL = SYSTEM_AI_CHAT_ALLOW_GENERAL;
const FE_AI_THINKING = SYSTEM_AI_THINKING;
const FE_AI_CHAT_CLASS = 'aiChatClass';
const FE_AI_RAG_PROJECT = 'aiRagProject';
// aiRagAcl grammar: a bare default mode, or a comma list of '<source>:<mode>' entries.
//   mode = 'user' (per-login, login from session) | 'user:<login>' (explicit login, e.g. {{feUser:...}})
//        | 'public' | 'off' (needs aiRagProject) | 'all' (NO ACL - dev-asserted, can expose private content).
//   e.g. 'user', 'user:{{feUser:UY0}}', 'redmine:all,kb:user,docs:public'.
const FE_AI_RAG_ACL = SYSTEM_AI_RAG_ACL;
const FE_AI_RAG_K = SYSTEM_AI_RAG_K;
const AI_RAG_ACL_USER = 'user';
const AI_RAG_ACL_PUBLIC = 'public';
const AI_RAG_ACL_OFF = 'off';
const AI_RAG_ACL_ALL = 'all';
const FE_AI_TARGET_LANGUAGE = 'aiTargetLanguage';
const AI_TRANSLATE_LANGUAGES_DEFAULT = 'English,German';
const FE_TYPEAHEAD_LDAP_VALUE_PRINTF = F_TYPEAHEAD_LDAP_VALUE_PRINTF;
const FE_TYPEAHEAD_LDAP_ID_PRINTF = F_TYPEAHEAD_LDAP_ID_PRINTF;
const FE_TYPEAHEAD_LDAP = 'typeAheadLdap';
const FE_TYPEAHEAD_LDAP_SEARCH = F_TYPEAHEAD_LDAP_SEARCH;
const FE_TYPEAHEAD_LDAP_SEARCH_PREFETCH = F_TYPEAHEAD_LDAP_SEARCH_PREFETCH;
const FE_TYPEAHEAD_LDAP_SEARCH_PER_TOKEN = F_TYPEAHEAD_LDAP_SEARCH_PER_TOKEN;
const FE_FILL_STORE_LDAP = 'fillStoreLdap';
const FE_FILL_STORE_VAR = 'fillStoreVar';
const FE_CHARACTER_COUNT_WRAP = 'characterCountWrap';
const FE_CHARACTER_COUNT_CLASS = 'qfq-cc-style';
const FE_INPUT_EXTRA_BUTTON_LOCK = 'extraButtonLock';
const FE_INPUT_EXTRA_BUTTON_PASSWORD = 'extraButtonPassword';
const FE_INPUT_EXTRA_BUTTON_INFO = 'extraButtonInfo';
const FE_INPUT_EXTRA_BUTTON_INFO_CLASS = SYSTEM_EXTRA_BUTTON_INFO_CLASS;
const FE_INPUT_EXTRA_BUTTON_INFO_MIN_WIDTH = 'extraButtonMinWidth';
const FE_INPUT_EXTRA_BUTTON_INFO_MIN_WIDTH_DEFAULT = '250';
const FE_INPUT_TOGGLE = 'toggleInput';
const FE_INPUT_TOGGLE_CONFIG_DEFAULT = 'default';
const FE_INPUT_TOGGLE_CONFIG_LABEL = 'label';
const FE_INPUT_TOGGLE_CONFIG_HIDDEN = 'hidden';
const FE_FILE_NAME_TO_LOWER = F_FILE_NAME_TO_LOWER;
const FE_DATE_TIME_PICKER_TYPE = F_DATE_TIME_PICKER_TYPE;
const FE_INPUT_AUTOCOMPLETE = 'autocomplete';
const FE_TMP_EXTRA_BUTTON_HTML = '_extraButtonHtml'; // will be filled on the fly during building extrabutton
const FE_TMP_AI_ASSIST_ACTIVE = '_aiAssistActive';
const FE_CHECKBOX_CHECKED = 'checked';
const FE_CHECKBOX_UNCHECKED = 'unchecked';
const FE_CHECKBOX_MODE = 'checkBoxMode';
const FE_CHECKBOX_MODE_SINGLE = 'single';
const FE_CHECKBOX_MODE_MULTI = 'multi';
const FE_CHECKBOX_MODE_MULTI_STATE = 'multiState';
const FE_ITEM_LIST = 'itemList';
const FE_RECORD_DESTINATION_TABLE = 'recordDestinationTable';
const FE_RECORD_SOURCE_TABLE = 'recordSourceTable';
const FE_TRANSLATE_ID_COLUMN = 'translateIdColumn';
const FE_EMPTY_MEANS_NULL = 'emptyMeansNull';
const FE_TEXTAREA_RESIZE = 'textareaResize';
const FE_EMPTY_ITEM_AT_START = 'emptyItemAtStart';
const FE_EMPTY_ITEM_AT_END = 'emptyItemAtEnd';
const FE_SUBRECORD_TABLE_CLASS = 'subrecordTableClass';
const FE_SUBRECORD_TABLE_ATTRIBUTE = 'subrecordTableAttribute';
const FE_FILE_BUTTON_TEXT = 'fileButtonText';
const FE_FILE_BUTTON_TEXT_DEFAULT = 'Choose File';
const FE_INPUT_TYPE = 'inputType';
const FE_STEP = 'step';
const FE_ACCEPT_ZERO_AS_REQUIRED = 'acceptZeroAsRequired';
const FE_PROCESS_READ_ONLY = 'processReadOnly';
const FE_INDICATE_REQUIRED = 'indicateRequired';
const FE_DATALIST = 'datalist';
const FE_IMAGE_CUT_RESIZE_WIDTH = 'resizeWidth';

// FE: ImageCut
const FE_IMAGE_KEEP_ORIGINAL = 'keepOriginal';
const FE_IMAGE_OUTPUT_FORMAT = 'outputFormat';
const FE_IMAGE_OUTPUT_QUALITY_JPEG = 'outputQualityJpeg';
const FE_IMAGE_OUTPUT_WIDTH = 'outputWidth';
const FE_IMAGE_OUTPUT_HEIGHT = 'outputHeight';
const FE_IMAGE_DARKEN_MARGIN = 'darkenMargin';
const FE_IMAGE_PREVIEW_HTML_ID = 'previewHtmlId';
const HTML_ID_TARGET_IMAGE = '-target-image'; // ID: data-base64 Element
const HTML_NAME_TARGET_IMAGE = '_b64_image_'; // NAME: data-base64 Element

const IMAGE_ADJUST_CSS_CLASS = 'qfq-image-adjust';

const FE_FLAG_ROW_OPEN_TAG = '_flagRowOpenTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_ROW_CLOSE_TAG = '_flagRowCloseTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_LABEL_OPEN_TAG = '_flagLabelOpenTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_LABEL_CLOSE_TAG = '_flagLabelCloseTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_INPUT_OPEN_TAG = '_flagInputOpenTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_INPUT_CLOSE_TAG = '_flagInputCloseTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_NOTE_OPEN_TAG = '_flagNoteOpenTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_NOTE_CLOSE_TAG = '_flagNoteCloseTag'; // will be automatically computed during Formload: true | false

const FE_MIN = 'min';
const FE_MAX = 'max';
const FE_HTML_ALLOW = 'htmlAllow';
const FE_TINYMCE_DROPDOWN_FORMATS = 'tinymceDropdownFormats';
const FE_TINYMCE_SECURE_IMAGE_UPLOAD = 'secure';

// Save form as Json
const FE_SAVE_FORM_JSON = 'saveFormJson';
const FE_SAVE_FORM_JSON_NAME = 'saveFormJsonName';

// Save formElement as Json
const FE_SAVE_FORMELEMENT_JSON = 'saveFormElementJson';
const FE_SAVE_FORMELEMENT_JSON_NAME = 'saveFormElementJsonName';

const TYPEAHEAD_PLACEHOLDER = '?';

// Values
const FE_ENCODE_SPECIALCHAR = 'specialchar';
const FE_ENCODE_SINGLE_TICK = 'single tick';
const FE_ENCODE_NONE = 'none';
const FE_FILE_CAPTURE_CAMERA = 'camera';

// FormElement Types
const FE_TYPE_CHECKBOX = 'checkbox';
const FE_TYPE_DATE = 'date';
const FE_TYPE_TIME = 'time';
const FE_TYPE_DATETIME = 'datetime';
const FE_TYPE_TEXT = 'text';
const FE_TYPE_SEARCH = 'search';
const FE_TYPE_EDITOR = 'editor';
const FE_TYPE_PASSWORD = 'password';
const FE_TYPE_RADIO = 'radio';
const FE_TYPE_SELECT = 'select';
const FE_TYPE_UPLOAD = 'upload';
const FE_TYPE_ANNOTATE = 'annotate';
const FE_TYPE_IMAGE_CUT = 'imageCut';
const FE_TYPE_CAPTCHA = 'captcha';
const FE_TYPE_EXTRA = 'extra';
const FE_TYPE_SUBRECORD = 'subrecord';
const FE_TYPE_NOTE = 'note';
const FE_TYPE_CHAT = 'chat';
const FE_TYPE_AI_CHAT = 'aiChat';
const FE_TYPE_BEFORE_LOAD = 'beforeLoad';
const FE_TYPE_BEFORE_SAVE = 'beforeSave';
const FE_TYPE_BEFORE_INSERT = 'beforeInsert';
const FE_TYPE_BEFORE_UPDATE = 'beforeUpdate';
const FE_TYPE_BEFORE_DELETE = 'beforeDelete';
const FE_TYPE_AFTER_LOAD = 'afterLoad';
const FE_TYPE_AFTER_SAVE = 'afterSave';
const FE_TYPE_AFTER_INSERT = 'afterInsert';
const FE_TYPE_AFTER_UPDATE = 'afterUpdate';
const FE_TYPE_AFTER_DELETE = 'afterDelete';
const FE_TYPE_SENDMAIL = 'sendMail';
const FE_TYPE_PASTE = 'paste';
const FE_TYPE_COLOR_PICKER = 'colorPicker';
const FE_TYPE_INPUT_COLLECTION_JSON = 'inputCollectionJson';

const FE_TYPE_TEMPLATE_GROUP = 'templateGroup';
const FE_TYPE_FIELDSET = 'fieldset';
const FE_FIELDSET_CSS = 'fieldsetCss';
const FE_TYPE_PILL = 'pill';

const FE_HTML_ID = 'htmlId'; // Will be dynamically computed during runtime.
const FE_SELECT_BS = 'selectBS';
const FE_ORDER_INTERVAL = 'orderInterval';
const FE_ORDER_INTERVAL_DEFAULT = '10';
const FE_ORDER_COLUMN = 'orderColumn';
const FE_DND_TABLE = 'dndTable';

const FE_TMP_CLASS_OPTION = '_classOption';

const FE_DATA_LOAD = 'data-load';
const FE_DATA_MATCH = 'data-match';

const FE_SUBRECORD_EMPTY = SYSTEM_SUBRECORD_EMPTY;

// Form element attributes (FE_*)
const FE_DUMMY_ROW = 'dummy-row';
const FE_MULTI_CHECKBOX_ITEMS = 'checkBoxState';
const MODE_ENCODE = 'encode';
const MODE_ENCODE_ALL = 'encodeAll';
const MODE_DECODE = 'decode';
const MODE_NONE = 'none';

// HTML attributes (HTML_ATTR_*)
const HTML_ATTR_CREATED = 'created';
const HTML_ATTR_DATALIST = 'datalist';
const HTML_ATTR_LIST = 'list';
const HTML_ATTR_SELECTED = 'selected';
const HTML_ATTR_DATA_FILE = 'data-file';
const HTML_ATTR_HREF = 'href';
const HTML_ATTR_MODIFIED = 'modified';
const HTML_ATTR_NOCLICK = 'noclick';
const HTML_ATTR_DISABLED = 'disabled';
const HTML_ATTR_TEXT = 'text';
const HTML_ATTR_TITLE = 'title';
const HTML_ATTR_TYPE = 'type';
const HTML_ATTR_TYPE_CHECKBOX = 'checkbox';
const HTML_ATTR_TYPE_TEXT = 'text';
const HTML_ATTR_VALUE = 'value';
const HTML_ATTR_CHECKED = 'checked';
const HTML_ATTR_STYLE = 'style';
const HTML_ATTR_REQUIRED = 'required';
const HTML_ATTR_CLASS = 'class';
const HTML_ATTR_DATA_SYNC_BY_RULE_TYPE = 'data-sync-by-rule-type';
const HTML_ATTR_DATA_SIP = 'data-sip';
const HTML_ATTR_DATA_BASE_URL = 'data-base-url';
const HTML_ATTR_DATA_TOGGLE = 'data-toggle';
const HTML_ATTR_ARIA_HASPOPUP = 'aria-haspopup';
const HTML_ATTR_ARIA_EXPANDED = 'aria-expanded';

const HTML_DELIMITER_NAME = '-';
const HTML_DELIMITER_ID = HTML_DELIMITER_NAME;

const HTML_ID_EXTENSION_LABEL = '-l';
const HTML_ID_EXTENSION_INPUT = '-i';
const HTML_ID_EXTENSION_NOTE = '-n';
const HTML_ID_EXTENSION_TOOLTIP = '-t';
const HTML_ID_EXTENSION_ROW = '-r';
const HTML_ID_EXTENSION_CHARACTER_COUNT = '-cc';
const HTML_ID_EXTENSION_PILL_LI = '-pl';
const HTML_ID_EXTENSION_PILL_LI_A = '-pla';
const HTML_ID_EXTENSION_BUTTON_GROUP = '-b';
const HTML_ID_EXTENSION_DIV = '-d';
const HTML_ID_EXTENSION_TOGGLE_INPUT = '-Toggle';

const HTML_ATTR_ID = 'id';
const HTML_ATTR_NAME = 'name';
const HTML_ATTR_HIDDEN = 'hidden';

const HTML_INPUT_TYPE_NUMBER = 'number';

const SHEBANG_REPORT = '#!report';

const TOKEN_COMMENT = '#';

// SUPPORT
const PARAM_T3_ALL = 't3 all';
const PARAM_T3_NO_ID = "t3 no id";
const ESCAPE_WITH_BACKSLASH = 'backslash';
const ESCAPE_WITH_HTML_QUOTE = 'htmlquote';

// AbstractBuildForm
const FLAG_ALL = 'flagAll';
const FLAG_DYNAMIC_UPDATE = 'flagDynamicUpdate';

const QUERY_TYPE_SELECT = 'type: select,show,describe,explain';
const QUERY_TYPE_INSERT = 'type: insert';
const QUERY_TYPE_UPDATE = 'type: update,replace,delete';
const QUERY_TYPE_CONTROL = 'type: set';
const QUERY_TYPE_FAILED = 'type: query failed';

//Regexp
//const REGEXP_DATE_INT = '^\d{4}-\d{2}-\d{2}$';
//const REGEXP_DATE_GER = '^\d{1,2}\.\d{1,2}\.\d{2}(\d{2})?$';
//const REGEXP_TIME = '^\d{1,2}:\d{1,2}(:\d{1,2})?$';


// Date/ DateTime formats
const FORMAT_DATE_INTERNATIONAL = 'yyyy-mm-dd';
const FORMAT_DATE_INTERNATIONAL_QFQ = 'YYYY-MM-DD';
const FORMAT_DATE_GERMAN = 'dd.mm.yyyy';
const FORMAT_DATE_GERMAN_QFQ = 'DD.MM.YYYY';

// Upload
const UPLOAD_MODE_UNCHANGED = 'unchanged';
const UPLOAD_MODE_NEW = 'new';
const UPLOAD_MODE_DELETEOLD = 'deleteOld';
const UPLOAD_MODE_DELETEOLD_NEW = 'deleteOld+new';
const UPLOAD_DEFAULT_MAX_SIZE = '10M';
const UPLOAD_DEFAULT_MIME_TYPE = 'application/pdf';
const UPLOAD_LOG_PREFIX = 'Upload';

const MIME_TYPE_SPLIT_CAPABLE = 'application/pdf';

// $_FILES
const FILES_NAME = 'name';
const FILES_TMP_NAME = 'tmp_name';
const FILES_TYPE = 'type';
const FILES_ERROR = 'error';
const FILES_SIZE = 'size';
const FILES_FLAG_DELETE = 'flagDelete';
const FILES_FILEPOND = 'filepond';

const UPLOAD_CACHED = '.cached';
const FILE_ACTION = 'action';
const FILE_ACTION_UPLOAD = 'upload';
const FILE_ACTION_UPLOAD_2 = 'upload2';
const FILE_ACTION_DELETE = 'delete';
const FILE_ACTION_IMAGE_UPLOAD = 'imageUpload';
const FILE_ACTION_DOWNLOAD = 'download';
const UPLOAD_ID = 'uploadId';
const UPLOAD_TEXT = 'text';
const UPLOAD_MIME_TYPE_ACCEPT = 'accept';
const UPLOAD_MULTI_UPLOAD = 'multiUpload';
const UPLOAD_RECORD_DATA = 'recordData';
const UPLOAD_MAX_FILES = 'maxFiles';
const UPLOAD_MAX_FILE_SIZE = SYSTEM_FILE_MAX_FILE_SIZE;
const UPLOAD_ALLOW = 'allowUpload';
const UPLOAD_DOWNLOAD_ALLOW = 'allowDownload';
const UPLOAD_DELETE_OPTION = 'deleteOption';
const UPLOAD_GROUP_ID = 'groupId';
const UPLOAD_SIP_DOWNLOAD_KEY = 'sipDownloadKey';
const UPLOAD_EXTRA_BUTTON_HTML = 'extraButton';
const UPLOAD_DROP_BACKGROUND = 'dropBackground';
const UPLOAD_DOWNLOAD_BUTTON = 'downloadButton';
const UPLOAD_TYPE_FORM = 'form';
const UPLOAD_FORM_ID = 'formId';
const UPLOAD_PATH_FILE_NAME = 'pathFileName';
const UPLOAD_PATH_FILE_NAME_KEY = 'pathFileNameKey';
const UPLOAD_IMAGE_EDITOR = 'imageEditor';
const UPLOAD_PATH_DEFAULT = 'pathDefault';
const UPLOAD_TOOL_TIP = 'tooltip';
const UPLOAD_GLYPH_ICON = 'glyphicon';
const UPLOAD_TYPE = SYSTEM_UPLOAD_TYPE;
const UPLOAD_TYPE_V1 = 'v1'; //deprecated
const UPLOAD_TYPE_BUTTON = 'button';
const UPLOAD_TYPE_V2 = 'v2'; //filepond
const UPLOAD_TYPE_DND = 'dnd';
const UPLOAD_TYPE_DEFAULT = 'dnd';
const F_UPLOAD_SUCCESS_MESSAGE = 'completeMessage';
const F_UPLOAD_IDLE_TEXT = 'uploadText';
const F_UPLOAD_PDF_PROTECTED_ACTION = SYSTEM_UPLOAD_ACTION;
const PATH_FILE_CONCAT = 'pathFileConcat';
const FILE_PRIORITY = 'filePriority';
const UPLOAD_ATTR_TYPE = 'type';
const UPLOAD_ATTR_DATA_PRELOADED_FILES = 'data-preloadedFiles';
const UPLOAD_ATTR_DATA_API_URLS = 'data-api-urls';
const UPLOAD_ATTR_DATA_SIPS = 'data-sips';
const UPLOAD_ATTR_DATA_CONFIG = 'data-config';
const UPLOAD_ATTR_TITLE = 'title';
const UPLOAD_ATTR_STYLE = 'style';
const UPLOAD_VALUE_FILE = 'file';

const FILE_MODE_WRITE = 'w';
const FILE_MODE_APPEND = 'a';

const FILE_NAME_UNIQUE_RETURN_PATH = 'path';
const FILE_NAME_UNIQUE_RETURN_NAME = 'name';
const FILE_NAME_UNIQUE_KEY = 'filenameUnique';
const FILE_NAME_UNIQUE_VAR = '{{' . FILE_NAME_UNIQUE_KEY . ':V}}';
// d: will turn {{filenameDecode:V}} into __filenameDecode_V__
const FILE_NAME_UNIQUE_NAME_VAR_SANITIZED = '__filenameDecode_V__';
const FILE_NAME_UNIQUE_BASE_64_MARKER = 'B64';

// Chat constants
const CHAT_CLIENT_MESSAGE = 'message';
const CHAT_CLIENT_ROOM_FLAG = 'chat_room';
const CHAT_CLIENT_THREAD_ID = 'threadId';
const CHAT_CLIENT_FLAG_FIRST_MSG = 'flagFirstMsg';
const CHAT_CLIENT_RESET_DONE = 'resetDone';
const CHAT_CLIENT_LOAD_MODE = 'load_mode';
const CHAT_CLIENT_ELEMENT_MODE = 'element_mode';
const CHAT_CLIENT_MESSAGE_ID_LIST = 'messageIdList';
const CHAT_DB_COLUMN_NAMES = 'dbColumnNames';
const CHAT_TABLE_NAME = 'tableName';
const CHAT_MESSAGE_ID = 'messageId';
const CHAT_ACTIVE_THREAD = 'activeThread';
const CHAT_ROOM_FLAG = 'chatRoom';
const CHAT_JSON_RESULT = 'result';
const CHAT_TAG_VALUE = 'tagValue';
const CHAT_REACTION_CODE = 'reactionCode';
const CHAT_JSON_REACTIONS = 'reactions';
const CHAT_CID = 'cId';
const CHAT_FIRST_MSG_ID = 'firstMsgId';
const CHAT_TOOLBAR_CONFIG = 'toolbarConfig';
const CHAT_DOWNLOAD_URL = 'downloadUrl';
const CHAT_THUMBNAIL_URL = 'thumbnailUrl';
const CHAT_COLUMN_MAP = 'columnMap';
const CHAT_TYPE_MESSAGE = CHAT_CLIENT_MESSAGE;
const CHAT_COLUMN_ID = 'id';
const CHAT_COLUMN_XID = 'xId';
const CHAT_COLUMN_USERNAME = 'username';
const CHAT_COLUMN_MESSAGE = 'message';
const CHAT_COLUMN_PID_CREATOR = 'pIdCreator';
const CHAT_COLUMN_PID_TEAM = 'pIdTeam';
const CHAT_COLUMN_CID_TOPIC = 'cIdTopic';
const CHAT_COLUMN_CID_THREAD = 'cIdThread';
const CHAT_COLUMN_CID_TAG = 'cIdTag';
const CHAT_COLUMN_CID_MESSAGE = 'cIdMessage';
const CHAT_COLUMN_X_GRID_STATUS = 'xGrIdStatus';
const CHAT_COLUMN_TYPE = 'type';
const CHAT_COLUMN_TYPE_MESSAGE = 'message';
const CHAT_COLUMN_TYPE_REACTION = 'reaction';
const CHAT_COLUMN_TYPE_FILE = 'file';
const CHAT_COLUMN_TYPE_VIDEO_CALL = 'videoCall';
const CHAT_COLUMN_FILE_NAME =  'fileName';
const CHAT_COLUMN_PATH_FILE_NAME = 'pathFileName';
const CHAT_COLUMN_MIME_TYPE = 'mimeType';
const CHAT_COLUMN_FILE_SIZE = 'fileSize';
const CHAT_COLUMN_TYPE_TAG = 'tag';
const CHAT_COLUMN_CREATED = 'created';

const CHAT_LOAD_MODE_REFRESH = 'refresh';
const CHAT_LOAD_MODE_PING = 'ping';
const CHAT_LOAD_MODE_FIRST = 'first';

const CHAT_MODE_SAVE = 'chat_save';
const CHAT_MODE_LOAD = 'chat_load';
const CHAT_MODE_TAG_DONE = 'chat_tag_done';
const CHAT_MODE_TOOLBAR_LOAD = 'chat_toolbar_load';
const CHAT_MODE_TAG_ADD = 'chat_tag_add';
const CHAT_MODE_TAG_DELETE = 'chat_tag_delete';
const CHAT_MODE_REACTION_ADD = 'chat_reaction_add';
const CHAT_MODE_REACTION_DELETE = 'chat_reaction_delete';
const CHAT_MODE_VIDEO_CALL_START = 'chat_videoCall_start';
const CHAT_MODE_ATTACHMENT_UPLOAD = 'chat_attachment_upload';
const CHAT_DONE_RESET = 'reset';
const CHAT_DONE_REGULAR = 'regular';


const CHAT_CONFIG_SIP = 'chat_config';

const CHAT_DONE = 'chatDone';
const CHAT_FLAG_MORE_RECORDS = 'flagMoreRecords';

const CHAT_PARAMETER_XID = CHAT_COLUMN_XID;
const CHAT_PARAMETER_PID_CREATOR = CHAT_COLUMN_PID_CREATOR;
const CHAT_PARAMETER_USERNAME = CHAT_COLUMN_USERNAME;
const CHAT_PARAMETER_CID_TOPIC = CHAT_COLUMN_CID_TOPIC;
const CHAT_PARAMETER_OPTION_TAG_DONE = 'optionTagDone';
const CHAT_PARAMETER_OPTION_TAG = 'optionTag';
const CHAT_PARAMETER_OPTION_REMINDER = 'optionReminder';
const CHAT_PARAMETER_OPTION_TAG_DONE_RESET = 'optionTagDoneResetOnNewMessage';
const CHAT_PARAMETER_THREAD = 'thread';
const CHAT_PARAMETER_PID_TEAM = CHAT_COLUMN_PID_TEAM;
const CHAT_PARAMETER_X_GRID_STATUS = CHAT_COLUMN_X_GRID_STATUS;
const CHAT_REACTION_CODE_REGEX = '/^:[a-z0-9_+-]{1,32}:$/';

const CHAT_TYPE_TAG_DONE = '__done';
const CHAT_ATTACHMENT_MAX_SIZE = 26214400; //25MB in bytes
const CHAT_ATTACHMENT_MIME_WHITELIST = 'image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain'; //In qfqChat.js is the same whitelist in the function qfqChat.addFilesToStaging, do changes there too.
const CHAT_ATTACHMENT_EXTENSION_WHITELIST = 'jpg,jpeg,png,gif,webp,pdf,txt';

// DATABASE
const DB_NUM_ROWS = 'numRows';
const DB_AFFECTED_ROWS = 'affectedRows';
const DB_INSERT_ID = 'insertId';

const COLUMN_ID = 'id';
const COLUMN_FIELD = 'Field';
const COLUMN_CREATED = 'created';
const COLUMN_MODIFIED = 'modified';
const COLUMN_BODYTEXT = 'bodytext';
const COLUMN_ALIAS = 'alias';
const COLUMN_PID = 'pid';
const COLUMN_UID = 'uid';
const COLUMN_HEADER = 'header';
const COLUMN_TITLE = 'title';
const COLUMN_SUBHEADER = 'subheader';
const COLUMN_EXPIRE = 'expire';
const COLUMN_UPLOAD_ID = 'uploadId';
const COLUMN_COUNT = 'count';

const INDEX_PHP = 'index.php';

// QuickFormQuery.php
const T3DATA_BODYTEXT = 'bodytext';
const T3DATA_BODYTEXT_RAW = 'bodytext-raw';
const T3DATA_UID = 'uid';
const T3DATA_SUBHEADER = 'subheader';
const T3DATA_DESCRIPTION = 'description';
const T3DATA_ABSTRACT = 'abstract';
const T3DATA_NAV_TITLE = 'nav_title';
const T3DATA_KEYWORDS = 'keywords';
const T3DATA_PID = 'pid';
const T3DATA_HEADER = 'header';
const T3DATA_REPORT_PATH_FILENAME = 'reportPathFileName';
const T3DATA_OLD_RECORD = 'oldRecord';
const T3DATA_NEW_RECORD = 'newRecord';
const REPORT_INLINE_BODYTEXT = 'bodytext';
const REPORT_INLINE_HEADER = 'header';
const REPORT_INLINE_SUBHEADER = 'subheader';
const REPORT_FILE_EXTENSION = '.qfqr';
const EXISTING_REPORT_FILE = 'existingReportFile';
const FORM_FILE_EXTENSION = '.json';

// Special Column to check for uploads
const COLUMN_PATH_FILE_NAME = 'pathFileName';

// Used to in SIP Store to handle 'delete' after upload
const EXISTING_PATH_FILE_NAME = '_existingPathFileName';

const THUMBNAIL_WIDTH_DEFAULT = '150x';
const THUMBNAIL_MAX_SECONDS = 60;
const THUMBNAIL_PREPARE = 'prepare';
const THUMBNAIL_VIA_DOWNLOAD = 'secureFile';

//SENDMAIL
const SENDMAIL_TOKEN_RECEIVER = 't';
const SENDMAIL_TOKEN_RECEIVER_LONG = 'to';
const SENDMAIL_TOKEN_SENDER = 'f';
const SENDMAIL_TOKEN_SENDER_LONG = 'from';
const SENDMAIL_TOKEN_SUBJECT = 's';
const SENDMAIL_TOKEN_SUBJECT_LONG = 'subject';
const SENDMAIL_TOKEN_BODY = 'b';
const SENDMAIL_TOKEN_BODY_LONG = 'body';
const SENDMAIL_TOKEN_REPLY_TO = 'r';
const SENDMAIL_TOKEN_REPLY_TO_LONG = 'reply-to';
const SENDMAIL_TOKEN_FLAG_AUTO_SUBMIT = 'A';
const SENDMAIL_TOKEN_FLAG_AUTO_SUBMIT_LONG = 'autosubmit';
const SENDMAIL_TOKEN_GR_ID = 'g';
const SENDMAIL_TOKEN_GR_ID_LONG = 'grid';
const SENDMAIL_TOKEN_X_ID = 'x';
const SENDMAIL_TOKEN_X_ID_LONG = 'xid';
const SENDMAIL_TOKEN_X_ID2 = 'y';
const SENDMAIL_TOKEN_X_ID2_LONG = 'xid2';
const SENDMAIL_TOKEN_X_ID3 = 'z';
const SENDMAIL_TOKEN_X_ID3_LONG = 'xid3';
const SENDMAIL_TOKEN_HEADER = 'h';
const SENDMAIL_TOKEN_HEADER_LONG = 'header';
const SENDMAIL_TOKEN_SRC = 'S';
const SENDMAIL_TOKEN_SRC_LONG = 'source';
const SENDMAIL_TOKEN_RECEIVER_CC = 'c';
const SENDMAIL_TOKEN_RECEIVER_CC_LONG = 'cc';
const SENDMAIL_TOKEN_RECEIVER_BCC = 'B';
const SENDMAIL_TOKEN_RECEIVER_BCC_LONG = 'bcc';
const SENDMAIL_TOKEN_ATTACHMENT = 'attachment';
const SENDMAIL_TOKEN_ATTACHMENT_FILE = 'F';
const SENDMAIL_TOKEN_ATTACHMENT_FILE_DEPRECATED = 'a'; // since 5.12.17
const SENDMAIL_TOKEN_SUBJECT_HTML_ENTITY = 'e';
const SENDMAIL_TOKEN_BODY_HTML_ENTITY = 'E';
const SENDMAIL_TOKEN_BODY_MODE = 'mode';
const SENDMAIL_TOKEN_BODY_MODE_LONG = 'mode';
const SENDMAIL_TOKEN_BODY_MODE_HTML = 'html';

const SENDMAIL_TOKEN_CONCAT = 'C';
const SENDMAIL_TOKEN_DOWNLOAD_FILENAME = 'd';
const SENDMAIL_TOKEN_DOWNLOAD_MODE = 'M';
const SENDMAIL_TOKEN_ATTACHMENT_URL = 'u';
const SENDMAIL_TOKEN_ATTACHMENT_URL_PARAM = 'U';
const SENDMAIL_TOKEN_ATTACHMENT_PAGE = 'p';

// Record history
const RECORD_HISTORY_LOAD = 'historyLoad';
const RECORD_HISTORY_FORM_DATA = 'formData';
const RECORD_HISTORY_FE_USER = 'feUser';
const RECORD_HISTORY_CREATED = 'created';
const RECORD_HISTORY_FORM_LABEL_DATA = 'formLabelData';
const RECORD_HISTORY_FORM_NAMES = 'formNames';
const RECORD_HISTORY_FORM_ID = 'formId';
const RECORD_HISTORY_DATA = 'data';

// Report, BodyText
const TOKEN_SQL = 'sql';
const TOKEN_FUNCTION = 'function';
const TOKEN_TWIG = 'twig';
const TOKEN_HEAD = 'head';
const TOKEN_ALT_HEAD = 'althead';
const TOKEN_ALT_SQL = 'altsql';
const TOKEN_TAIL = 'tail';
const TOKEN_SHEAD = 'shead';
const TOKEN_STAIL = 'stail';
const TOKEN_RBEG = 'rbeg';
const TOKEN_REND = 'rend';
const TOKEN_RENR = 'renr';
const TOKEN_RSEP = 'rsep';
const TOKEN_FBEG = 'fbeg';
const TOKEN_FEND = 'fend';
const TOKEN_FSEP = 'fsep';
const TOKEN_LBEG = 'lbeg';
const TOKEN_LEND = 'lend';
const TOKEN_LIBEG = 'libeg';
const TOKEN_LIEND = 'liend';
const TOKEN_FSKIPWRAP = 'fskipwrap';
const TOKEN_RBGD = 'rbgd';
const TOKEN_DEBUG = 'debug';
const TOKEN_FORM = CLIENT_FORM;
const TOKEN_RECORD_ID = CLIENT_RECORD_ID;
const TOKEN_DEBUG_BODYTEXT = TYPO3_DEBUG_SHOW_BODY_TEXT;
const TOKEN_DB_INDEX = F_DB_INDEX;
//Report Cache
const REPORT_CACHE_TOKEN = 'cache';
const REPORT_CACHE_PURGE_FILES_OLDER_DAYS = 7;
const REPORT_CACHE_RENDER_TIME = 'renderTimeMs';
const REPORT_CACHE_R_STORE_BEFORE_CACHE = 'rStoreBeforeCache';
const REPORT_CACHE_FULL_CACHE_KEY = 'fullCacheKey';
const REPORT_CACHE_STORE = 'store';
const REPORT_CACHE_TABLE_KEY = '@';
const REPORT_CACHE_PATH = 'typo3temp/var/cache-qfq/';
// cacheState array keys: per-level cache state passed between Report and ReportCache
const REPORT_CACHE_START = 'cacheStart';
const REPORT_CACHE_FILE_PATH = 'cacheFilePath';
const REPORT_CACHE_PAIRS = 'pairs';
const REPORT_CACHE_STORE_RECORD = 'cacheStoreRecord';
const REPORT_CACHE_REMOVED_R_KEYS = 'removedRKeys';
// Valid dependency stores for the cache key parameter ('@' = table-update dependency)
const REPORT_CACHE_VALID_STORES = ['R', 'S', 'T', 'U', 'C', 'Y', REPORT_CACHE_TABLE_KEY];
const REPORT_CACHE_EVENT_TYPE_HIT   = 'hit';
const REPORT_CACHE_EVENT_TYPE_WRITE = 'write';
// Keywords parsed from QFQ Report code will be converted to LC. Most of the keywords do not have camelcase (=already LC) >> No LC version required.
const TOKEN_DB_INDEX_LC = 'dbindex';
const TOKEN_CONTENT = 'content';
const TOKEN_REPORT_FILE = 'file';
const TOKEN_ALIAS = 'alias';
const TOKEN_NOTATION_NUMERIC = 'numeric';
const TOKEN_NOTATION_ALIAS = 'alias';
const TOKEN_PERFORMANCE_REPORT = 'performanceReport';

const TOKEN_VALID_LIST = 'sql|function|twig|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|fskipwrap|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content|render|performanceReport|lbeg|lend|libeg|liend|cache';

const TOKEN_COLUMN_CTRL = '_';

const TOKEN_CONTENT_STORE = 'store';
const TOKEN_CONTENT_HIDE_LEVEL = 'hideLevel';
const TOKEN_CONTENT_HIDE = 'hide';
const TOKEN_CONTENT_SHOW = 'show';

const LINE_COUNT = 'count';
const LINE_TOTAL = 'total';
const LINE_INSERT_ID = 'insertId';

const LINE_ALT_COUNT = 'altCount';
const LINE_ALT_TOTAL = 'altTotal';
const LINE_ALT_INSERT_ID = 'altInsertId';

//Report: Column Token
const COLUMN_LINK = 'link';
const COLUMN_AUTHENTICATE = 'authenticate';
const COLUMN_UPLOAD = 'upload';
const COLUMN_EXEC = 'exec';
const COLUMN_THUMBNAIL = 'thumbnail';
const COLUMN_FUNCTION = 'function';
const COLUMN_PPAGE = 'Page';
const COLUMN_PPAGEC = 'Pagec';
const COLUMN_PPAGED = 'Paged';
const COLUMN_PPAGEE = 'Pagee';
const COLUMN_PPAGEH = 'Pageh';
const COLUMN_PPAGEI = 'Pagei';
const COLUMN_PPAGEN = 'Pagen';
const COLUMN_PPAGES = 'Pages';
const COLUMN_PPDF = 'Pdf';
const COLUMN_ZZIP = 'Zip';
const COLUMN_FFILE = 'File';

const COLUMN_PAGE = 'page';
const COLUMN_PAGEC = 'pagec';
const COLUMN_PAGED = 'paged';
const COLUMN_PAGEE = 'pagee';
const COLUMN_PAGEH = 'pageh';
const COLUMN_PAGEI = 'pagei';
const COLUMN_PAGEN = 'pagen';
const COLUMN_PAGES = 'pages';

const COLUMN_YANK = 'yank';

const COLUMN_PDF = 'pdf';
const COLUMN_SAVE_PDF = 'savePdf';
const COLUMN_SAVE_ZIP = 'saveZip';
const COLUMN_FILE = 'file';
const COLUMN_ZIP = 'zip';
const COLUMN_MONITOR = 'monitor';
const COLUMN_EXCEL = 'excel';
const COLUMN_NL2BR = 'nl2br';
const COLUMN_HTMLENTITIES = 'htmlentities';
const COLUMN_STRIPTAGS = 'striptags';
const COLUMN_MIME_TYPE = 'mimeType'; // Will also be used to identify equal named columns in upload record.
const COLUMN_FILE_SIZE = 'fileSize'; // Will also be used to identify equal named columns in upload record.
const COLUMN_EXCEL_PLAIN = 'XLS';
const COLUMN_EXCEL_NUMERIC = 'XLSn';
const COLUMN_EXCEL_STRING = 'XLSs';
const COLUMN_EXCEL_BASE64 = 'XLSb';

const COLUMN_BULLET = "bullet";
const COLUMN_CHECK = "check";
const COLUMN_IMG = "img";
const COLUMN_MAILTO = "mailto";
const COLUMN_SENDMAIL = "sendmail";
const COLUMN_VERTICAL = "vertical";
const COLUMN_WEBSOCKET = "websocket";
const COLUMN_REST_CLIENT = "restClient";
const COLUMN_SCRIPT = "script";

const COLUMN_NO_WRAP = "noWrap";
const COLUMN_HIDE = "hide";
const C_FULL = 'full';
const C_TITLE = 'title';
const C_NO_WRAP = 'noWrap';
const C_SPECIAL = 'special';
const C_HIDE = 'hide';
const C_STORE = 'store';
const C_ENCRYPTION_METHOD = SYSTEM_ENCRYPTION_METHOD;

const COLUMN_WRAP_TOKEN = '+';
const COLUMN_STORE_USER = '=';

const COLUMN_FORM_JSON = 'formJson';
const COLUMN_FORM_ELEMENT_JSON = 'formElementJson';
const EXTRA_FE_MY_JSON = 'myFormJson';

const COLUMN_JWT = 'jwt';
const COLUMN_MESSENGER_TOKEN = 'messengerToken';

const COLUMN_ENCRYPT = 'encrypt';
const COLUMN_DECRYPT = 'decrypt';

// Special Column: Input/Filter elements (renders FormElement inputs in Reports)
const COLUMN_INPUT = 'input';

// Input Filter Mode for load.php API
const INPUT_FILTER_CONTENT_MODE = 'filterContent'; // Main content loading (with validation)
const INPUT_FILTER_COUNT_MODE = 'filterCount';      // Count refresh only (no validation)
const INPUT_FILTER_COUNT_SIPS = 'countSips';
const INPUT_FILTER_COUNT_TOTAL = 'total';
const INPUT_FILTER_PARAMS = 'filterParams';
const API_INPUT_FILTER_COUNTS = 'filter-counts';

// Data attributes for input filter elements
const DATA_TARGET = 'data-target';
const DATA_PARAM = 'data-param';
const DATA_COUNT_SIP = 'data-count-sip';
const DATA_LABEL = 'data-label';

// Input filter validation (allowedValues included directly in combined SIP)
const INPUT_FILTER_ALLOWED_VALUES = 'allowedValues';
const INPUT_FILTER_VALIDATION_ERROR = 'Filter option restricted';

// Input filter target registry keys
const INPUT_FILTER_KEY_QFQ_FUNCTION_NAME = 'qfqFunctionName';
const INPUT_FILTER_KEY_UID_PARAMS = 'uidParams';
const INPUT_FILTER_KEY_PARAMS = 'params';

// _input column token constants
const TOKEN_INPUT_FORM_ELEMENT = 'f';           // formName.feName (required for all variants)
const TOKEN_INPUT_UID = 'uid';                  // qfqFunctionName (required for filter variant)
const TOKEN_INPUT_TARGET_CLASS = 'targetClass'; // CSS target class (required for filter variant)

const FORM_NAME_FORM = 'form';
const FORM_NAME_FORM_ELEMENT = 'formElement';
const FORM_LOG_MODE = '_formLogMode'; // Variable to call the form in debug mode.
const FORM_LOG_SESSION = 'logSession';
const FORM_LOG_ALL = 'logAll';
const FORM_LOG_HTML_ID = 'formLog-1';
const FORM_LOG_FILE = 'formLogFile';
const FORM_LOG_FILE_SESSION = FORM_LOG_FILE . '_' . FORM_LOG_SESSION;
const FORM_LOG_FILE_ALL = FORM_LOG_FILE . '_' . FORM_LOG_ALL;
const FORM_LOG_FILE_EXPIRE = 1800; // time in seconds after the last
const FORM_LOG_ACTIVE = 'formLogActive';

// DOWNLOAD
const DOWNLOAD_MODE = 'mode';
const DOWNLOAD_MODE_FILE = 'file';
const DOWNLOAD_MODE_PDF = 'pdf';
const DOWNLOAD_MODE_TEXT = 'txt';
const DOWNLOAD_MODE_QFQPDF = 'qfqpdf';
const DOWNLOAD_MODE_SAVE_PDF = 'save-pdf';
const DOWNLOAD_MODE_SAVE_ZIP = 'save-zip';
const DOWNLOAD_MODE_EXCEL = 'excel';
const DOWNLOAD_MODE_ZIP = 'zip';
const DOWNLOAD_MODE_THUMBNAIL = 'thumbnail';
const DOWNLOAD_MODE_MONITOR = 'monitor';
const DOWNLOAD_MODE_CHAT_ATTACHMENT = 'chat-attachment';
const DOWNLOAD_EXPORT_FILENAME = '_exportFilename';
const DOWNLOAD_PARAM_CACHE = '_cache';
const DOWNLOAD_CACHE_STATUS = 'status';
const DOWNLOAD_CACHE_STATUS_NO = 'no';
const DOWNLOAD_CACHE_STATUS_VALID = 'valid';
const DOWNLOAD_CACHE_STATUS_CREATE = 'create';
const DOWNLOAD_CACHE_PATH = 'path';
const TMP_FILE_PREFIX = 'qfq.temp.'; // temporary filename on server of single export file
const DOWNLOAD_OUTPUT_FILENAME = 'output';
const DOWNLOAD_SIP_ENCODE_PARAMETER = '_sip';
const DOWNLOAD_OUTPUT_FORMAT = '_dataFormat';
const DOWNLOAD_OUTPUT_FORMAT_RAW = 'raw';
const DOWNLOAD_OUTPUT_FORMAT_JSON = 'json';
const DOWNLOAD_MODAL_API_PARAMETER = 'modalDownload';
const DOWNLOAD_MODAL_PREPARE_FILE = 'prepFile';
const DOWNLOAD_MODAL_FILE_NAME = 'fileName';
const DOWNLOAD_MODAL_FILE_PATH = 'filePath';
const DOWNLOAD_MODAL_DOWNLOAD_FILE = 'downloadFile';
const DOWNLOAD_MODAL_TRIGGER_CLASS = 'modalDownload';
const DOWNLOAD_MODAL_PROGRESS_FILE_PATH = 'typo3temp/var/progress-qfq/';
const DOWNLOAD_MODAL_GET_STATUS = 'progress';
const DOWNLOAD_MODAL_GET_MODE = 'downloadMode';
const DOWNLOAD_MODAL_GET_JOBID = 'jobId';
const DOWNLOAD_MODAL_GET_TIMING = 'timing';
const DOWNLOAD_MODAL_GET_DELETE_FILE = 'deleteFile';
const DOWNLOAD_MODAL_STATUS_PREPARING = 'preparing';
const DOWNLOAD_MODAL_STATUS_CURRENT_FILES = 'currentFiles';
const DOWNLOAD_MODAL_STATUS_TOTAL_FILES = 'totalFiles';
const DOWNLOAD_MODAL_STATUS_COMPLETE = 'complete';
const DOWNLOAD_MODAL_TIMING_SAMPLES = 'samples';

const JSON_TEXT = 'text';

const OUTPUT_MODE_DIRECT = 'direct'; // Send the file direct via readfile() to the browser
const OUTPUT_MODE_FILE = 'file'; // return a filename
const OUTPUT_MODE_COPY_TO_FILE = 'copyToFile'; // create a local copy return a filename

const EXCEL_WORKSHEET = 'worksheet';
const EXCEL_MODE = 'mode';
const EXCEL_MODE_INSERT = 'insert';
const EXCEL_MODE_OVERWRITE = 'overwrite';
const EXCEL_POSITION = 'position';
const EXCEL_NEWLINE = 'newline';
const EXCEL_STRING2 = 'str';
const EXCEL_STRING = 's';
const EXCEL_FORMULA = 'f';
const EXCEL_NUMERIC = 'n';
const EXCEL_BASE64 = 'b';
const EXCEL_NULL = 'null';
const EXCEL_INLINE = 'inlineStr';
const EXCEL_ERROR = 'e';
const EXCEL_IMPORT_FROM_COLUMN_MODE_ONLY = 'onlyFrom';
const EXCEL_IMPORT_FROM_COLUMN_MODE_SIMPLE = 'simple';
const EXCEL_IMPORT_FROM_COLUMN_MODE_BOTH = 'both';
const EXCEL_HEADER_NAME = 'header_name';
const EXCEL_COL = 'excel_col';
const EXCEL_OCCURRENCE = 'occurrence';

const MONITOR_TAIL_DEFAULT = 30;
const MONITOR_APPEND_DEFAULT = 0;
const MONITOR_INTERVAL_DEFAULT = 1000;
const MONITOR_HTML_ID_DEFAULT = 'monitor-1';

// HTML2PDF
const HTML2PDF_PAGEID = 'id';
const HTML2PDF_PARAM_GET = 'paramGet';
const HTML2PDF_URL_PRINT = 'urlPrint';

const SESSION_COOKIE_PREFIX = 'qfq.cookie.'; // temporary 'cookie file' to forward `fe_user` and `qfq` session.
const SESSION_LAST_ACTIVITY = 'lastActivity';
const SESSION_LAST_COOKIE_FE = 'lastCookieFe';

// Class: LINK
const NAME_URL = 'url';
const NAME_MAIL = 'mail';
const NAME_PAGE = 'page';
const NAME_UID = 'uid';
const NAME_SOURCE = 'source';
const NAME_TEXT = 'text';
const NAME_DROPDOWN = 'dropdown';
const NAME_DOWNLOAD = DOWNLOAD_EXPORT_FILENAME;
const NAME_COLLECT_ELEMENTS = 'downloadElements';  // array with element sources
const NAME_DOWNLOAD_MODE = 'mode';
const NAME_BOOTSTRAP_BUTTON = 'bootstrapButton';
const NAME_ALT_TEXT = 'altText';
const NAME_TOOL_TIP = 'toolTip';
const NAME_TOOL_TIP_JS = 'toolTipJs';
const NAME_IMAGE = 'image';
const NAME_IMAGE_TITLE = 'imageTitle';
const NAME_GLYPH = 'glyph';
const NAME_GLYPH_TITLE = 'glyphTitle';
const NAME_DELETE = 'delete';
const NAME_RENDER = 'render';
const NAME_TARGET = 'target';
const NAME_LINK_CLASS = 'linkClass';
const NAME_LINK_CLASS_DEFAULT = 'linkClassDefault';
const NAME_QUESTION = 'question';
const NAME_ENCRYPTION = 'encryption';
const NAME_SIP = 'sip';
const NAME_URL_PARAM = 'param';
const NAME_RIGHT = 'picturePositionRight';
const NAME_ACTION_DELETE = 'actionDelete';
const NAME_ORDER_TEXT = 'orderText';
const NAME_ORDER_TEXT_WRAP = 'orderTextWrap';
const NAME_EXTRA_CONTENT_WRAP = 'extraContentWrap';
const NAME_FILE = 'file';
const NAME_THUMBNAIL = 'thumbnail';
const NAME_THUMBNAIL_DIMENSION = 'thumbnailDimension';
const NAME_COPY_TO_CLIPBOARD = 'copyToClipBoard';
const FLAG_COPY_TO_CLIPBOARD = 'flagCopyToClipBoard';
const NAME_MONITOR = 'monitor';
const NAME_ATTRIBUTE = 'attribute';
const NAME_ATTRIBUTE2 = 'attribute2';
const NAME_EMAIL = 'email';
const NAME_REALNAME = 'realname';
const NAME_BEFORE_LINK = 'beforeLink';
const NAME_AFTER_LINK = 'afterLink';
const NAME_CACHE = 'cache';
const NAME_REDIRECT_HTTP_CODE = 'httpCode';
const NAME_BACK_BUTTON = '_back';
const NAME_STICKY_TOOL_TIP = 'stickyToolTip';
const NAME_MAILTO_SELECT = 'select';
const NAME_COPY_PASTE = 'copyPaste';

// Name constants for Inline-Rendering in Link.php
const NAME_INLINE_FORM_ELEMENT = 'inlineFormElement';
const NAME_INLINE_UID = 'inlineUid';
const NAME_INLINE_TARGET_CLASS = 'inlineTargetClass';
const NAME_INLINE_TYPE = 'inlineType';

const FINAL_WRAP_TAG = 'wrapTag';

const FINAL_HREF = 'finalHref';
const FINAL_RENDER_HREF = 'finalRenderHref';
const FINAL_ANCHOR = 'finalAnchor';
const FINAL_CONTENT = 'finalContent';
const FINAL_CONTENT_PURE = 'finalContentPure';
const FINAL_SYMBOL = 'finalSymbol';
const FINAL_TOOL_TIP = 'finalToolTip';
const FINAL_CLASS = 'finalClass';
const FINAL_QUESTION = 'finalQuestion';
const FINAL_THUMBNAIL = 'finalThumbnail';
const FINAL_HTTP_CODE = 'finalHttpCode';

const FINAL_BUTTON = 'finalButton';

const FINAL_JS = 'finalJs';

const FINAL_IS_LINK = 'finalIsLink';

const FINAL_BUTTON_ID = 'finalButtonId';

const FINAL_NO_REDIRECT = 'finalNoRedirect';

const TOOLTIP_DEBUG = 'tooltipDebug';

const LINK_ANCHOR = 'linkAnchor';
const LINK_PICTURE = 'linkPicture';

const NO_CLASS = 'no_class';

const DEFAULT_BULLET_COLOR = 'green';
const DEFAULT_CHECK_COLOR = 'green';
const DEFAULT_RENDER_MODE = '0';
const DEFAULT_QUESTION_TEXT = 'Please confirm';
const DEFAULT_QUESTION_LEVEL = 'info';
const DEFAULT_ACTION_DELETE = 'r';
const DEFAULT_CACHE = '1000-01-01 00:00:00';

const QUESTION_INDEX_TEXT = 0;
const QUESTION_INDEX_LEVEL = 1;
const QUESTION_INDEX_BUTTON_OK = 2;
const QUESTION_INDEX_BUTTON_FALSE = 3;
const QUESTION_INDEX_TIMEOUT = 4;
const QUESTION_INDEX_FLAG_MODAL = 5;

const PARAM_DELIMITER = '|';
const PARAM_TOKEN_DELIMITER = ':';
const PARAM_VAR_DELIMITER = ':';

// It is allowed to set variable in the following stores
const STORE_SET_ALLOWED = 'ARUVW';

const PARAM_LIST_DELIMITER = ',';
const PARAM_KEY_VALUE_DELIMITER = ':';
const TOKEN_STICKY_TOOL_TIP = 'O';
const TOKEN_URL = 'u';
const TOKEN_MAIL = 'm';
const TOKEN_PAGE = 'p';
const TOKEN_UID = 'uid';
const TOKEN_SOURCE = 'source';
const TOKEN_DOWNLOAD = 'd';
const TOKEN_COPY_TO_CLIPBOARD = 'y';
const TOKEN_DROPDOWN = 'z';
const TOKEN_WEBSOCKET = 'w';
const TOKEN_REST_CLIENT = 'n';
const TOKEN_SCRIPT = 'F';
const TOKEN_INLINE_EDIT = 'i';
const TOKEN_IMAP = 'J';
const TOKEN_IMPORT = 'import';
const TOKEN_EXPORT = 'export';

const TOKEN_TEXT = 't';
const TOKEN_ALT_TEXT = 'a';
const TOKEN_TOOL_TIP = 'o';
const TOKEN_BOOTSTRAP_BUTTON = 'b';
const TOKEN_PICTURE = 'P';
const TOKEN_BULLET = 'B';
const TOKEN_CHECK = 'C';
const TOKEN_DELETE = 'D';
const TOKEN_EDIT = 'E';
const TOKEN_HELP = 'H';
const TOKEN_INFO = 'I';
const TOKEN_NEW = 'N';
const TOKEN_SHOW = 'S';
const TOKEN_GLYPH = 'G';
const TOKEN_RENDER = 'r';
const TOKEN_TARGET = 'g';
const TOKEN_CLASS = 'c';
const TOKEN_QUESTION = 'q';
const TOKEN_ENCRYPTION = 'e';
const TOKEN_SIP = 's';
const TOKEN_URL_PARAM = 'U';
const TOKEN_RIGHT = 'R';
const TOKEN_FILE = 'F';
const TOKEN_FILE_DEPRECATED = 'f';  // since 5.12.17
const TOKEN_DOWNLOAD_MODE = 'M';
const TOKEN_ATTRIBUTE = 'A';
const TOKEN_BEFORE_LINK = 'v';
const TOKEN_AFTER_LINK = 'V';
const TOKEN_REDIRECT_HTTP_CODE = 'h';

const TOKEN_FUNCTION_CALL = 'call';
const TOKEN_ARGUMENT = 'arg';
const TOKEN_FORM_ID = 'fid';
const TOKEN_FORMELEMENT_ID = 'feid';
const TOKEN_ENCODING_BASE_64 = 'b64';
const TOKEN_REDUCE_KEYS = 'reduce';
const TOKEN_ORDER_TEXT = 'Y';
const TOKEN_CACHE = 'cache';

const TOKEN_THUMBNAIL = 'T';
const TOKEN_THUMBNAIL_DIMENSION = 'W';

const TOKEN_MONITOR = 'L';

const TOKEN_ACTION_DELETE = 'x';
const TOKEN_ACTION_DELETE_AJAX = 'a';
const TOKEN_ACTION_DELETE_REPORT = 'r';
const TOKEN_ACTION_DELETE_CLOSE = 'c';

const TOKEN_CLASS_NONE = 'n';
//const TOKEN_CLASS_INTERNAL = 'i';
//const TOKEN_CLASS_EXTERNAL = 'e';

// Following tokens are defined in 'long' form: TOKEN_L_...
const TOKEN_L_FILE = 'file';
const TOKEN_L_TAIL = 'tail';
const TOKEN_L_APPEND = 'append';
const TOKEN_L_INTERVAL = 'interval';
const TOKEN_L_HTML_ID = 'htmlId';

const TOKEN_L_METHOD = 'method';
const TOKEN_L_HEADER = 'header';
const TOKEN_L_CONTENT = 'content';
const TOKEN_L_CONTENT_FILE = 'contentFile';
const TOKEN_L_TIMEOUT = 'timeout';
const TOKEN_L_SSL = 'ssl';

const TOKEN_UPLOAD_ID = UPLOAD_ID;
const TOKEN_UPLOAD_MIME_TYPE_ACCEPT = UPLOAD_MIME_TYPE_ACCEPT;
const TOKEN_SIP_TABLE = SIP_TABLE;
const TOKEN_UPLOAD_MULTI_UPLOAD = 'M';
const TOKEN_UPLOAD_RECORD_DATA = UPLOAD_RECORD_DATA;
const TOKEN_UPLOAD_MAX_FILES = UPLOAD_MAX_FILES;
const TOKEN_UPLOAD_MAX_FILE_SIZE = UPLOAD_MAX_FILE_SIZE;
const TOKEN_UPLOAD_ALLOW = UPLOAD_ALLOW;
const TOKEN_UPLOAD_DELETE = TOKEN_ACTION_DELETE;
const TOKEN_UPLOAD_IMAGE_EDITOR = UPLOAD_IMAGE_EDITOR;
const MONITOR_MODE_APPEND_0 = '0';
const MONITOR_MODE_APPEND_1 = '1';
const MONITOR_SESSION_FILE_SEEK = 'monitor-seek-file';

const RENDER_MODE_0_LINK = 0;
const RENDER_MODE_1_LINK_OR_TEXT = 1;
const RENDER_MODE_2_LINK_WITH_TEXT = 2;
const RENDER_MODE_3_TEXT_OR_URL = 3;
const RENDER_MODE_4_URL_OR_TEXT = 4;
const RENDER_MODE_5_NONE = 5;

const RENDER_MODE_6_ONLY_TEXT = 6;
const RENDER_MODE_7_ONLY_URL = 7;
const RENDER_MODE_8_ONLY_SIP = 8;
const RENDER_MODE_9_REDIRECT = 9;

// Submodes for Inline-Rendering (used in Link.php)
const SUBMODE_INLINE_FILTER = 300;
const SUBMODE_INLINE_EDIT = 400;

const REPORT_TOKEN_FINAL_VALUE = '&';

const WKHTML_OPTION_VIEWPORT = '--viewport-size';
const WKHTML_OPTION_VIEWPORT_VALUE = '1280x1024';


const HTTP_REDIRECT_DEFAULT = 303;
const HTTP_REDIRECT_GET = 303;
const HTTP_REDIRECT_TEMP = 307;
const HTTP_REDIRECT_PERM = 308;


// Class AuthLink
const AUTH_TOKEN_CREATE = 'c';
const AUTH_TOKEN_UNLOCK = 'u';
const AUTH_TOKEN_ACTIVATE = 'a';
const AUTH_TOKEN_FORCE = 'f';
const AUTH_TOKEN_UPDATE = 'm';

const AUTH_CREATE = 'create';
const AUTH_UNLOCK = 'unlock';
const AUTH_ACTIVATE = 'activate';
const AUTH_FORCE = 'force';
const AUTH_UPDATE = 'modify';

const AUTH_STATUS_OK = 'OK';
const AUTH_STATUS_LOCKED = 'LOCKED';
const AUTH_STATUS_INACTIVE = 'INACTIVE';

const AUTH_STATUS_EXPIRED = 'EXPIRED';
const AUTH_STATUS_NOT_FOUND = 'NOT_FOUND';

// FormAction.php:
const ACTION_ELEMENT_NO_CHANGE = 0;
const ACTION_ELEMENT_MODIFIED = 1;
const ACTION_ELEMENT_DELETED = -1;

// Dirty.php
const DIRTY_MODE_EXCLUSIVE = 'exclusive';
const DIRTY_MODE_ADVISORY = 'advisory';
const DIRTY_MODE_NONE = 'none';
const DIRTY_QFQ_USER_SESSION_COOKIE = 'qfqUserSessionCookie';
const DIRTY_FE_USER = 'feUser';
const DIRTY_EXPIRE = 'expire';
const DIRTY_TABLE_NAME = 'tableName';
const DIRTY_PRIMARY_KEY = 'primaryKey';
const DIRTY_RECORD_ID = 'recordId';
const DIRTY_RECORD_HASH_MD5 = 'recordHashMd5';
const DIRTY_RECORD_HASH_MD5_SPAN = 'recordHashMd5Span';
const DIRTY_REMOTE_ADDRESS = 'remoteAddress';
const DIRTY_API_ACTION = 'action';  // Name of parameter in API call of dirty.php?action=...&s=...
const DIRTY_API_ACTION_LOCK = 'lock';
const DIRTY_API_ACTION_RELEASE = 'release';
const DIRTY_API_ACTION_EXTEND = 'extend';
const DIRTY_API_SAME_USER = 'sameUser';
const LOCK_NOT_FOUND = 0;
const LOCK_FOUND_OWNER = 1;
const LOCK_FOUND_CONFLICT = 2;
const TAB_UNIQ_ID = 'tabUniqId'; // Uniq identifier per tab: no values stored behind the identifier - might change.

// Class EncryptDecrypt
const ENCRYPTION_METHOD_AES_128 = 'AES-128';
const ENCRYPTION_METHOD_AES_256 = 'AES-256';
const ENCRYPTION_KEYWORD_ENCRYPTED_DATA = '$encryptedData$';
const ENCRYPTION_IV = 'iv';
const ENCRYPTION_CIPHER_METHOD = 'cipherMethod';
const ENCRYPTION_CIPHERTEXT = 'ciphertext';
const DB_COLUMN_TYPE = 'type';
const DB_COLUMN_TYPE_DATETIME = 'datetime';
const DB_COLUMN_LENGTH = 'length';
const DB_COLUMN_NAME = 'name';
const ENCRYPTION_CIPHER_METHOD_COLUMN_NAME = 'cipherMethodColumnName';
const ENCRYPTION_VALUE = 'encryptedValue';
const ENCRYPTION_METHOD_KEYWORD = SYSTEM_ENCRYPTION_METHOD;

// AutoCron
const AUTOCRON_MAX_AGE_MINUTES = 10;
const AUTOCRON_TYPE = 'type';
const AUTOCRON_TYPE_WEBSITE = 'website';
const AUTOCRON_TYPE_MAIL = 'mail';
const AUTOCRON_LAST_RUN = 'lastRun';
const AUTOCRON_LAST_STATUS = 'lastStatus';
const AUTOCRON_NEXT_RUN = 'nextRun';
const AUTOCRON_FREQUENCY = 'frequency';
const AUTOCRON_IN_PROGRESS = 'inProgress';
const AUTOCRON_STATUS = 'status';
const AUTOCRON_CONTENT = 'content';
const AUTOCRON_SQL1 = 'sql1';
const AUTOCRON_OUTPUT_FILE = 'outputFile';
const AUTOCRON_OUTPUT_MODE = 'outputMode';
const AUTOCRON_OUTPUT_PATTERN = 'outputPattern';
const AUTOCRON_STATUS_OK = 'OK: ';
const AUTOCRON_STATUS_ERROR = 'Error: ';

const AUTOCRON_UNIT = 'unit';
const AUTOCRON_COUNT = 'count';

// Annotate
const ANNOTATE_GRAPHIC_CSS_CLASS = 'annotate-graphic'; // Ex 'fabric'
const ANNOTATE_TEXT_CSS_CLASS = 'annotate-text'; // Ex 'codeCorrection
const ANNOTATE_EXTRA_BUTTON_HTML = 'data-extraButton';

// DataImport
const IMPORT_MODE_APPEND = 'append';
const IMPORT_MODE_REPLACE = 'replace';
const IMPORT_REGION_DEFAULT = '1';
const IMPORT_PREFIX = 'Import_';

const EXCEPTION_TYPE = 'Type';
const EXCEPTION_FORM = 'Form';
const EXCEPTION_FORM_ELEMENT = 'Form Element';
const EXCEPTION_FORM_ELEMENT_COLUMN = 'Form Element Column';
const EXCEPTION_SQL_RAW = 'SQL before evaluation';
const EXCEPTION_SQL_FINAL = 'SQL final';
const EXCEPTION_SQL_PARAM_ARRAY = 'SQL Params';

const EXCEPTION_REPORT_COLUMN_INDEX = 'Report column index'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_COLUMN_NAME = 'Report column name'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_COLUMN_VALUE = 'Report column value'; // Keyname of SQL-column processed at the moment.
const EXCEPTION_REPORT_FULL_LEVEL = 'Report level key';
const EXCEPTION_REPORT_LINE = 'Report line';

const EXCEPTION_SIP = 'current sip';
const EXCEPTION_PAGE_ID = 'Page Id';
const EXCEPTION_TT_CONTENT_UID = 'Content Id';
const EXCEPTION_FE_USER = 'FE User';
const EXCEPTION_FE_USER_STORE_USER = 'FE User STORE_USER';
const EXCEPTION_EDIT_FORM = 'Edit';

const EXCEPTION_TIMESTAMP = 'Timestamp';
const EXCEPTION_UNIQID = 'UniqId';
const EXCEPTION_CODE = 'Code';
const EXCEPTION_MESSAGE = 'Message'; // Will be shown on every exception. NO sensitive data here!
const EXCEPTION_MESSAGE_DEBUG = SYSTEM_MESSAGE_DEBUG;  // Will only be shown as debugging (Typically BE user is logged in)

const EXCEPTION_FILE = 'File';
const EXCEPTION_LINE = 'Line';
const EXCEPTION_CWD = 'CWD';
const EXCEPTION_STACKTRACE = 'Stacktrace';
const EXCEPTION_IP_ADDRESS = 'IP Address';
const EXCEPTION_QFQ_COOKIE = 'QFQ Cookie';
const EXCEPTION_HTTP_USER_AGENT = 'HTTP User Agent';
const EXCEPTION_PHP_SESSION = 'PHP Session';

const EXCEPTION_TABLE_CLASS = 'table table-hover qfq-table-80';

const EXCEPTION_DB_UPDATE_FORM = 'DB Update';

// Drag And Drop
const DND_DRAG_ID = 'dragId';
const DND_DRAG_POSITION = 'dragPosition';
const DND_SET_TO = 'setTo';
const DND_SET_TO_BEFORE = 'before';
const DND_SET_TO_AFTER = 'after';
const DND_HOVER_ID = 'hoverId';
const DND_HOVER_POSITION = 'hoverPosition';
const DND_COLUMN_ID = 'id';
const DND_COLUMN_ORD = 'ord';
const DND_COLUMN_ORD_NEW = 'ordNew';
const DND_DATA_DND_API = 'data-dnd-api';
const DND_SUBRECORD_ID = 'dnd-subrecord-id'; // Internal qualifier used to communicate with dnd api for subrecord dnd
const DND_SUBRECORD_FORM_ID = 'dnd-subrecord-form-id';
const DND_SUBRECORD_FORM_TABLE = 'dnd-subrecord-form-table';
const DND_ORD_HTML_ID_PREFIX = 'qfq-dnd-ord-id-';
const DND_FORM_SIP_VALUES = '_sipForm';
const DND_DB_INDEX = 'dnd-db-index';

// Application Test: SELENIUM
const ATTRIBUTE_DATA_REFERENCE = 'data-reference';

// REST
const HTTP_HEADER_AUTHORIZATION = 'Authorization';
const HTTP_HEADER_X_API_KEY = 'X-Api-Key';

const HTTP_200_OK = '200 OK';
const HTTP_201_CREATED = '201 Created';

const HTTP_400_BAD_REQUEST = '400 Bad Request';
const HTTP_401_UNAUTHORIZED = '401 Unauthorized';
const HTTP_403_FORBIDDEN = '403 Forbidden';
const HTTP_403_METHOD_NOT_ALLOWED = '405 Method Not Allowed';
const HTTP_404_NOT_FOUND = '404 Not Found';
const HTTP_409_CONFLICT = '409 Conflict';
const HTTP_400_INVALID_EXTENSION = 'HTTP/1.1 400 Invalid extension.';
const HTTP_400_INVALID_FILE_NAME = 'HTTP/1.1 400 Invalid file name.';
const HTTP_403_ORIGIN_DENIED = 'HTTP/1.1 403 Origin Denied';
const HTTP_500_SERVER_ERROR = 'HTTP/1.1 500 Server Error';

// update sql functions
const ACTION_FUNCTION_UPDATE = '_fupdate';  // get parameter to set the update behaviour of function.sql
const ACTION_FUNCTION_UPDATE_NEXT_UPDATE = 'nextUpdate'; // function.sql is updated at next qfq update
const ACTION_FUNCTION_UPDATE_NEVER = 'never'; // function.sql is never updated
const ACTION_FUNCTION_UPDATE_NOT_PERFORMED = 'notUpdated'; // function.sql update was skipped during last qfq update
const QFQ_VERSION_KEY_FUNCTION_HASH = 'functionHash';
const QFQ_VERSION_KEY_FUNCTION_VERSION = 'functionVersion';
const QFQ_VERSION_KEY = 'Version';
const QFQ_FUNCTION_DEFAULT_SQL = 'qfqFunctionDefault.sql';
const QFQ_FUNCTION_PREFIX = 'qfqFunction';

const QFQ_TABLE_DEFAULT_SQL = 'qfqTableDefault.sql';
const QFQ_TABLE_PREFIX = 'qfqTable';

// update special column names (add '_' in front)
const ACTION_SPECIAL_COLUMN_UPDATE = '_scupdate';  // get parameter to set the update behaviour
const ACTION_SPECIAL_COLUMN_DO_REPLACE = 'replace'; // special columns are automatically replaced
const ACTION_SPECIAL_COLUMN_DO_SKIP_REPLACE = 'skip_replace'; // special columns are automatically replaced

// page slug migration
const ACTION_SLUG_MIGRATION_UPDATE = '_pamupdate'; // get parameter to set the update behaviour
const ACTION_SLUG_MIGRATION_DO_REPLACE = 'replace'; // replace page aliases by slugs
const ACTION_SLUG_MIGRATION_DO_PAUSE = 'pause'; // disable the slug migration check temporarily
const ACTION_SLUG_MIGRATION_DO_RESUME = 'resume'; // resume the slug migration check
const ACTION_SLUG_MIGRATION_DO_SKIP_FOREVER = 'skipForever'; // disable the slug migration check
const QFQ_VERSION_KEY_SLUG_MIGRATION = 'pageSlugMigration'; // written to note of Form table
const QFQ_VERSION_KEY_SLUG_MIGRATION_DONE = 'done'; // migration check passed once without occurrences found
const QFQ_VERSION_KEY_SLUG_MIGRATION_SKIP = 'skip'; // migration was skipped forever using link in exception
// bs zero column check
const ACTION_BS_ZERO_COL_CHECK = '_bsZeroColCheck';
const ACTION_BS_ZERO_COL_CHECK_SKIP_ONCE = 'skipOnce';
const ACTION_BS_ZERO_COL_CHECK_SKIP_FOREVER = 'skipForever';
const QFQ_VERSION_KEY_BS_ZERO_COL_CHECK = 'bsZeroColCheck';
const QFQ_VERSION_KEY_BS_ZERO_COL_CHECK_DONE = 'done';
const QFQ_VERSION_KEY_BS_ZERO_COL_CHECK_SKIP = 'skip';
const QFQ_BS_ZERO_COL_FIX = 'qfqBsZeroColFix';         // session key for affected FE entries
const BS_ZERO_COL_FIX_INPUT_PREFIX = 'bs_zero_fix_';   // checkbox name prefix
const BS_ZERO_COL_FIX_SUBMIT = 'bs_zero_fix_submit';   // submit button name

const QFQ_VERSION_KEY_TABLE_SPLIT = 'tableFileSplit';
const QFQ_VERSION_KEY_TABLE_SPLIT_OFF = '0';
const QFQ_VERSION_KEY_TABLE_SPLIT_ON = '1';

// tablesorter
const TABLESORTER_VIEW_SAVER = 'tablesorter-view-saver';
const DATA_TABLESORTER_VIEW = 'data-tablesorter-view';
const DATA_TABLESORTER_SIP = 'data-tablesorter-sip';
const DATA_TABLESORTER_BASE_URL = 'data-tablesorter-base-url';

// Data attributes (DATA_*)
const DATA_BASE_URL = 'data-base-url';
const DATA_CLASS_ON_CHANGE = 'data-class-on-change';
const DATA_HISTORY_TITLE = 'data-history-title';
const DATA_TABLESORTER_VIEW_JSON = 'data-tablesorter-view-json';
const DATA_CHAT_CONFIG = 'data-chat-config';

// Setting
const SETTING_TYPE_TABLESORTER = 'tablesorter';
const SETTING_TABLE_NAME = 'Setting';
const SETTING_TABLE_COLUMN_TYPE_CREDENTIALS = 'credentials';
const SETTING_TABLESORTER_TABLE_ID = 'tableId';
const SETTING_TABLESORTER_FE_USER = 'feUser';
const SETTING_TABLESORTER_PUBLIC = 'public';
const SETTING_TABLESORTER_NAME = 'name';
const SETTING_TABLESORTER_VIEW = 'view';
const SETTING_TABLESORTER_READONLY = 'readonly';
const SETTING_TABLESORTER_MODE = 'mode';
const SETTING_TABLESORTER_MODE_DELETE = 'delete';
const SETTING_TABLESORTER_CLEAR = 'Clear';

const COLUMN_FUNCTION_OUTPUT = '_output';

// Object: Type
const T_LABEL = 't_label';
const T_INPUT = 't_input';
const T_NOTE = 't_note';
const T_ = 't_note';

// Object: Item
const I_TYPE = 'type';
const I_ID = 'id';
const I_VALUE = 'value';
const I_CLASS = 'class';
const I_ATTRIBUTE = 'attribute';

// Object: extra for checkboxes
const I_CHECKED = 'checked';
const I_UNCHECKED = 'unchecked';

// Rest Client
const HTTP_STATUS = 'http-status';
const ERROR_MESSAGE = 'error-message';

// Author: Jan Haller
// Wiki
const HTML_TAG_H1 = 'h1';
const HTML_TAG_H2 = 'h2';
const HTML_TAG_H3 = 'h3';
const HTML_TAG_H4 = 'h4';
const HTML_TAG_H5 = 'h5';
const HTML_TAG_H6 = 'h6';
const HTML_TAG_HTML = 'html';
const HTML_TAG_BODY = 'body';
const WIKI_CSS_CLASS_QFQ_WIKI_CONTENT = 'qfq-wiki-content';
const WIKI_CSS_CLASS_QFQ_WIKI_NAVIGATION = 'qfq-wiki-navigation';
const WIKI_CSS_CLASS_QFQ_WIKI_TOC = 'qfq-wiki-toc';
const WIKI_CSS_CLASS_QFQ_WIKI_CHILD_PAGES = 'qfq-wiki-child-pages';
const WIKI_CSS_CLASS_QFQ_WIKI_COLLAPSE_LINK = 'qfq-wiki-collapse-link';
const WIKI_CSS_CLASS_QFQ_WIKI_COLLAPSE_CHEVRON = 'qfq-wiki-collapse-chevron';
const WIKI_CSS_CLASS_QFQ_WIKI_COLLAPSE_CONTAINER = 'qfq-wiki-collapse-container';
const WIKI_CSS_CLASS_QFQ_WIKI_LINK = 'qfq-wiki-link';
const WIKI_CSS_CLASS_GLYPHICON = 'glyphicon';
const WIKI_CSS_CLASS_GLYPHICON_CHEVRON_DOWN = 'glyphicon-chevron-down';
const WIKI_CSS_CLASS_GLYPHICON_CHEVRON_RIGHT = 'glyphicon-chevron-right';
const WIKI_HTML_ID_QFQ_WIKI_COLLAPSE_CHEVRON = 'qfq-wiki-collapse-chevron';
const WIKI_HTML_ID_QFQ_WIKI_COLLAPSE_CONTENT = 'qfq-wiki-collapse-content';
const WIKI_HTML_ID_QFQ_WIKI_SECTION = 'qfq-wiki-section';
const WIKI_PAGE_COLUMN_ID = 'id';
const WIKI_PAGE_COLUMN_CONTENT = 'content';
const WIKI_PAGE_COLUMN_PAGE_SLUG = 'pageSlug';
const WIKI_PAGE_COLUMN_NAME = 'name';
const WIKI_PAGE_COLUMN_WP_ID_PARENT = 'wpIdParent';
const WIKI_PAGE_COLUMN_WP_ID_CURRENT = 'wpIdCurrent';
const WIKI_PAGE_COLUMN_RO_USER = 'roUser';
const WIKI_PAGE_COLUMN_RO_GROUP = 'roGroup';
const WIKI_PAGE_COLUMN_RO_PUBLIC = 'roPublic';
const WIKI_PAGE_COLUMN_RW_USER = 'rwUser';
const WIKI_PAGE_COLUMN_RW_GROUP = 'rwGroup';
const WIKI_PAGE_COLUMN_RW_PUBLIC = 'rwPublic';
const WIKI_PAGE_COLUMN_PAGE_LOCK = 'pageLock';
const WIKI_PAGE_COLUMN_AUTHOR = 'author';
const WIKI_PAGE_COLUMN_IMAGE_BORDER = 'imageBorder';
const WIKI_PAGE_COLUMN_WP_ID = 'wpId';
const WIKI_PAGE_TABLE_WIKI_PAGE = 'WikiPage';
const WIKI_PAGE_TABLE_WIKI_ATTACHMENT = 'WikiAttachment';
const WIKI_PAGE_SECTION_ID = 'sectionId';
const WIKI_PAGE_SECTION_ID_START = 'sectionIdStart';
const WIKI_PAGE_SECTION_ID_END = 'sectionIdEnd';
const WIKI_PAGE_CONTENT = 'wikiPageContent';
const WIKI_HEADING_TITLE = 'headingTitle';
const WIKI_RENDER_MODE = 'renderMode';
const WIKI_PRINT_MODE = 'printMode';
const WIKI_TOKEN_ACTION = 'action';
const WIKI_TOKEN_WIKI_ACCESS = 'wikiAccess';
const WIKI_TOKEN_CHILD_PAGES = '{{childPages}}';
const WIKI_TOKEN_TABLE_OF_CONTENTS = '{{toc}}';
const WIKI_TOKEN_EDIT_SECTION = 'editSection';
const WIKI_TOKEN_EDIT_ALL = 'editAll';
const WIKI_TOKEN_ACCESS_READ_ONLY = 'ro';
const WIKI_TOKEN_ACCESS_READ_WRITE = 'rw';
const WIKI_TOKEN_ACCESS_OFF = 'off';
const WIKI_TOKEN_ACCESS_ON = 'on';
const WIKI_TOKEN_WIKI_PAGE_ID_PREVIOUS = 'wpIdPrevious';
const WIKI_TOKEN_FE_USER = 'feUser';
// End author

// Issue Constants
const ISSUE_TABLE = 'Issue';
const ISSUE_NAME = 'issue';
const ISSUE_COLUMN_ID = 'id';
const ISSUE_BUTTON_HTML_ID = 'issue-button';

// Author : Zhoujie Li
// Multiform
const MULTIFORM_DELETE_ROW_ID = 'multiFormDeleteRowId';

const FLAG_MULTIFORM = 'flagMultiForm';
const MULTIFORM_ADD_ROW_BTN = 'addRowBtn';
const MULTIFORM_DELETE_ROW_BTN = 'deleteRowBtn';
const F_MULTIFORM_ADD_ROW = 'multiFormAddRow';
const F_MULTIFORM_DELETE_ROW = 'multiFormDeleteRow';
// End from author


// Misc
const BASE_URL_FAKE = 'http://i_am_set_in_constants_php/qfq/';
const HTTP_EXAMPLE_COM = 'http://example.com/';
const QFQ_VERSION_EXAMPLE = '10.0.0';
// Max columnsize FormSubmitLog.formData
const LOG_MAX_FORMDATA = 65535;

const QFQ_CREATE_TABLE = 'qfqCreateTable';

// Element Renderer

const RENDER_MODE_HTML = 'html';
const RENDER_MODE_JSON = "JSON";
const RENDER_MODE_PLAIN = 'plain';

const ICON_RENDERER_TAG = 'tag';
const ICON_RENDERER_FAMILY = 'family';
const ICON_RENDERER_DEFAULT_FAMILY = 'default_family_name';
const ICON_RENDERER_NAME = 'name';

const ICON_RENDERER_DEFAULT_TAG = 'i';

// Button-specific constants (BTN_*)
const BTN_CLASS = 'class';
const BTN_DISABLED = 'disabled';
const BTN_HISTORY_TITLE = 'historyTitle';
const BTN_HTML_ID = 'buttonHtmlId';
const BTN_ICON = 'icon';
const BTN_ID = 'id';
const BTN_ONCHANGE_CLASS = 'onChangeClass';
const BTN_ONCLICK = 'onClick';
const BTN_SIP = 'sip';
const BTN_TABLESORTER_VIEW = 'tablesorterView';
const BTN_TEXT = "text";
const BTN_TOOLTIP = 'tooltip';
const BTN_TYPE_BUTTON = 'button';
const BTN_URL = 'url';
const BTN_TITLE = 'title';

// FE: Validation
const DOUBLE_OPEN_BRACE = '{{';
const DOUBLE_OPEN_BRACE_WITH_EXCLAMATION = '{{!';
const NO_BRACE = '';
const DOUBLE_CLOSE_BRACE = '}}';
const DOUBLE_OPEN_BRACE_WITH_SQUARE_BRACKET = '{{[';


// EMAIL_SYNC
const ES_MODE_LIST_ALL_FOLDER = 'listAllFolder';
const ES_MODE_LIST_ALL_FOLDER_ALL_MAIL = 'listAllFolderMail';
const ES_MODE_SYNC = 'sync';
const ES_MODE_SYNC_POLL = 'syncPoll';
const ES_MODE_ACTION = 'action';

const ES_COL_ACCOUNT = 'account';
const ES_COL_MESSAGE_ID = 'messageId';
const ES_COL_FOLDER_PATH = 'folderPath';
const ES_COL_SENDER = 'sender';
const ES_COL_RECEIVER = 'receiver';
const ES_COL_CC = 'cc';
const ES_COL_SUBJECT = 'subject';
const ES_COL_BODYTEXT = 'bodyText';
const ES_COL_BODYHTML = 'bodyHtml';
const ES_COL_ATTACHMENT = 'attachment';
const ES_COL_HEADER = 'header';
const ES_COL_FLAGS = 'flags';
const ES_COL_MAIL_DATE = 'mailDate'; // real send/receive time from the Date header (created = sync time)

const ES_TABLENAME = 'EmailSync';

// Re-auth notification: delegated OAuth2 whose refresh token died (e.g. sign-in-frequency policy).
const SYSTEM_IMAP_NOTIFICATION_EMAIL = 'imapNotificationEmail'; // ext_conf recipient; empty = off
const ES_REAUTH_NOTIFY_INTERVAL_SECONDS = 86400; // max one re-auth mail per account per 24h
const ES_REAUTH_MARKER_SUFFIX = '.reauth-notified';
const ES_REAUTH_CHECK_EVERY_CYCLES = 8640; // ~24h at 10s poll

const SYSTEM_IMAP_SYNC_ATTACHMENTS = 'imapSyncAttachments'; // ext_conf checkbox; default off
const SYSTEM_IMAP_ATTACHMENT_MAX_MB = 'imapAttachmentMaxMB'; // ext_conf size limit in MB
const SYSTEM_IMAP_OAUTH2_CLIENT_ID = 'imapOAuth2ClientId'; // ext_conf: Microsoft OAuth2 client id (own Azure app); empty = OAuth2 accounts cannot authenticate
const ES_ATTACHMENT_MAX_MB_DEFAULT = 25; // fallback when imapAttachmentMaxMB is unset/invalid
const ES_ATTACHMENT_DIR = 'emailSync'; // subdir under the protected project dir

const ES_SYNC_CHUNK_SIZE = 100; // header fetch page size (a full-folder body fetch overflows the server)
const ES_SYNC_SINCE_BUFFER_DAYS = 2; // incremental SEARCH SINCE buffer (day granularity + TZ slack)
const ES_SYNC_FULL_WALK_EVERY_CYCLES = 360; // full reconciliation walk ~hourly
const ES_SYNC_THROTTLE_MS = 100; // full-walk backfill: pause between chunks so a large folder doesn't saturate disk/network I/O (0 = off)

// EMAIL_SYNC IMAP OAuth2 (XOAUTH2). Setting.view password 'oauth2token:<path>' points to a token file.
const IMAP_OAUTH2_TOKEN_PREFIX = 'oauth2token:';
const IMAP_AUTHENTICATION_OAUTH = 'oauth'; // Webklex 'authentication' value forcing SASL XOAUTH2
const IMAP_OAUTH2_EXPIRY_MARGIN_SECONDS = 300; // renew this early; cushions PHP/system TZ drift

// Token file JSON keys - the well-known mutt oauth2 token format, do not change.
const IMAP_OAUTH2_KEY_REGISTRATION = 'registration';
const IMAP_OAUTH2_KEY_AUTHFLOW = 'authflow';
const IMAP_OAUTH2_KEY_EMAIL = 'email';
const IMAP_OAUTH2_KEY_ACCESS_TOKEN = 'access_token';
const IMAP_OAUTH2_KEY_ACCESS_TOKEN_EXPIRATION = 'access_token_expiration';
const IMAP_OAUTH2_KEY_REFRESH_TOKEN = 'refresh_token';
// Optional token-file overrides (own Azure app).
const IMAP_OAUTH2_KEY_TOKEN_ENDPOINT = 'token_endpoint';
const IMAP_OAUTH2_KEY_DEVICECODE_ENDPOINT = 'devicecode_endpoint';
const IMAP_OAUTH2_KEY_CLIENT_ID = 'client_id';
const IMAP_OAUTH2_KEY_CLIENT_SECRET = 'client_secret';
const IMAP_OAUTH2_KEY_TENANT = 'tenant';
const IMAP_OAUTH2_KEY_SCOPE = 'scope';
// Pending device-flow state (QFQ addition; survives mutt read/write).
const IMAP_OAUTH2_KEY_DEVICE_CODE = 'device_code';
const IMAP_OAUTH2_KEY_DEVICE_CODE_EXPIRATION = 'device_code_expiration';

const IMAP_OAUTH2_AUTHFLOW_DEVICECODE = 'devicecode';
const IMAP_OAUTH2_AUTHFLOW_CLIENT_CREDENTIALS = 'clientcredentials'; // app-only (shared mailboxes)

const IMAP_OAUTH2_REGISTRATION_MICROSOFT = 'microsoft';
const IMAP_OAUTH2_REGISTRATION_GOOGLE = 'google';
const IMAP_OAUTH2_TOKEN_ENDPOINT_MICROSOFT = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
const IMAP_OAUTH2_TOKEN_ENDPOINT_GOOGLE = 'https://accounts.google.com/o/oauth2/token';
const IMAP_OAUTH2_DEVICECODE_ENDPOINT_MICROSOFT = 'https://login.microsoftonline.com/common/oauth2/v2.0/devicecode';
const IMAP_OAUTH2_DEVICECODE_ENDPOINT_GOOGLE = 'https://oauth2.googleapis.com/device/code';
// offline_access is required for a refresh token.
const IMAP_OAUTH2_SCOPE_MICROSOFT = 'offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/SMTP.Send';
const IMAP_OAUTH2_SCOPE_GOOGLE = 'https://mail.google.com/';
const IMAP_OAUTH2_SCOPE_CLIENT_CREDENTIALS_MICROSOFT = 'https://outlook.office365.com/.default';
// client_credentials needs the tenant-specific endpoint, not /common. %s = tenant id.
const IMAP_OAUTH2_TOKEN_ENDPOINT_MICROSOFT_TENANT_TEMPLATE = 'https://login.microsoftonline.com/%s/oauth2/v2.0/token';

// Keys of the internal IMAP credential array: EmailSync::extractImapCredentials() builds it,
// generateImapConfigArray()/getAccountListToProcess()/notifyReauthIfNeeded() read it.
const IMAP_CRED_HOST = 'host';
const IMAP_CRED_USERNAME = 'username';
const IMAP_CRED_PASSWORD = 'password';
const IMAP_CRED_AUTHENTICATION = 'authentication';
const IMAP_CRED_REAUTH_NEEDED = 'reauthNeeded';
const IMAP_CRED_TOKEN_PATH = 'tokenPath';
const IMAP_CRED_FOLDER = 'folder';
const IMAP_CRED_PORT = 'port';
const IMAP_CRED_ENCRYPTION = 'encryption';
const IMAP_CRED_VALIDATE_CERT = 'validate_cert';

const LOG_LEVEL_ERROR = 0;
const LOG_LEVEL_MODIFY = 1;
const LOG_LEVEL_ALL = 2;
const LOG_LEVEL_DEBUG = 3;
const LOG_LEVEL_NONE = 10;

// Form BibTex upload parameter
const OWNER_ID_KEY = 'pId';
const FILE_TYPE_KEY = 'fileType';
const FILE_TYPE_BIB = 'bib';
const FIELD_TYPE = 'type';
const FIELD_CITEKEY = 'kiteKey';
const FIELD_TARGETTABLE = 'targetTable';
const TABLE_PUBLICATION = 'Publication';
const MIME_TYPE_TEXT_PLAIN = 'text/plain';

// Dev Panel Constants START
const API_DEV_PANEL_ACTION = 'action';
const API_DEV_PANEL_ACTION_GET_STORE = 'getStore';
const API_DEV_PANEL_ACTION_GET_INFO = 'getInfo';
const API_DEV_PANEL_ACTION_GET_PERFORMANCE = 'getPerformance';
const API_DEV_PANEL_ACTION_GENERATE_LINK = 'genLink';
const API_DEV_PANEL_ACTION_POLL_LOGS = 'pollLogs';
const API_DEV_PANEL_ACTION_CLEAR_DIRTY = 'clearDirty';
const API_DEV_PANEL_ACTION_CLEAR_REPORT_CACHE = 'clearReportCache';
const API_DEV_PANEL_ACTION_APPLY_CHANGES = 'applyChanges';
const API_DEV_PANEL_ACTION_GET_REPORT_CACHE = 'getReportCache';
const STORE_NAME_USER = 'User';
const STORE_NAME_TYPO3 = 'Typo3';
const STORE_NAME_RECORD = 'Record';
const STORE_NAME_SYSTEM = 'System';
const STORE_NAME_SIP = 'SIP';
const STORE_NAME_CLIENT = 'Client';
const STORE_NAME_FORM = 'Form';
const API_INFO_KEY_TYPO3 = 'Typo3 Version';
const API_INFO_KEY_QFQ = 'QFQ Version';
const API_INFO_KEY_PHP = 'PHP Version';
const API_INFO_KEY_WEBSERVER = 'Webserver';
const API_INFO_KEY_DB = 'DB Server';
const REPORT_CACHE_SESSION_KEY = 'reportCacheEvents';
const PERFORMANCE_SESSION_KEY = 'sqlPerformance';
const API_LOGS_SQL_KEY = 'sql';
const API_LOGS_MAIL_KEY = 'mail';
const API_LOGS_QFQ_KEY = 'qfq';
const API_STORE_READONLY_FLAG_KEY = 'readOnly';
const API_STORE_DATA_KEY = 'data';
const DEV_PANEL_SESSION_FLAG_CHANGES = 'appliedChanges';
const DEV_PANEL_SESSION_FLAG_BUILD = 'buildDevPanel';
const DEV_PANEL_SESSION_FLAG_BUILD_NO = 'no';
const DEV_PANEL_SESSION_FLAG_BUILD_YES = 'yes';
const DEV_PANEL_SESSION_FLAG_BUILD_TIME = 'timeOfBuildDevPanel';
const FAKE_NEVER_USE_ID = 'fake_uniq_never_use_this';
const DEV_PANEL_API_ENDPOINT = 'typo3conf/ext/qfq/Classes/Api/devPanel.php';
const JS_ARRAY_KEY_STORE = 'store';
const JS_ARRAY_KEY_INFO = 'info';
const JS_ARRAY_KEY_REPORT_CACHE = 'reportCache';
const JS_ARRAY_KEY_LINK = 'link';
const JS_ARRAY_KEY_PERFORMANCE = 'performance';
const JS_ARRAY_KEY_LOGS = 'logs';
const JS_ARRAY_KEY_CLEAR_DIRTY = 'clearDirty';
const JS_ARRAYKEY_CLEAR_REPORTCACHE = 'clearCache';
const JS_ARRAY_KEY_APPLY_CHANGES = 'applyChanges';
const DEV_PANEL_REBUILD_TIMEOUT_NS = (5 * 60 * 1e9); // 5min in nanoseconds
const DEV_PANEL_PREVENT_BUILD_PARAM = 'preventBuildDevPanel';
const DEV_PANEL_PERFORMANCE_ARRAY_KEY_QUERY = 'query';
const DEV_PANEL_PERFORMANCE_ARRAY_KEY_TIME = 'time';
const DEV_PANEL_REPORT_CACHE_ARRAY_KEY_TYPE  = 'type';
const DEV_PANEL_REPORT_CACHE_ARRAY_KEY_MS    = 'ms';
const DEV_PANEL_REPORT_CACHE_ARRAY_KEY_LEVEL = 'level';
const DEV_PANEL_REPORT_CACHE_ARRAY_KEY_FILE  = 'file';

// Dev Panel Constants END

// Color Picker Config START

const COLOR_PICKER_DATA_CONFIG = 'data-config';
const COLOR_PICKER_DEFAULT = 'default';
const COLOR_PICKER_DATA_TARGET = 'dataTarget';
const COLOR_PICKER_THEME = 'theme';
const COLOR_PICKER_PREVIEW = 'preview';
const COLOR_PICKER_OPACITY = 'opacity';
const COLOR_PICKER_INTERACTION_HEX = 'hex';
const COLOR_PICKER_INTERACTION_RGBA = 'rgba';
const COLOR_PICKER_INTERACTION_INPUT = 'input';
const COLOR_PICKER_INTERACTION_CLEAR = 'clear';
const COLOR_PICKER_INTERACTION_SAVE = 'save';
const COLOR_PICKER_SWATCHES = 'swatches';
const COLOR_PICKER_DISABLED = 'disabled';
const FE_COLOR_PICKER_CONFIG = 'colorPickerConfig';

// Color Picker Config END

// Form Multi Upload parameter
const MULTI_UPLOAD_DETAIL = 'detail';
const MULTI_UPLOAD_TARGET_TABLE = 'targetTable';
const MULTI_UPLOAD_TARGET_TABLE_DEFAULT = 'FileUpload';
const MULTI_UPLOAD_NEW_UPLOAD_FLAG = 'newUpload';
const MULTI_UPLOAD_DELETE_FLAG = 'delete';
const MULTI_UPLOAD_FILE_FULL_PATH = 'full_path';
const MULTI_UPLOAD_UPLOADS_KEY = 'uploads';
const MULTI_UPLOAD_API_ACTION_UPLOAD = 'uploadMulti';
const MULTI_UPLOAD_API_ACTION_DELETE = 'deleteMulti';
const MULTI_UPLOAD_API_MODE_DOWNLOAD = 'downloadMulti';
const MULTI_UPLOAD_DOWNLOAD_FILE_INDEX = 'fileIndex';
const MULTI_UPLOAD_DOWNLOAD_FILE_PATH = 'filePath';
const MULTI_UPLOAD_DOWNLOAD_FILE_NAME = 'outputFileName';

const CURL_HTTP = 'http';
const CURL_METHOD = 'method';
const CURL_METHOD_POST = 'POST';
const CURL_HEADER = 'header';
const CURL_HEADER_DEFAULT = 'Content-type: application/x-www-form-urlencoded';
const CURL_CONTENT = 'content';
const CURL_IGNORE_ERRORS = 'ignore_errors';


//IMAP: 'J:<action>:[<arg>]:[<srcFolder>]:[<srcId>]:[<account>]' AS _link`

// FormElement Datepicker parameter

const FE_DATEPICKER_HH = 'HH';
const FE_DATEPICKER_SS_LOWER = 'ss';
const FE_DATEPICKER_DATE_STANDARD_UPPER = 'DD.MM.YYYY';
const PART_DATE = 'date';
const PART_TIME = 'time';
const FE_DATEPICKER_TODAY = '-today';
const FE_DATEPICKER_LAST = '-last';
const FE_DATEPICKER_FIRST = '-first';
const FE_ATTRIBUTES_PLACEHOLDER = 'placeholder';
const JSON_VALUE = 'value';


const INDEX_IMAP_TOKEN = 0;
const INDEX_IMAP_ACTION = 1;
const INDEX_IMAP_ARG = 2;
const INDEX_IMAP_SRC_FOLDER = 3;
const INDEX_IMAP_SRC_ID = 4;
const INDEX_IMAP_ACCOUNT = 5;

// Report action 'mailList': show at most this many (newest) mails.
const IMAP_MAIL_LIST_LIMIT = 250;

const IMAP_ACTION_FOLDER_LIST = 'folderList';
const IMAP_ACTION_FOLDER_NEW = 'folderNew';
const IMAP_ACTION_FOLDER_DELETE = 'folderDelete';
const IMAP_ACTION_MAIL_LIST = 'mailList';
const IMAP_ACTION_MAIL_NEW = 'mailNew';
const IMAP_ACTION_MAIL_MOVE = 'mailMove';
const IMAP_ACTION_SEEN = 'seen';
const IMAP_ACTION_UNSEEN = 'unseen';
const IMAP_ACTION_TAG = 'tag';
const IMAP_ACTION_CHECK_ACCOUNT = 'checkAccount';

// SyncByRule/Deploy Feature
const SYNC_BY_RULE_EXPORT = TOKEN_EXPORT;
const SYNC_BY_RULE_IMPORT = TOKEN_IMPORT;
const API_SYNC_BY_RULE_DATA = 'syncByRuleData';
const SYNC_BY_RULE_VALUE = 'value';
const SYNC_BY_RULE_JS_JSON_DATA = 'jsonData';
const SYNC_BY_RULE_TEMPLATE = 'template';
const SYNC_BY_RULE_ITEMS = 'items';
const SYNC_BY_RULE_CHILDREN = 'children';
const SYNC_BY_RULE_ITEM_RESULT_ACTION = 'action';
const SYNC_BY_RULE_ITEM_RESULT_OLD_ID = 'oldId';
const SYNC_BY_RULE_ITEM_RESULT_NEW_ID = 'newId';
const SYNC_BY_RULE_CHILD_ELEMENTS = 'childElements';
const SYNC_BY_RULE_UPDATE_ONCE = 'once';
const SYNC_BY_RULE_UPDATE_ALWAYS = 'always';
const SYNC_BY_RULE_UPDATE_SKIP_MODIFIED = 'skipModified';
const SYNC_BY_RULE_JSON_VERSION = 'version';
const SYNC_BY_RULE_JSON_EXPORTED_AT = 'exportedAt';
const SYNC_BY_RULE_JSON_ELEMENT = 'element';
const SYNC_BY_RULE_JSON_TABLE = 'table';
const SYNC_BY_RULE_JSON_DATA = 'data';
const SYNC_BY_RULE_JSON_CONDITION = 'condition';
const SYNC_BY_RULE_JSON_RELATION = 'relation';
const SYNC_BY_RULE_JSON_IDENTIFIER = 'identifier';
const SYNC_BY_RULE_JSON_UPDATE = 'update';
const SYNC_BY_RULE_JSON_MAKE_UNIQUE = 'makeUnique';
const SYNC_BY_RULE_JSON_KEEP_ID = 'keepId';
const SYNC_BY_RULE_JSON_RULE_ID = 'ruleId';
const SYNC_BY_RULE_JSON_RESULT_SUCCESS = 'success';
const SYNC_BY_RULE_JSON_RESULT_IMPORTED = 'imported';
const SYNC_BY_RULE_JSON_RESULT_ID_MAPPING = 'idMapping';
const SYNC_BY_RULE_DB_COLUMN_ID = 'id';
const SYNC_BY_RULE_DB_COLUMN_DEFINITION = 'definition';
const SYNC_BY_RULE_DB_COLUMN_MODIFIED = 'modified';
const SYNC_BY_RULE_DB_COLUMN_CREATED = 'created';
const SYNC_BY_RULE_DB_COLUMN_TARGET_ID = 'targetId';
const SYNC_BY_RULE_DB_COLUMN_POTENTIALLY_DELETED = 'potentiallyDeleted';
const SYNC_BY_RULE_DB_COLUMN_SRC_ID = 'srcId';
const SYNC_BY_RULE_CMD_ACTION = 'action';
const SYNC_BY_RULE_CMD_EXPORT = 'export';
const SYNC_BY_RULE_CMD_IMPORT = 'import';
const SYNC_BY_RULE_CMD_RULES = 'rules';
const SYNC_BY_RULE_CMD_OVERRIDES = 'overrides';
const SYNC_BY_RULE_SIPS = 'ruleSips';
// SyncByRule JSON Keys - Validation
const SYNC_BY_RULE_JSON_DATA_TYPE = 'dataType';
const SYNC_BY_RULE_JSON_CHECKSUM = 'checksum';
const SYNC_BY_RULE_JSON_BASE_URL_SRC = 'baseUrlSrc';

// SyncByRule API Response Keys
const API_SYNC_BY_RULE_ERROR_TYPE = 'syncByRuleErrorType';
const API_SYNC_BY_RULE_ERROR_MESSAGE = 'syncByRuleErrorMessage';

// SyncByRule Error Types
const SYNC_BY_RULE_ERROR_DATA_TYPE_MISMATCH = 'dataTypeMismatch';
const SYNC_BY_RULE_ERROR_TABLE_NOT_FOUND = 'tableNotFound';
const SYNC_BY_RULE_ERROR_CHECKSUM_INVALID = 'checksumInvalid';
const SYNC_BY_RULE_ERROR_CHECKSUM_VERIFICATION_FAILED = 'checksumVerificationFailed';

// SyncByRule attributes
const SYNC_BY_RULE_CLASS_QFQ_SYNCBYRULE = 'qfq-syncByRule';
const SYNC_BY_RULE_CLASS_QFQ_SYNCBYRULE_CHECKBOX_ALL = 'qfq-syncByRule-checkbox-all';
const SYNC_BY_RULE_CLASS_QFQ_SYNCBYRULE_TRIGGER = 'qfq-syncByRule-trigger';
const SYNC_BY_RULE_TEXT_COPY = 'Copy';
const SYNC_BY_RULE_TEXT_PASTE = 'Paste';
const SYNC_BY_RULE_CHECKBOX_TITLE = 'Select/Deselect All';

// Checksum API Rate Limiting
const SYNC_BY_RULE_CHECKSUM_RATE_LIMIT_ATTEMPTS = 10;
const SYNC_BY_RULE_CHECKSUM_RATE_LIMIT_WINDOW = 60; // seconds
const SYNC_BY_RULE_CHECKSUM_RATE_LIMIT_LOCKOUT = 300; // 5 minutes lockout

// Version API Check Keys
const API_VERSION_CHECK_EXT_MODULE = 'check-extModule';
const API_VERSION_CHECK_EXT_SETTING = 'check-extSetting';
const API_VERSION_CHECK_BE_USER = 'check-beUser';
const API_VERSION_CHECK_FE_USER = 'check-feUser';

// Version API Deploy Key
const API_VERSION_DEPLOY = 'deploy';

// Version API Response Keys
const API_VERSION_KEY_URL = 'url';
const API_VERSION_KEY_HOSTNAME = 'hostname';
const API_VERSION_KEY_PROJECT = 'project';
const API_VERSION_KEY_TYPO3 = 'typo3';
const API_VERSION_KEY_DEB_PACKAGES = 'deb-packages';

// Extension Keys
const EXT_KEY_OIDC_CLIENT = 'oidc_client';

// TYPO3 Extension Table Names
const TABLE_T3_OIDC_CLIENT_CONFIG = 'tx_oidcclient_config';
const TABLE_T3_LDAP_SSO_AUTH_CONFIG = 'tx_igldapssoauth_config';

// OIDC Module Response Keys
const OIDC_KEY_INSTALLED = 'installed';
const OIDC_KEY_TABLE_EXISTS = 'tableExists';
const OIDC_KEY_PROVIDERS = 'providers';
const OIDC_KEY_PROCESSED = 'processed';
const OIDC_KEY_ERROR = 'error';
const OIDC_KEY_RESULTS = 'results';

// InputCollectionJson Metadata Keys
const ICJ_KEY_VALUE = 'value';
const ICJ_KEY_LABEL = '__label';
const ICJ_KEY_DESC = '__desc';
const ICJ_KEY_TYPE = '__type';
const ICJ_KEY_READONLY = '__readonly';
const ICJ_KEY_CAT = '__cat';
const ICJ_KEY_OPTIONS = '__options';

// OIDC Category Names
const OIDC_CAT_GENERAL = 'general';
const OIDC_CAT_AUTHENTICATION = 'authentication';
const OIDC_CAT_CLIENT = 'client';
const OIDC_CAT_PROVIDER = 'provider';
const OIDC_CAT_MAPPING = 'mapping';
const OIDC_CAT_NOTES = 'notes';
const OIDC_CAT_PROCESSORS_LDAP = 'processors_ldap';
const OIDC_CAT_PROCESSORS_QFQ = 'processors_qfq';

// OIDC FlexForms Sheet Names
const OIDC_SHEET_LDAP_SYNC = 's_ldap-sync';
const OIDC_SHEET_LDAP_PROCESSOR = 's_ldap-processor';
const OIDC_SHEET_QFQ_PROCESSOR = 's_qfq-processor';

// Version API Result Keys
const API_RESULT_KEY_ACTION = 'action';
const API_RESULT_KEY_CHANGES = 'changes';
const API_RESULT_KEY_UID = 'uid';
const API_RESULT_KEY_NAME = 'name';

// Version API Change Detail Keys
const API_CHANGE_KEY_FIELD = 'field';
const API_CHANGE_KEY_OLD = 'old';
const API_CHANGE_KEY_NEW = 'new';

// Extension Settings Format Keys
const EXT_SETTINGS_TEMPLATE = 'template';
const EXT_SETTINGS_VALUES = 'values';

// TYPO3 be_users table columns
const T3_BE_USERS_UID = 'uid';
const T3_BE_USERS_USERNAME = 'username';
const T3_BE_USERS_REAL_NAME = 'realName';
const T3_BE_USERS_EMAIL = 'email';
const T3_BE_USERS_ADMIN = 'admin';
const T3_BE_USERS_DISABLE = 'disable';
const T3_BE_USERS_DELETED = 'deleted';

// Backend User API Keys
const BE_USER_KEY_USERNAME = 'username';
const BE_USER_KEY_REAL_NAME = 'realName';
const BE_USER_KEY_EMAIL = 'email';
const BE_USER_KEY_IS_ADMIN = 'isAdmin';
const BE_USER_KEY_IS_MAINTAINER = 'isMaintainer';
const BE_USER_KEY_IS_DISABLED = 'isDisabled';
const BE_USER_KEY_DELETE = 'delete';
const BE_USER_KEY_CREATED = 'created';

// Metadata Source Keys (for reading from metadata arrays)
const META_KEY_LABEL = 'label';
const META_KEY_DESC = 'desc';
const META_KEY_TYPE = 'type';
const META_KEY_OPTIONS = 'options';
const META_KEY_READONLY = 'readonly';
const META_KEY_CAT = 'cat';

const STORE_USER_LAST_LOGIN = '__feUserLastLogin';