#!/bin/bash

# KingbaseES 健康巡检脚本
# 用法: ./kes_check.sh <port> <user> <data_dir>
# 需要环境变量: KINGBASE_HOME (默认: /home/kingbase/install/kingbase)
# 生成报告目录: grep -E "^----->>>|^\|" /tmp/kes_packet.txt | sed 's/^----->>>---->>>/    /'

# Check required arguments
if [ $# -lt 2 ]; then
    echo "Usage: $0 port user [data_dir]"
    echo "Example: $0 54321 system /home/kingbase/userdata/data"
    echo "Requires: KINGBASE_HOME env var (default: /home/kingbase/install/kingbase)"
    exit 1
fi

# KINGBASE_HOME fallback
if [ -z "$KINGBASE_HOME" ]; then
    export KINGBASE_HOME=/home/kingbase/install/kingbase
fi

if [ ! -x "$KINGBASE_HOME/bin/ksql" ]; then
    echo "Error: ksql not found at $KINGBASE_HOME/bin/ksql"
    exit 1
fi

export PORT=$1
export KUSER=$2
export KDATA=${3:-""}

DATE1=$(date +"%Y%m%d%H%M")

# Resilient query runner: failure is silently tolerated (prints nothing, returns empty)
ksql_q() {
    local sql="$1"
    # run with timeout; eat errors; never abort the script
    "$KINGBASE_HOME/bin/ksql" -p "$PORT" -U "$KUSER" -d test \
        --pset=pager=off -q 2>/dev/null -c "$sql" || true
}

# -------- Header --------
echo "    ----- KingbaseES 巡检报告 -----  "
echo "    ===== $DATE1        =====  "
echo ""

# -------- Section: OS info --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                      操作系统信息                       |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  数据库用户信息: "
id "${KUSER}" 2>/dev/null || id
echo ""

echo "----->>>---->>>  数据库数据目录属主信息: "
if [ -n "$KDATA" ]; then
    ls -ld "$KDATA" 2>/dev/null || echo "(data_dir not accessible)"
else
    echo "(data_dir not provided)"
fi
echo ""

echo "----->>>---->>>  主机名: "
hostname -s 2>/dev/null || hostname 2>/dev/null || cat /proc/sys/kernel/hostname 2>/dev/null || echo "(hostname not available)"
echo ""

echo "----->>>---->>>  IP地址信息: "
ip addr show 2>/dev/null || ifconfig 2>/dev/null || echo "(ip info not available)"
echo ""

echo "----->>>---->>>  操作系统内核: "
uname -a
echo ""

echo "----->>>---->>>  内存: "
free -h 2>/dev/null || echo "(free not available)"
echo ""

echo "----->>>---->>>  CPU: "
lscpu 2>/dev/null || cat /proc/cpuinfo 2>/dev/null | grep "model name" | head -4 || echo "(cpu info not available)"
echo ""

echo "----->>>---->>>  块设备: "
lsblk 2>/dev/null || echo "(lsblk not available)"
echo ""

echo "----->>>---->>>  磁盘空间: "
df -T -h 2>/dev/null || df -h
echo ""

echo "----->>>---->>>  KES进程信息: "
ps aux 2>/dev/null | grep -E "[k]ingbase|[k]sql|[p]ostgres" | head -20 || echo "(no kes processes found)"
echo ""

echo "----->>>---->>>  KES配置文件: "
if [ -n "$KDATA" ] && [ -f "$KDATA/kingbase.conf" ]; then
    grep '^[a-z]' "$KDATA/kingbase.conf" 2>/dev/null | awk -F "#" '{print $1}' | head -50
elif [ -n "$KDATA" ] && [ -f "$KDATA/postgresql.conf" ]; then
    grep '^[a-z]' "$KDATA/postgresql.conf" 2>/dev/null | awk -F "#" '{print $1}' | head -50
else
    echo "(conf file not accessible)"
fi
echo ""

echo "----->>>---->>>  sys_hba.conf / pg_hba.conf: "
if [ -n "$KDATA" ]; then
    HBA_FILE="$KDATA/sys_hba.conf"
    [ -f "$HBA_FILE" ] || HBA_FILE="$KDATA/pg_hba.conf"
    if [ -f "$HBA_FILE" ]; then
        grep '^[a-z]' "$HBA_FILE" 2>/dev/null
    else
        echo "(hba conf not found)"
    fi
fi
echo -e "\n"

# -------- Section: DB info --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                       数据库信息                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  实例与版本信息: "
ksql_q "SELECT 'version' AS item, version() AS value
UNION ALL
SELECT 'db_size', pg_size_pretty(pg_database_size(current_database()))
UNION ALL
SELECT 'start_time', sys_postmaster_start_time()::text;"
echo ""

echo "----->>>---->>>  实例启动时间与运行时长: "
ksql_q "SELECT sys_postmaster_start_time() AS start_time,
       now() - sys_postmaster_start_time() AS uptime,
       EXTRACT(EPOCH FROM (now() - sys_postmaster_start_time()))::bigint AS uptime_seconds;"
echo ""

echo "----->>>---->>>  数据库列表与大小: "
ksql_q "SELECT datname,
       pg_size_pretty(pg_database_size(oid)) AS size,
       pg_database_size(oid) AS bytes
FROM sys_database
ORDER BY pg_database_size(oid) DESC;"
echo ""

echo "----->>>---->>>  是否为备库: "
ksql_q "SELECT sys_is_in_recovery() AS is_standby;"
echo ""

echo "----->>>---->>>  已安装的扩展: "
ksql_q "SELECT current_database() AS db, extname, extversion
FROM sys_extension
ORDER BY extname;"
echo ""

# -------- Section: Key parameters --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                       关键参数配置                      |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  关键参数(sys_settings): "
ksql_q "SELECT name, setting, unit, source
FROM sys_settings
WHERE name IN (
    'max_connections','shared_buffers','work_mem','maintenance_work_mem',
    'effective_cache_size','wal_level','max_wal_size','min_wal_size',
    'checkpoint_timeout','checkpoint_completion_target','wal_buffers',
    'autovacuum','autovacuum_max_workers','autovacuum_freeze_max_age',
    'autovacuum_vacuum_cost_delay','log_min_duration_statement',
    'archive_mode','ssl','huge_pages','random_page_cost',
    'default_statistics_target','statement_timeout',
    'idle_in_transaction_session_timeout','track_activities',
    'track_counts','track_io_timing','log_connections'
)
ORDER BY name;"
echo ""

echo "----->>>---->>>  修改过的参数(非默认值): "
ksql_q "SELECT name, setting, boot_val, source
FROM sys_settings
WHERE setting <> boot_val AND sourcefile IS NOT NULL
ORDER BY name;"
echo ""

# -------- Section: Connections --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                     数据库连接分析                      |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  当前连接汇总(sys_stat_activity): "
ksql_q "SELECT count(*) AS total,
       count(*) FILTER (WHERE state='active') AS active,
       count(*) FILTER (WHERE state='idle') AS idle,
       count(*) FILTER (WHERE state='idle in transaction') AS idle_in_txn,
       count(*) FILTER (WHERE wait_event_type IS NOT NULL) AS waiting
FROM sys_stat_activity;"
echo ""

echo "----->>>---->>>  连接数与上限: "
ksql_q "SELECT (SELECT count(*) FROM sys_stat_activity) AS used,
       (SELECT setting::int FROM sys_settings WHERE name='max_connections') AS max_conn,
       (SELECT setting::int FROM sys_settings WHERE name='superuser_reserved_connections') AS reserved_super,
       (SELECT setting::int FROM sys_settings WHERE name='max_connections')
         - (SELECT count(*) FROM sys_stat_activity)
         - (SELECT setting::int FROM sys_settings WHERE name='superuser_reserved_connections')
         AS free_for_normal;"
echo ""

echo "----->>>---->>>  按用户的连接分布: "
ksql_q "SELECT usename, state, count(*) AS cnt
FROM sys_stat_activity
GROUP BY usename, state
ORDER BY cnt DESC
LIMIT 20;"
echo ""

echo "----->>>---->>>  按数据库的连接分布: "
ksql_q "SELECT datname, count(*) AS cnt
FROM sys_stat_activity
GROUP BY datname
ORDER BY cnt DESC;"
echo ""

# -------- Section: Cache --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                       缓存命中率                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  缓冲区命中率(sys_stat_database): "
ksql_q "SELECT datname, blks_read, blks_hit,
       CASE WHEN blks_read+blks_hit > 0
            THEN round(blks_hit * 100.0 / (blks_read+blks_hit), 2)
            ELSE 100 END AS hit_ratio_pct
FROM sys_stat_database
WHERE datname NOT IN ('template0','template1')
ORDER BY hit_ratio_pct ASC;"
echo ""

# -------- Section: Locks --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                     锁与阻塞分析                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  当前阻塞链(sys_locks自连接): "
ksql_q "SELECT w.pid AS blocked_pid,
       wa.usename AS blocked_user,
       left(wa.query, 100) AS blocked_query,
       b.pid AS blocking_pid,
       ba.usename AS blocking_user,
       left(ba.query, 100) AS blocking_query,
       EXTRACT(EPOCH FROM (now() - wa.state_change))::int AS wait_seconds
FROM sys_locks w
JOIN sys_stat_activity wa ON w.pid = wa.pid
JOIN sys_locks b
  ON b.locktype = w.locktype
  AND b.database IS NOT DISTINCT FROM w.database
  AND b.relation IS NOT DISTINCT FROM w.relation
  AND b.page IS NOT DISTINCT FROM w.page
  AND b.tuple IS NOT DISTINCT FROM w.tuple
  AND b.transactionid IS NOT DISTINCT FROM w.transactionid
  AND b.pid != w.pid
JOIN sys_stat_activity ba ON b.pid = ba.pid
WHERE NOT w.granted
ORDER BY wait_seconds DESC NULLS LAST
LIMIT 20;"
echo ""

echo "----->>>---->>>  锁类型统计: "
ksql_q "SELECT locktype, mode, granted, count(*) AS cnt
FROM sys_locks
GROUP BY locktype, mode, granted
ORDER BY cnt DESC;"
echo ""

# -------- Section: Long transactions --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                       长事务分析                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  长事务(>60秒, sys_stat_activity): "
ksql_q "SELECT pid, usename, datname, state,
       left(query, 150) AS query,
       EXTRACT(EPOCH FROM (now() - xact_start))::int AS xact_seconds,
       wait_event_type, wait_event
FROM sys_stat_activity
WHERE state <> 'idle'
  AND xact_start IS NOT NULL
  AND EXTRACT(EPOCH FROM (now() - xact_start)) > 60
ORDER BY xact_seconds DESC;"
echo ""

echo "----->>>---->>>  idle in transaction(>30秒): "
ksql_q "SELECT pid, usename, datname,
       EXTRACT(EPOCH FROM (now() - xact_start))::int AS idle_txn_seconds,
       left(query, 100) AS last_query
FROM sys_stat_activity
WHERE state = 'idle in transaction'
  AND xact_start IS NOT NULL
  AND EXTRACT(EPOCH FROM (now() - xact_start)) > 30
ORDER BY idle_txn_seconds DESC;"
echo ""

# -------- Section: Wait events --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                       等待事件分析                      |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  当前等待事件分布(sys_stat_activity): "
ksql_q "SELECT coalesce(wait_event_type, 'CPU/Running') AS wait_event_type,
       coalesce(wait_event, '-') AS wait_event,
       count(*) AS sessions
FROM sys_stat_activity
WHERE pid <> sys_backend_pid()
GROUP BY wait_event_type, wait_event
ORDER BY sessions DESC;"
echo ""

echo "----->>>---->>>  当前活动SQL(非idle): "
ksql_q "SELECT pid, usename, datname, state,
       left(query, 120) AS query,
       wait_event_type, wait_event,
       EXTRACT(EPOCH FROM (now() - query_start))::int AS query_seconds
FROM sys_stat_activity
WHERE state <> 'idle'
  AND pid <> sys_backend_pid()
ORDER BY query_seconds DESC NULLS LAST
LIMIT 20;"
echo ""

# -------- Section: WAL / checkpoint --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                   WAL与检查点分析                       |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  bgwriter统计(sys_stat_bgwriter): "
ksql_q "SELECT checkpoints_timed, checkpoints_req,
       checkpoint_write_time, checkpoint_sync_time,
       buffers_checkpoint, buffers_clean, buffers_backend,
       buffers_backend_fsync, buffers_alloc, stats_reset
FROM sys_stat_bgwriter;"
echo ""

echo "----->>>---->>>  WAL配置参数: "
ksql_q "SELECT name, setting, unit
FROM sys_settings
WHERE name IN ('wal_level','max_wal_size','min_wal_size',
               'wal_buffers','checkpoint_timeout',
               'checkpoint_completion_target','wal_keep_size',
               'archive_mode','archive_command','wal_compression')
ORDER BY name;"
echo ""

echo "----->>>---->>>  当前WAL位置: "
# Try KES-native function first, fallback to PG-compatible name
ksql_q "SELECT CASE
    WHEN (SELECT count(*) FROM sys_proc WHERE proname='sys_current_wal_lsn') > 0
    THEN sys_current_wal_lsn()::text
    ELSE pg_current_wal_lsn()::text
END AS current_wal_lsn;" 2>/dev/null || \
ksql_q "SELECT pg_current_wal_lsn()::text AS current_wal_lsn;" 2>/dev/null || true
echo ""

echo "----->>>---->>>  归档统计(sys_stat_archiver): "
ksql_q "SELECT archived_count, last_archived_wal, last_archived_time,
       failed_count, last_failed_wal, last_failed_time, stats_reset
FROM sys_stat_archiver;"
echo ""

echo "----->>>---->>>  流复制状态(sys_stat_replication): "
ksql_q "SELECT pid, usename, application_name, client_addr, state,
       sent_lsn, write_lsn, flush_lsn, replay_lsn,
       sync_state, sync_priority
FROM sys_stat_replication;"
echo ""

echo "----->>>---->>>  复制槽(sys_replication_slots): "
ksql_q "SELECT slot_name, plugin, slot_type, active, restart_lsn, confirmed_flush_lsn
FROM sys_replication_slots;"
echo ""

# -------- Section: VACUUM / bloat --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                  VACUUM与表膨胀分析                     |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  死元组TOP20(sys_stat_user_tables): "
ksql_q "SELECT schemaname || '.' || relname AS table_name,
       n_live_tup, n_dead_tup,
       CASE WHEN n_live_tup > 0
            THEN round(n_dead_tup * 100.0 / n_live_tup, 2)
            ELSE 0 END AS dead_ratio_pct,
       last_autovacuum, last_autoanalyze, autovacuum_count
FROM sys_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC
LIMIT 20;"
echo ""

echo "----->>>---->>>  VACUUM配置参数: "
ksql_q "SELECT name, setting, unit
FROM sys_settings
WHERE name IN ('autovacuum','autovacuum_max_workers',
               'autovacuum_naptime','autovacuum_vacuum_threshold',
               'autovacuum_analyze_threshold',
               'autovacuum_vacuum_scale_factor',
               'autovacuum_analyze_scale_factor',
               'autovacuum_vacuum_cost_delay',
               'autovacuum_vacuum_cost_limit',
               'autovacuum_freeze_max_age',
               'maintenance_work_mem','vacuum_cost_delay')
ORDER BY name;"
echo ""

echo "----->>>---->>>  当前运行中的VACUUM进度: "
ksql_q "SELECT pid, datname, relid::regclass AS table_name, phase,
       heap_blks_total, heap_blks_scanned, heap_blks_vacuumed,
       CASE WHEN heap_blks_total > 0
            THEN round(heap_blks_scanned * 100.0 / heap_blks_total, 2)
            ELSE 0 END AS scan_pct,
       index_vacuum_count
FROM sys_stat_progress_vacuum;"
echo ""

# -------- Section: XID freeze --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                   事务ID冻结风险分析                    |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  数据库XID年龄(sys_database): "
ksql_q "SELECT datname,
       age(datfrozenxid) AS xid_age,
       2147483647 - age(datfrozenxid) AS remaining_xids
FROM sys_database
WHERE datallowconn
ORDER BY age(datfrozenxid) DESC;"
echo ""

echo "----->>>---->>>  高危表XID年龄(年龄>5亿, sys_class): "
ksql_q "SELECT n.nspname || '.' || c.relname AS table_name,
       age(c.relfrozenxid) AS xid_age,
       2147483647 - age(c.relfrozenxid) AS remaining_xids
FROM sys_class c
JOIN sys_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','t','m')
  AND c.relpersistence = 'p'
  AND age(c.relfrozenxid) > 500000000
ORDER BY age(c.relfrozenxid) DESC
LIMIT 20;"
echo ""

# -------- Section: I/O stats --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                    I/O与事务统计                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  数据库I/O与事务统计(sys_stat_database): "
ksql_q "SELECT datname,
       xact_commit, xact_rollback,
       CASE WHEN xact_commit + xact_rollback > 0
            THEN round(xact_rollback * 100.0 / (xact_commit + xact_rollback), 2)
            ELSE 0 END AS rollback_ratio_pct,
       blks_read, blks_hit,
       deadlocks, conflicts,
       temp_files, temp_bytes,
       blk_read_time, blk_write_time
FROM sys_stat_database
WHERE datname NOT IN ('template0','template1')
ORDER BY xact_commit + xact_rollback DESC;"
echo ""

# -------- Section: Top objects --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                    最大对象TOP10                        |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  最大表(sys_class按大小TOP10): "
ksql_q "SELECT n.nspname || '.' || c.relname AS table_name,
       c.relkind,
       pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,
       pg_size_pretty(pg_relation_size(c.oid)) AS table_size,
       pg_size_pretty(pg_indexes_size(c.oid)) AS indexes_size,
       pg_total_relation_size(c.oid) AS total_bytes
FROM sys_class c
JOIN sys_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
  AND n.nspname NOT IN ('pg_catalog','sys_catalog','information_schema','pg_toast')
ORDER BY pg_total_relation_size(c.oid) DESC
LIMIT 10;"
echo ""

echo "----->>>---->>>  用户对象数量统计: "
ksql_q "SELECT n.nspname AS schema, c.relkind, count(*) AS obj_count
FROM sys_class c
JOIN sys_namespace n ON n.oid = c.relnamespace
WHERE n.nspname NOT IN ('pg_catalog','sys_catalog','information_schema','pg_toast')
  AND n.nspname NOT LIKE 'pg_temp%'
GROUP BY n.nspname, c.relkind
ORDER BY obj_count DESC
LIMIT 30;"
echo ""

# -------- Section: Capacity --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                      容量分析                           |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  各库大小: "
ksql_q "SELECT datname,
       pg_size_pretty(pg_database_size(oid)) AS size,
       pg_database_size(oid) AS bytes
FROM sys_database
ORDER BY pg_database_size(oid) DESC;"
echo ""

echo "----->>>---->>>  表空间大小(sys_tablespace): "
ksql_q "SELECT spcname,
       pg_tablespace_location(oid) AS location,
       pg_size_pretty(pg_tablespace_size(oid)) AS size
FROM sys_tablespace
ORDER BY pg_tablespace_size(oid) DESC;"
echo ""

echo "----->>>---->>>  数据目录磁盘使用: "
if [ -n "$KDATA" ]; then
    df -h "$KDATA" 2>/dev/null || echo "(data dir df not available)"
else
    df -h 2>/dev/null | head -10
fi
echo ""

# -------- Section: Security --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                     安全与账号分析                      |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  用户角色与超级用户(sys_roles): "
ksql_q "SELECT rolname, rolsuper, rolcreatedb, rolcreaterole,
       rolcanlogin, rolconnlimit, rolvaliduntil,
       rolreplication, rolbypassrls
FROM sys_roles
ORDER BY rolsuper DESC, rolname
LIMIT 50;"
echo ""

echo "----->>>---->>>  SSL配置: "
ksql_q "SELECT name, setting, source
FROM sys_settings
WHERE name IN ('ssl','ssl_cert_file','ssl_key_file',
               'ssl_ca_file','ssl_prefer_server_ciphers',
               'password_encryption')
ORDER BY name;"
echo ""

echo "----->>>---->>>  超级用户列表: "
ksql_q "SELECT rolname
FROM sys_roles
WHERE rolsuper = true
ORDER BY rolname;"
echo ""

# -------- Section: Backup / archive --------
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo "|                     备份与归档分析                      |"
echo "|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|"
echo ""

echo "----->>>---->>>  归档与备份配置: "
ksql_q "SELECT name, setting
FROM sys_settings
WHERE name IN ('archive_mode','archive_command',
               'archive_cleanup_command','wal_level',
               'max_wal_senders','wal_keep_size',
               'hot_standby','recovery_target_timeline')
ORDER BY name;"
echo ""

echo "----->>>---->>>  归档统计详情: "
ksql_q "SELECT archived_count, last_archived_wal, last_archived_time,
       failed_count, last_failed_wal, last_failed_time
FROM sys_stat_archiver;"
echo ""

echo "    ===== KingbaseES 巡检完成 =====  "
echo "    ===== $DATE1        =====  "
