<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://new.pvzhe.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E6%84%A4%E6%80%92%E7%9A%84%E9%83%8E%E6%9C%97</id>
	<title>植物大战僵尸杂交版Wiki - 用户贡献 [zh-cn]</title>
	<link rel="self" type="application/atom+xml" href="https://new.pvzhe.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%E6%84%A4%E6%80%92%E7%9A%84%E9%83%8E%E6%9C%97"/>
	<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/w/%E7%89%B9%E6%AE%8A:%E7%94%A8%E6%88%B7%E8%B4%A1%E7%8C%AE/%E6%84%A4%E6%80%92%E7%9A%84%E9%83%8E%E6%9C%97"/>
	<updated>2026-06-13T08:33:36Z</updated>
	<subtitle>用户贡献</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4730</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4730"/>
		<updated>2026-06-13T06:06:44Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度面板 - 宠物上方，有间隔 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translateX(-50%);&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 提示文字 - 好感度面板上方，紧贴无间隔 */&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translateX(-50%);&lt;br /&gt;
    margin-bottom: 28px;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4729</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4729"/>
		<updated>2026-06-13T06:03:27Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var pets = {&lt;br /&gt;
            &#039;冰瓜香蒲&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 100&lt;br /&gt;
            },&lt;br /&gt;
            &#039;小猫向日葵&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/9/9b/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/8/85/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 100&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var petNames = Object.keys(pets);&lt;br /&gt;
        var currentPet = localStorage.getItem(&#039;wiki_pet_current&#039;) || &#039;冰瓜香蒲&#039;;&lt;br /&gt;
        if (!pets[currentPet]) currentPet = &#039;冰瓜香蒲&#039;;&lt;br /&gt;
&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection_&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey + currentPet, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function switchPet(newPet) {&lt;br /&gt;
            if (newPet === currentPet) return;&lt;br /&gt;
            currentPet = newPet;&lt;br /&gt;
            localStorage.setItem(&#039;wiki_pet_current&#039;, currentPet);&lt;br /&gt;
            affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
            $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            setPetState(&#039;idle&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, {&lt;br /&gt;
            src: pets[currentPet].idle,&lt;br /&gt;
            alt: currentPet,&lt;br /&gt;
            draggable: &#039;false&#039;,&lt;br /&gt;
            css: { width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        var $switchBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, { class: &#039;pet-switch-btn&#039;, text: &#039;🔄&#039;, title: &#039;切换宠物&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip, $switchBtn);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        $switchBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var idx = petNames.indexOf(currentPet);&lt;br /&gt;
            var nextIdx = (idx + 1) % petNames.length;&lt;br /&gt;
            switchPet(petNames[nextIdx]);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
                $img.css({ width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].petting);&lt;br /&gt;
                var petSize = currentPet === &#039;小猫向日葵&#039; ? pets[currentPet].size * 1.2 : Math.round(pets[currentPet].size * 1.2);&lt;br /&gt;
                $img.css({ width: petSize + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            $pet.addClass(&#039;touching&#039;);&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchend&#039;, function() {&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4728</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4728"/>
		<updated>2026-06-13T06:02:09Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 提示文字 - 宠物下方 */&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translateX(-50%);&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度面板 - 宠物上方 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 100%;&lt;br /&gt;
    left: 0%;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    margin-bottom: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4727</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4727"/>
		<updated>2026-06-13T06:01:36Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 提示文字 - 宠物下方 */&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translateX(-50%);&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度面板 - 宠物右上方 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    margin-bottom: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4726</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4726"/>
		<updated>2026-06-13T05:59:35Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 提示文字 - 宠物下方 */&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 100%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translateX(-50%);&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度面板 - 宠物右上方 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 100%;&lt;br /&gt;
    left: 100%;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    margin-bottom: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4725</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4725"/>
		<updated>2026-06-13T05:57:19Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 200px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4724</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4724"/>
		<updated>2026-06-13T05:55:46Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 150px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4723</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4723"/>
		<updated>2026-06-13T05:53:22Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var pets = {&lt;br /&gt;
            &#039;冰瓜香蒲&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 150&lt;br /&gt;
            },&lt;br /&gt;
            &#039;小猫向日葵&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/9/9b/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/8/85/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 200&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var petNames = Object.keys(pets);&lt;br /&gt;
        var currentPet = localStorage.getItem(&#039;wiki_pet_current&#039;) || &#039;冰瓜香蒲&#039;;&lt;br /&gt;
        if (!pets[currentPet]) currentPet = &#039;冰瓜香蒲&#039;;&lt;br /&gt;
&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection_&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey + currentPet, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function switchPet(newPet) {&lt;br /&gt;
            if (newPet === currentPet) return;&lt;br /&gt;
            currentPet = newPet;&lt;br /&gt;
            localStorage.setItem(&#039;wiki_pet_current&#039;, currentPet);&lt;br /&gt;
            affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
            $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            setPetState(&#039;idle&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, {&lt;br /&gt;
            src: pets[currentPet].idle,&lt;br /&gt;
            alt: currentPet,&lt;br /&gt;
            draggable: &#039;false&#039;,&lt;br /&gt;
            css: { width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        var $switchBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, { class: &#039;pet-switch-btn&#039;, text: &#039;🔄&#039;, title: &#039;切换宠物&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip, $switchBtn);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        $switchBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var idx = petNames.indexOf(currentPet);&lt;br /&gt;
            var nextIdx = (idx + 1) % petNames.length;&lt;br /&gt;
            switchPet(petNames[nextIdx]);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
                $img.css({ width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].petting);&lt;br /&gt;
                var petSize = currentPet === &#039;小猫向日葵&#039; ? pets[currentPet].size * 1.2 : Math.round(pets[currentPet].size * 1.2);&lt;br /&gt;
                $img.css({ width: petSize + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            $pet.addClass(&#039;touching&#039;);&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchend&#039;, function() {&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4722</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4722"/>
		<updated>2026-06-13T05:51:37Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var pets = {&lt;br /&gt;
            &#039;冰瓜香蒲&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 150&lt;br /&gt;
            },&lt;br /&gt;
            &#039;小猫向日葵&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/9/9b/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/8/85/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 200&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var petNames = Object.keys(pets);&lt;br /&gt;
        var currentPet = localStorage.getItem(&#039;wiki_pet_current&#039;) || &#039;冰瓜香蒲&#039;;&lt;br /&gt;
        if (!pets[currentPet]) currentPet = &#039;冰瓜香蒲&#039;;&lt;br /&gt;
&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection_&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey + currentPet, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function switchPet(newPet) {&lt;br /&gt;
            if (newPet === currentPet) return;&lt;br /&gt;
            currentPet = newPet;&lt;br /&gt;
            localStorage.setItem(&#039;wiki_pet_current&#039;, currentPet);&lt;br /&gt;
            affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
            $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            setPetState(&#039;idle&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, {&lt;br /&gt;
            src: pets[currentPet].idle,&lt;br /&gt;
            alt: currentPet,&lt;br /&gt;
            draggable: &#039;false&#039;,&lt;br /&gt;
            css: { width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        var $switchBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, { class: &#039;pet-switch-btn&#039;, text: &#039;🔄&#039;, title: &#039;切换宠物&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip, $switchBtn);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        $switchBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var idx = petNames.indexOf(currentPet);&lt;br /&gt;
            var nextIdx = (idx + 1) % petNames.length;&lt;br /&gt;
            switchPet(petNames[nextIdx]);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
                $img.css({ width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].petting);&lt;br /&gt;
                var petSize = currentPet === &#039;小猫向日葵&#039; ? pets[currentPet].size * 2 : Math.round(pets[currentPet].size * 1.5);&lt;br /&gt;
                $img.css({ width: petSize + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            $pet.addClass(&#039;touching&#039;);&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchend&#039;, function() {&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4721</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4721"/>
		<updated>2026-06-13T05:49:45Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var pets = {&lt;br /&gt;
            &#039;冰瓜香蒲&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 150&lt;br /&gt;
            },&lt;br /&gt;
            &#039;小猫向日葵&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/9/9b/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/8/85/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&#039;,&lt;br /&gt;
                size: 200&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var petNames = Object.keys(pets);&lt;br /&gt;
        var currentPet = localStorage.getItem(&#039;wiki_pet_current&#039;) || &#039;冰瓜香蒲&#039;;&lt;br /&gt;
        if (!pets[currentPet]) currentPet = &#039;冰瓜香蒲&#039;;&lt;br /&gt;
&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection_&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey + currentPet, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function switchPet(newPet) {&lt;br /&gt;
            if (newPet === currentPet) return;&lt;br /&gt;
            currentPet = newPet;&lt;br /&gt;
            localStorage.setItem(&#039;wiki_pet_current&#039;, currentPet);&lt;br /&gt;
            affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
            $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
            $img.css({ width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; });&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            setPetState(&#039;idle&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, {&lt;br /&gt;
            src: pets[currentPet].idle,&lt;br /&gt;
            alt: currentPet,&lt;br /&gt;
            draggable: &#039;false&#039;,&lt;br /&gt;
            css: { width: pets[currentPet].size + &#039;px&#039;, height: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        var $switchBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, { class: &#039;pet-switch-btn&#039;, text: &#039;🔄&#039;, title: &#039;切换宠物&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip, $switchBtn);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        $switchBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var idx = petNames.indexOf(currentPet);&lt;br /&gt;
            var nextIdx = (idx + 1) % petNames.length;&lt;br /&gt;
            switchPet(petNames[nextIdx]);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].petting);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            $pet.addClass(&#039;touching&#039;);&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchend&#039;, function() {&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - pets[currentPet].size));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - pets[currentPet].size));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + pets[currentPet].size / 3, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4720</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4720"/>
		<updated>2026-06-13T05:47:15Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var pets = {&lt;br /&gt;
            &#039;冰瓜香蒲&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;&lt;br /&gt;
            },&lt;br /&gt;
            &#039;小猫向日葵&#039;: {&lt;br /&gt;
                idle: &#039;https://new.pvzhe.wiki/images/9/9b/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&#039;,&lt;br /&gt;
                petting: &#039;https://new.pvzhe.wiki/images/8/85/%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&#039;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        var petNames = Object.keys(pets);&lt;br /&gt;
        var currentPet = localStorage.getItem(&#039;wiki_pet_current&#039;) || &#039;冰瓜香蒲&#039;;&lt;br /&gt;
        if (!pets[currentPet]) currentPet = &#039;冰瓜香蒲&#039;;&lt;br /&gt;
&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection_&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey + currentPet, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function switchPet(newPet) {&lt;br /&gt;
            if (newPet === currentPet) return;&lt;br /&gt;
            currentPet = newPet;&lt;br /&gt;
            localStorage.setItem(&#039;wiki_pet_current&#039;, currentPet);&lt;br /&gt;
            affection = parseInt(localStorage.getItem(affectionKey + currentPet)) || 0;&lt;br /&gt;
            $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            setPetState(&#039;idle&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: pets[currentPet].idle, alt: currentPet, draggable: &#039;false&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        var $switchBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, { class: &#039;pet-switch-btn&#039;, text: &#039;🔄&#039;, title: &#039;切换宠物&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip, $switchBtn);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        $switchBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            var idx = petNames.indexOf(currentPet);&lt;br /&gt;
            var nextIdx = (idx + 1) % petNames.length;&lt;br /&gt;
            switchPet(petNames[nextIdx]);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].idle);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pets[currentPet].petting);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($switchBtn)) return;&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 移动端触摸时显示切换按钮&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            $pet.addClass(&#039;touching&#039;);&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchend&#039;, function() {&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            $pet.removeClass(&#039;touching&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4719</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4719"/>
		<updated>2026-06-13T05:46:44Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 130px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;br /&gt;
/* 宠物切换按钮 */&lt;br /&gt;
.pet-switch-btn {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: -5px;&lt;br /&gt;
    right: -5px;&lt;br /&gt;
    width: 24px;&lt;br /&gt;
    height: 24px;&lt;br /&gt;
    background: rgba(0,0,0,0.6);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: 1px solid rgba(255,255,255,0.3);&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    display: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 22px;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.pet-switch-btn:hover {&lt;br /&gt;
    transform: scale(1.2);&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-switch-btn,&lt;br /&gt;
.wiki-pet.touching .pet-switch-btn {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&amp;diff=4718</id>
		<title>文件:小猫向日葵待机.gif</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E5%BE%85%E6%9C%BA.gif&amp;diff=4718"/>
		<updated>2026-06-13T05:42:33Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&amp;diff=4717</id>
		<title>文件:小猫向日葵抚摸.gif</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%B0%8F%E7%8C%AB%E5%90%91%E6%97%A5%E8%91%B5%E6%8A%9A%E6%91%B8.gif&amp;diff=4717"/>
		<updated>2026-06-13T05:42:33Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E5%BD%A9%E5%8D%A1&amp;diff=4716</id>
		<title>彩卡</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E5%BD%A9%E5%8D%A1&amp;diff=4716"/>
		<updated>2026-06-13T05:23:19Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​创建页面，内容为“{{返回关卡列表}} &amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=招财猫试玩&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=吸金磁射手试玩&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=坚果存钱罐试玩&amp;lt;/div&amp;gt; &amp;lt;div sty…”&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{返回关卡列表}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:招财猫横.png|200px|link=招财猫试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:吸金磁射手横.png|200px|link=吸金磁射手试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:坚果存钱罐横.png|200px|link=坚果存钱罐试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:钻石种子横.png|200px|link=钻石种子试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:水晶蜗牛横.png|200px|link=水晶蜗牛试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%90%B8%E9%87%91%E7%A3%81%E5%B0%84%E6%89%8B%E6%A8%AA.png&amp;diff=4715</id>
		<title>文件:吸金磁射手横.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%90%B8%E9%87%91%E7%A3%81%E5%B0%84%E6%89%8B%E6%A8%AA.png&amp;diff=4715"/>
		<updated>2026-06-13T05:23:10Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%98%9F%E5%8D%A1&amp;diff=4714</id>
		<title>星卡</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%98%9F%E5%8D%A1&amp;diff=4714"/>
		<updated>2026-06-13T05:21:07Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​创建页面，内容为“{{返回关卡列表}} &amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=罐子豌豆射手试玩&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=罐子窝瓜试玩&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;link=泡椒罐子试玩&amp;lt;/div&amp;gt; &amp;lt;d…”&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{返回关卡列表}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:罐子豌豆射手横.png|200px|link=罐子豌豆射手试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:罐子窝瓜横.png|200px|link=罐子窝瓜试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:泡椒罐子横.png|200px|link=泡椒罐子试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:日月罐子横.png|200px|link=日月罐子试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:伪装的向日葵横.png|200px|link=伪装的向日葵试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:伪装的樱桃炸弹横.png|200px|link=伪装的樱桃炸弹试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:伪装的三叶草横.png|200px|link=伪装的三叶草试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:伪装的机枪射手横.png|200px|link=伪装的机枪射手试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:净化辣椒横.png|200px|link=净化辣椒试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:坚果保龄球横.png|200px|link=坚果保龄球试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:礼盒机横.png|200px|link=礼盒机试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:荷叶伞横.png|200px|link=荷叶伞试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:宝石炸弹横.png|200px|link=宝石炸弹试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:荧光豆横.png|200px|link=荧光豆试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:流星横.png|200px|link=流星试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:怪怪水草横.png|200px|link=怪怪水草试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:迷你软糖横.png|200px|link=迷你软糖试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:传送门高坚果横.png|200px|link=传送门高坚果试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:全息投影花盆横.png|200px|link=全息投影花盆试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:巨型南瓜雪橇横.png|200px|link=巨型南瓜雪橇试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:苹果闹钟横.png|200px|link=苹果闹钟试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:逆时闹钟横.png|200px|link=逆时闹钟试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:黄金锤子横.png|200px|link=黄金锤子试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:壁垒高坚果横.png|200px|link=装甲高坚果试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:窝瓜跳跳糖横.png|200px|link=窝瓜跳跳糖试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:植物组合机甲横.png|200px|link=植物组合机甲试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:保龄球彩蛋横.png|200px|link=保龄球彩蛋试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4713</id>
		<title>紫卡</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4713"/>
		<updated>2026-06-13T05:15:32Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{返回关卡列表}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰炬高坚果横.png|200px|link=冰炬高坚果试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:寒光土豆雷横.png|200px|link=寒光土豆雷试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰锥射手横.png|200px|link=冰锥射手试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:双子阳光向日葵横.png|200px|link=双子阳光向日葵试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:机枪香蒲横.png|200px|link=机枪香蒲试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:三叶仙人掌横.png|200px|link=三叶仙人掌试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰焰南瓜壳横.png|200px|link=冰焰南瓜壳试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:机枪花盆横.png|200px|link=机枪花盆试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:魅惑菇丛横.png|200px|link=魅惑菇丛试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:双重玉米卷香蒲横.png|200px|link=双重玉米卷香蒲试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:原始刚刺果横.png|200px|link=原始钢刺果试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰冰凉凉大喷菇横.png|200px|link=冰冰凉凉大喷菇试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4711</id>
		<title>紫卡</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4711"/>
		<updated>2026-06-13T05:11:03Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{返回关卡列表}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex; flex-wrap:wrap; justify-content:center; gap:5px; width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰炬高坚果横.png|200px|link=冰炬高坚果试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:寒光土豆雷横.png|200px|link=寒光土豆雷试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:冰锥射手横.png|200px|link=冰锥射手试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:双子阳光向日葵横.png|200px|link=双子阳光向日葵试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:0 0 200px; max-width:200px;&amp;quot;&amp;gt;[[文件:机枪香蒲横.png|200px|link=机枪香蒲试玩]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4706</id>
		<title>紫卡</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E7%B4%AB%E5%8D%A1&amp;diff=4706"/>
		<updated>2026-06-13T05:02:46Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​创建页面，内容为“{{返回关卡列表}}”&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{返回关卡列表}}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E5%83%B5%E5%B0%B8&amp;diff=4701</id>
		<title>僵尸</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E5%83%B5%E5%B0%B8&amp;diff=4701"/>
		<updated>2026-06-13T04:43:52Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;欢迎来到《植物大战僵尸杂交版》的僵尸大全页面。这里列出了游戏中的各种僵尸，你可以通过以下链接查看他们的详细信息。&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{#widget:ZombieFilter}}&lt;br /&gt;
&lt;br /&gt;
= 常规僵尸 =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;pvzhe-card-container&amp;quot;&amp;gt;&lt;br /&gt;
{{Card|image=[[文件:普通僵尸.png|75px|普通僵尸|link=普通僵尸]]|name=普通僵尸|health=270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:路障僵尸.png|75px|路障僵尸|link=路障僵尸]]|name=路障僵尸|health=路障+270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:铁桶僵尸.png|75px|铁桶僵尸|link=铁桶僵尸]]|name=铁桶僵尸|health=铁桶+270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:铁栅门僵尸.png|75px|铁栅门僵尸|link=铁栅门僵尸]]|name=铁栅门僵尸|health=铁栅门+270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:废稿头盔僵尸.png|75px|废稿头盔僵尸|link=废稿头盔僵尸]]|name=废稿头盔僵尸|health=废稿头盔+270|speed=慢|type=普通|version=0.17}}&lt;br /&gt;
{{Card|image=[[文件:抽奖盒子僵尸.png|75px|抽奖盒子僵尸|link=抽奖盒子僵尸]]|name=抽奖盒子僵尸|health=270|speed=慢|type=普通|version=0.4}}&lt;br /&gt;
{{Card|image=[[文件:豌豆僵尸.png|75px|豌豆僵尸|link=豌豆僵尸]]|name=豌豆僵尸|health=270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:双发射手僵尸.png|75px|双发射手僵尸|link=双发射手僵尸]]|name=双发射手僵尸|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:寒冰射手僵尸.png|75px|寒冰射手僵尸|link=寒冰射手僵尸]]|name=寒冰射手僵尸|health=270|speed=慢|type=普通|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:向日葵僵尸.png|75px|向日葵僵尸|link=向日葵僵尸]]|name=向日葵僵尸|health=270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:坚果僵尸.png|75px|坚果僵尸|link=坚果僵尸]]|name=坚果僵尸|health=1370|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:火炬坚果僵尸.png|75px|火炬坚果僵尸|link=火炬坚果僵尸]]|name=火炬坚果僵尸|health=1370|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:冰冻坚果僵尸.png|75px|冰冻坚果僵尸|link=冰冻坚果僵尸]]|name=冰冻坚果僵尸|health=1370|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:高坚果僵尸.png|75px|高坚果僵尸|link=高坚果僵尸]]|name=高坚果僵尸|health=2470|speed=慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:高冰果僵尸.png|75px|高冰果僵尸|link=高冰果僵尸]]|name=高冰果僵尸|health=3570|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:毁灭菇僵尸.png|75px|毁灭菇僵尸|link=毁灭菇僵尸]]|name=毁灭菇僵尸|health=500|speed=慢|type=普通|version=0.16}}&lt;br /&gt;
{{Card|image=[[文件:窝瓜僵尸.png|75px|窝瓜僵尸|link=窝瓜僵尸]]|name=窝瓜僵尸|health=270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:火爆辣椒僵尸.png|75px|火爆辣椒僵尸|link=火爆辣椒僵尸]]|name=火爆辣椒僵尸|health=500|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:机枪僵尸.png|75px|机枪僵尸|link=机枪僵尸]]|name=机枪僵尸|health=270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:狂野机枪僵尸.png|75px|狂野机枪僵尸|link=狂野机枪僵尸]]|name=狂野机枪僵尸|health=500|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:套盒坚果僵尸.png|75px|套盒坚果僵尸|link=套盒坚果僵尸]]|name=套盒坚果僵尸|health=270|speed=慢|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:杨桃僵尸.png|75px|杨桃僵尸|link=杨桃僵尸]]|name=杨桃僵尸|health=270|speed=慢|type=普通}}&lt;br /&gt;
{{Card|image=[[文件:三线射手僵尸.png|75px|三线射手僵尸|link=三线射手僵尸]]|name=三线射手僵尸|health=270|speed=慢|type=普通}}&lt;br /&gt;
{{Card|image=[[文件:卷心菜投手僵尸.png|75px|卷心菜投手僵尸|link=卷心菜投手僵尸]]|name=卷心菜投手僵尸|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:玉米投手僵尸.png|75px|玉米投手僵尸|link=玉米投手僵尸]]|name=玉米投手僵尸|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:西瓜投手僵尸.png|75px|西瓜投手僵尸|link=西瓜投手僵尸]]|name=西瓜投手僵尸|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:冰瓜投手僵尸.png|75px|冰瓜投手僵尸|link=冰瓜投手僵尸]]|name=冰瓜投手僵尸|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:大嘴花僵尸.png|75px|大嘴花僵尸|link=大嘴花僵尸]]|name=大嘴花僵尸|health=500|speed=快|type=普通|version=0.19}}&lt;br /&gt;
{{Card|image=[[文件:玉米加农炮僵尸.png|75px|玉米加农炮僵尸|link=玉米加农炮僵尸]]|name=玉米加农炮僵尸|health=1000|speed=慢|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:模仿者僵尸.png|75px|模仿者僵尸|link=模仿者僵尸]]|name=模仿者僵尸|health=500|speed=慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:摇旗僵尸.png|75px|摇旗僵尸|link=摇旗僵尸]]|name=摇旗僵尸|health=路障+270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:小摔哥僵尸.png|75px|小摔哥僵尸|link=小摔哥僵尸]]|name=小摔哥僵尸|health=睡帽+270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:床车僵尸.png|75px|床车僵尸|link=床车僵尸]]|name=床车僵尸|health=1400|speed=快|type=车辆|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:读报僵尸.png|75px|读报僵尸|link=读报僵尸]]|name=读报僵尸|health=报纸+270|speed=慢,快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:撑杆僵尸.png|75px|撑杆僵尸|link=撑杆僵尸]]|name=撑杆僵尸|health=500|speed=快,慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:气球僵尸.png|75px|气球僵尸|link=气球僵尸]]|name=气球僵尸|health=气球+270|speed=慢|type=飞行,普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:多彩气球僵尸.png|75px|多彩气球僵尸|link=多彩气球僵尸]]|name=多彩气球僵尸|health=气球+270|speed=非常慢|type=飞行,普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:橄榄球僵尸.png|75px|橄榄球僵尸|link=橄榄球僵尸]]|name=橄榄球僵尸|health=橄榄头盔+270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:大喷菇橄榄球僵尸.png|75px|大喷菇橄榄球僵尸|link=大喷菇橄榄球僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;大喷菇橄榄球僵尸&amp;lt;/span&amp;gt;|health=橄榄头盔+270|speed=快|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:忧郁菇橄榄球僵尸.png|75px|忧郁菇橄榄球僵尸|link=忧郁菇橄榄球僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;忧郁菇橄榄球僵尸&amp;lt;/span&amp;gt;|health=橄榄头盔+270|speed=快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:暗黑橄榄球僵尸.png|75px|暗黑橄榄球僵尸|link=暗黑橄榄球僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;暗黑橄榄球僵尸&amp;lt;/span&amp;gt;|health=黑橄榄头盔+270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:大喷菇暗黑橄榄球僵尸.png|75px|大喷菇暗黑橄榄球僵尸|link=大喷菇暗黑橄榄球僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;大喷菇暗黑橄榄球僵尸&amp;lt;/span&amp;gt;|health=黑橄榄头盔+270|speed=快|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:忧郁菇暗黑橄榄球僵尸.png|75px|忧郁菇暗黑橄榄球僵尸|link=忧郁菇暗黑橄榄球僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;忧郁菇暗黑橄榄球僵尸&amp;lt;/span&amp;gt;|health=黑橄榄头盔+270|speed=快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:小鬼僵尸.png|75px|小鬼僵尸|link=小鬼僵尸]]|name=小鬼僵尸|health=270|speed=慢|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:小喷菇小鬼僵尸.png|75px|小喷菇小鬼僵尸|link=小喷菇小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;小喷菇小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.14}}&lt;br /&gt;
{{Card|image=[[文件:海蘑菇小鬼僵尸.png|75px|海蘑菇小鬼僵尸|link=海蘑菇小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;海蘑菇小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:阳光菇小鬼僵尸.png|75px|阳光菇小鬼僵尸|link=阳光菇小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;阳光菇小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:阳光菇投手小鬼僵尸.png|75px|阳光菇投手小鬼僵尸|link=阳光菇投手小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:11px;&amp;quot;&amp;gt;阳光菇投手小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:魅惑菇小鬼僵尸.png|75px|魅惑菇小鬼僵尸|link=魅惑菇小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:11px;&amp;quot;&amp;gt;魅惑菇小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=非常快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:礼盒小鬼僵尸.png|75px|礼盒小鬼僵尸|link=礼盒小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;礼盒小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:僵尸豌豆小鬼僵尸.png|75px|僵尸豌豆小鬼僵尸|link=僵尸豌豆小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;僵尸豌豆小鬼僵尸&amp;lt;/span&amp;gt;|health=500|speed=慢|type=普通|version=0.19}}&lt;br /&gt;
{{Card|image=[[文件:豌豆小鬼僵尸.png|75px|豌豆小鬼僵尸|link=豌豆小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;豌豆小鬼僵尸&amp;lt;/span&amp;gt;|health=270|speed=慢|type=普通|version=0.19}}&lt;br /&gt;
{{Card|image=[[文件:伽刚特尔.png|75px|伽刚特尔|link=伽刚特尔]]|name=伽刚特尔|health=3000|speed=非常慢|type=大型|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:礼盒伽刚特尔.png|75px|礼盒伽刚特尔|link=礼盒伽刚特尔]]|name=礼盒伽刚特尔|health=3000|speed=非常慢|type=大型|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:僵尸坚果伽刚特尔.png|75px|僵尸坚果伽刚特尔|link=僵尸坚果伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;僵尸坚果伽刚特尔&amp;lt;/span&amp;gt;|health=4000|speed=非常慢|type=大型|version=0.19}}&lt;br /&gt;
{{Card|image=[[文件:忧郁菇投手伽刚特尔.png|75px|忧郁菇投手伽刚特尔|link=忧郁菇投手伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:11px;&amp;quot;&amp;gt;忧郁菇投手伽刚特尔&amp;lt;/span&amp;gt;|health=4000|speed=非常慢|type=大型|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:暴走伽刚特尔.png|75px|暴走伽刚特尔|link=暴走伽刚特尔]]|name=暴走伽刚特尔|health=6000|speed=非常慢|type=大型|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:武装红眼伽刚特尔.png|75px|武装红眼伽刚特尔|link=武装红眼伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;武装红眼伽刚特尔&amp;lt;/span&amp;gt;|health=铁桶,黑橄榄头盔,废稿头盔,铁栅门,防爆门+6000|speed=非常慢|type=大型|version=0.17}}&lt;br /&gt;
{{Card|image=[[文件:武装伽刚特尔.png|75px|武装伽刚特尔|link=武装伽刚特尔]]|name=武装伽刚特尔|health=铁桶,黑橄榄头盔,废稿头盔,铁栅门,防爆门+3000|speed=非常慢|type=大型|version=0.4}}&lt;br /&gt;
{{Card|image=[[文件:冲锋橄榄撑杆僵尸.png|75px|冲锋橄榄撑杆僵尸|link=冲锋橄榄撑杆僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;冲锋橄榄撑杆僵尸&amp;lt;/span&amp;gt;|health=橄榄头盔+270|speed=快|type=普通|version=0.1}}&lt;br /&gt;
{{Card|image=[[文件:影子僵尸.png|75px|影子僵尸|link=影子僵尸]]|name=影子僵尸|health=500|speed=慢|type=普通|version=0.2}}&lt;br /&gt;
{{Card|image=[[文件:舞王僵尸.png|75px|舞王僵尸|link=舞王僵尸]]|name=舞王僵尸|health=500|speed=快,慢|type=普通|version=0.2}}&lt;br /&gt;
{{Card|image=[[文件:伴舞僵尸.png|75px|伴舞僵尸|link=伴舞僵尸]]|name=伴舞僵尸|health=270|speed=慢|type=普通|version=0.2}}&lt;br /&gt;
{{Card|image=[[文件:雪橇车僵尸.png|75px|雪橇车僵尸|link=雪橇车僵尸]]|name=雪橇车僵尸|health=1350|speed=慢|type=车辆|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:机枪冰车僵尸.png|75px|机枪冰车僵尸|link=机枪冰车僵尸]]|name=机枪冰车僵尸|health=1350|speed=慢|type=车辆|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:寒冰菇冰车僵尸.png|75px|寒冰菇冰车僵尸|link=寒冰菇冰车僵尸]]|name=寒冰菇冰车僵尸|health=1350|speed=慢|type=车辆|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:矿工僵尸.png|75px|矿工僵尸|link=矿工僵尸]]|name=矿工僵尸|health=矿工头盔+270|speed=快,慢|type=普通,矿工|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:机枪矿工僵尸.png|75px|机枪矿工僵尸|link=机枪矿工僵尸]]|name=机枪矿工僵尸|health=370|speed=快,慢|type=普通,矿工|version=0.18}}&lt;br /&gt;
{{Card|image=[[文件:土豆雷矿工僵尸.png|75px|土豆雷矿工僵尸|link=土豆雷矿工僵尸]]|name=土豆雷矿工僵尸|health=370|speed=快,慢|type=普通,矿工|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:矿工雪人僵尸.png|75px|矿工雪人僵尸|link=矿工雪人僵尸]]|name=矿工雪人僵尸|health=矿工头盔+800|speed=快,慢|type=普通,矿工|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:扶梯僵尸.png|75px|扶梯僵尸|link=扶梯僵尸]]|name=扶梯僵尸|health=扶梯+500|speed=快,慢|type=普通|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:玩偶匣僵尸.png|75px|玩偶匣僵尸|link=玩偶匣僵尸]]|name=玩偶匣僵尸|health=玩偶匣+500|speed=慢|type=普通|version=0.3}}&lt;br /&gt;
{{Card|image=[[文件:小黄鸭僵尸.png|75px|小黄鸭僵尸|link=小黄鸭僵尸]]|name=小黄鸭僵尸|health=270|speed=慢|type=普通|version=0.5}}&lt;br /&gt;
{{Card|image=[[文件:潜水僵尸.png|75px|潜水僵尸|link=潜水僵尸]]|name=潜水僵尸|health=270|speed=快|type=普通,水上僵尸|version=0.5}}&lt;br /&gt;
{{Card|image=[[文件:缠绕潜水僵尸.png|75px|缠绕潜水僵尸|link=缠绕潜水僵尸]]|name=缠绕潜水僵尸|health=270|speed=快|type=普通,水上僵尸|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:毁灭海草潜水僵尸.png|75px|毁灭海草潜水僵尸|link=毁灭海草潜水僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;毁灭海草潜水僵尸&amp;lt;/span&amp;gt;|health=270|speed=快|type=普通,水上僵尸|version=0.15}}&lt;br /&gt;
{{Card|image=[[文件:海豚骑士僵尸.png|75px|海豚骑士僵尸|link=海豚骑士僵尸]]|name=海豚骑士僵尸|health=500|speed=快,慢|type=普通,水上僵尸|version=0.5}}&lt;br /&gt;
{{Card|image=[[文件:机枪海豚僵尸.png|75px|机枪海豚僵尸|link=机枪海豚僵尸]]|name=机枪海豚僵尸|health=500|speed=快,慢|type=普通,水上僵尸|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:潜水海豚僵尸.png|75px|潜水海豚僵尸|link=潜水海豚僵尸]]|name=潜水海豚僵尸|health=500|speed=快,慢|type=普通,水上僵尸|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:骑鸭僵尸.png|75px|骑鸭僵尸|link=骑鸭僵尸]]|name=骑鸭僵尸|health=大黄鸭,铁桶,路障+800|speed=快|type=普通|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:防爆门僵尸.png|75px|防爆门僵尸|link=防爆门僵尸]]|name=防爆门僵尸|health=防爆头盔,防爆门+500|speed=慢|type=普通|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:猫战士僵尸.png|75px|猫战士僵尸|link=猫战士僵尸]]|name=猫战士僵尸|health=猫战士头盔+500|speed=快|type=普通|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:海妖僵尸.png|75px|海妖僵尸|link=海妖僵尸]]|name=海妖僵尸|health=4000|speed=慢|type=大型,水上僵尸|version=0.6}}&lt;br /&gt;
{{Card|image=[[文件:读报迪斯科僵尸.png|75px|读报迪斯科僵尸|link=读报迪斯科僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;读报迪斯科僵尸&amp;lt;/span&amp;gt;|health=报纸+500|speed=慢,快|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:愤怒舞者僵尸.png|75px|愤怒舞者僵尸|link=愤怒舞者僵尸]]|name=愤怒舞者僵尸|health=270|speed=快|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:跳跳僵尸.png|75px|跳跳僵尸|link=跳跳僵尸]]|name=跳跳僵尸|health=跳跳杆+500|speed=快,慢|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:磁场僵尸.png|75px|磁场僵尸|link=磁场僵尸]]|name=磁场僵尸|health=磁场头盔+270|speed=慢|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:鲨鱼僵尸.png|75px|鲨鱼僵尸|link=鲨鱼僵尸]]|name=鲨鱼僵尸|health=1400|speed=慢|type=普通,水上僵尸|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:天使僵尸.png|75px|天使僵尸|link=天使僵尸]]|name=天使僵尸|health=800|speed=慢|type=飞行,普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:舞王海豚僵尸.png|75px|舞王海豚僵尸|link=舞王海豚僵尸]]|name=舞王海豚僵尸|health=1200|speed=快,慢|type=普通,水上僵尸|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:伴舞海豚僵尸.png|75px|伴舞海豚僵尸|link=伴舞海豚僵尸]]|name=伴舞海豚僵尸|health=500|speed=快,慢|type=普通,水上僵尸|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:蹦极僵尸.png|75px|蹦极僵尸|link=蹦极僵尸]]|name=蹦极僵尸|health=450|speed=慢|type=普通|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:催眠师僵尸.png|75px|催眠师僵尸|link=催眠师僵尸]]|name=催眠师僵尸|health=1000|speed=慢|type=普通|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:投石车僵尸.png|75px|投石车僵尸|link=投石车僵尸]]|name=投石车僵尸|health=850|speed=快|type=车辆|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:气球炸弹.png|75px|气球炸弹|link=气球炸弹]]|name=气球炸弹|health=40|speed=快|type=飞行,普通|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:气球车僵尸.png|75px|气球车僵尸|link=气球车僵尸]]|name=气球车僵尸|health=1350|speed=快|type=车辆|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:跳跳伴舞僵尸.png|75px|跳跳伴舞僵尸|link=跳跳伴舞僵尸]]|name=跳跳伴舞僵尸|health=跳跳杆+270|speed=慢,快|type=普通|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:跳跳舞王僵尸.png|75px|跳跳舞王僵尸|link=跳跳舞王僵尸]]|name=跳跳舞王僵尸|health=跳跳杆+500|speed=慢,快|type=普通|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:小鬼投石车僵尸.png|75px|小鬼投石车僵尸|link=小鬼投石车僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;小鬼投石车僵尸&amp;lt;/span&amp;gt;|health=850|speed=快|type=车辆|version=0.11}}&lt;br /&gt;
{{Card|image=[[文件:跳棋僵尸.png|75px|跳棋僵尸|link=跳棋僵尸]]|name=跳棋僵尸|health=棋子头饰,跳跳杆+500|speed=快,慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:橄榄雪人僵尸.png|75px|橄榄雪人僵尸|link=橄榄雪人僵尸]]|name=橄榄雪人僵尸|health=橄榄头盔+800|speed=快|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:吸血鬼僵尸.png|75px|吸血鬼僵尸|link=吸血鬼僵尸]]|name=吸血鬼僵尸|health=1000|speed=慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:蜗牛壳.png|75px|蜗牛壳|link=蜗牛壳]]|name=蜗牛壳|health=1800|speed=慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:蜗牛小鬼僵尸.png|75px|蜗牛小鬼僵尸|link=蜗牛小鬼僵尸]]|name=蜗牛小鬼僵尸|health=蜗牛壳+270|speed=慢|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:投冰车僵尸.png|75px|投冰车僵尸|link=投冰车僵尸]]|name=投冰车僵尸|health=1350|speed=慢|type=车辆|version=0.13}}&lt;br /&gt;
{{Card|image=[[文件:伴舞伽刚特尔.png|75px|伴舞伽刚特尔|link=伴舞伽刚特尔]]|name=伴舞伽刚特尔|health=3000|speed=非常慢|type=大型|version=0.13}}&lt;br /&gt;
{{Card|image=[[文件:暴走舞王伽刚特尔.png|75px|暴走舞王伽刚特尔|link=暴走舞王伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;暴走舞王伽刚特尔&amp;lt;/span&amp;gt;|health=6000|speed=非常慢|type=大型|version=0.13}}&lt;br /&gt;
{{Card|image=[[文件:农民僵尸.png|75px|农夫僵尸|link=农夫僵尸]]|name=农夫僵尸|health=头巾+500|speed=慢|type=普通|version=0.14}}&lt;br /&gt;
{{Card|image=[[文件:财主僵尸.png|75px|财主僵尸|link=财主僵尸]]|name=财主僵尸|health=金帽子+1000|speed=慢|type=普通|version=0.14}}&lt;br /&gt;
{{Card|image=[[文件:海盗船员僵尸.png|75px|海盗船员僵尸|link=海盗船员僵尸]]|name=海盗船员僵尸|health=500|speed=慢|type=普通|version=0.14}}&lt;br /&gt;
{{Card|image=[[文件:海盗船长僵尸.png|75px|海盗船长僵尸|link=海盗船长僵尸]]|name=海盗船长僵尸|health=1000|speed=慢|type=普通|version=0.14}}&lt;br /&gt;
{{Card|image=[[文件:钻石僵尸.png|75px|钻石僵尸|link=钻石僵尸]]|name=钻石僵尸|health=钻石头盔+270|speed=快|type=普通|version=0.16}}&lt;br /&gt;
{{Card|image=[[文件:市场僵尸.png|75px|市场僵尸|link=市场僵尸]]|name=市场僵尸|health=高顶礼帽+850|speed=快|type=普通|version=0.18}}&lt;br /&gt;
{{Card|image=[[文件:矿工小鬼僵尸.png|75px|矿工小鬼僵尸|link=矿工小鬼僵尸]]|name=矿工小鬼僵尸|health=小矿工头盔+270|speed=快|type=普通,矿工|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:矿工伽刚特尔.png|75px|矿工伽刚特尔|link=矿工伽刚特尔]]|name=矿工伽刚特尔|health=矿工头盔+3000|speed=慢|type=大型,矿工|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:骷髅僵尸.png|75px|骷髅僵尸|link=骷髅僵尸]]|name=骷髅僵尸|health=500|speed=慢|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:死灵法师僵尸.png|75px|死灵法师僵尸|link=死灵法师僵尸]]|name=死灵法师僵尸|health=3000|speed=慢|type=大型|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:僵尸幽灵.png|75px|僵尸幽灵|link=僵尸幽灵]]|name=僵尸幽灵|health=500|speed=快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:矿工地刺小鬼僵尸.png|75px|矿工地刺小鬼僵尸|link=矿工地刺小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;矿工地刺小鬼僵尸&amp;lt;/span&amp;gt;|health=500|speed=慢|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:重生法师僵尸.png|75px|重生法师僵尸|link=重生法师僵尸]]|name=重生法师僵尸|health=3000|speed=慢|type=大型|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:迷魂僵尸.png|75px|迷魂僵尸|link=迷魂僵尸]]|name=迷魂僵尸|health=睡帽+270|speed=快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:巨化法师僵尸.png|75px|巨化法师僵尸|link=巨化法师僵尸]]|name=巨化法师僵尸|health=3000|speed=慢|type=大型|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:雪橇车巨人僵尸.png|75px|雪橇车巨人僵尸|link=雪橇车巨人僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;雪橇车巨人僵尸&amp;lt;/span&amp;gt;|health=3000|speed=慢|type=大型,车辆|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:雪橇车红眼巨人僵尸.png|75px|雪橇车红眼巨人僵尸|link=雪橇车红眼巨人僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:11px;&amp;quot;&amp;gt;雪橇车红眼巨人僵尸&amp;lt;/span&amp;gt;|health=6000|speed=慢|type=大型,车辆|version=0.17}}&lt;br /&gt;
{{Card|image=[[文件:火焰迪斯科僵尸.png|75px|火焰迪斯科僵尸|link=火焰迪斯科僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;火焰迪斯科僵尸&amp;lt;/span&amp;gt;|health=1100|speed=慢,快|type=普通|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:火焰舞者僵尸.png|75px|火焰舞者僵尸|link=火焰舞者僵尸]]|name=火焰舞者僵尸|health=500|speed=慢|type=普通|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:精英舞王僵尸.png|75px|精英舞王僵尸|link=精英舞王僵尸]]|name=精英舞王僵尸|health=1000|speed=快,慢|type=普通|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:舞者僵尸.png|75px|舞者僵尸|link=舞者僵尸]]|name=舞者僵尸|health=270|speed=慢|type=普通|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:迪斯科僵尸.png|75px|迪斯科僵尸|link=迪斯科僵尸]]|name=迪斯科僵尸|health=500|speed=快,慢|type=普通|version=0.7}}&lt;br /&gt;
{{Card|image=[[文件:冲锋橄榄读报僵尸.png|75px|冲锋橄榄读报僵尸|link=冲锋橄榄读报僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;冲锋橄榄读报僵尸&amp;lt;/span&amp;gt;|health=报纸,橄榄头盔+270|speed=慢,快|type=普通|version=0.9}}&lt;br /&gt;
{{Card|image=[[文件:板斧僵尸.png|75px|板斧僵尸|link=板斧僵尸]]|name=板斧僵尸|health=铁斧+2200|speed=慢|type=普通|version=0.10}}&lt;br /&gt;
{{Card|image=[[文件:黑客小鬼僵尸.png|75px|黑客小鬼僵尸|link=黑客小鬼僵尸]]|name=黑客小鬼僵尸|health=800|speed=快|type=普通|version=0.10.5}}&lt;br /&gt;
{{Card|image=[[文件:冲锋橄榄小鬼僵尸.png|75px|冲锋橄榄小鬼僵尸|link=冲锋橄榄小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;冲锋橄榄小鬼僵尸&amp;lt;/span&amp;gt;|health=橄榄头盔+270|speed=快|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:冲锋黑橄榄小鬼僵尸.png|75px|冲锋黑橄榄小鬼僵尸|link=冲锋黑橄榄小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:11px;&amp;quot;&amp;gt;冲锋黑橄榄小鬼僵尸&amp;lt;/span&amp;gt;|health=小黑橄榄头盔+270|speed=快|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:暴走黑橄榄红眼小鬼僵尸.png|75px|暴走黑橄榄红眼小鬼僵尸|link=暴走黑橄榄红眼小鬼僵尸]]|name=&amp;lt;span style=&amp;quot;font-size:9px;&amp;quot;&amp;gt;暴走黑橄榄红眼小鬼僵尸&amp;lt;/span&amp;gt;|health=小黑橄榄头盔+270|speed=快|type=普通|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:冲锋橄榄伽刚特尔.png|75px|冲锋橄榄伽刚特尔|link=冲锋橄榄伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:12px;&amp;quot;&amp;gt;冲锋橄榄伽刚特尔&amp;lt;/span&amp;gt;|health=橄榄头盔+3000|speed=快|type=大型|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:冲锋黑橄榄伽刚特尔.png|75px|冲锋黑橄榄伽刚特尔|link=冲锋黑橄榄伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:10px;&amp;quot;&amp;gt;冲锋黑橄榄伽刚特尔&amp;lt;/span&amp;gt;|health=黑橄榄头盔+3000|speed=快|type=大型|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:暴走黑橄榄红眼伽刚特尔.png|75px|暴走黑橄榄红眼伽刚特尔|link=暴走黑橄榄红眼伽刚特尔]]|name=&amp;lt;span style=&amp;quot;font-size:9px;&amp;quot;&amp;gt;暴走黑橄榄红眼伽刚特尔&amp;lt;/span&amp;gt;|health=黑橄榄头盔+6000|speed=快|type=大型|version=0.12}}&lt;br /&gt;
{{Card|image=[[文件:跳跳球僵尸.png|75px|跳跳球僵尸|link=跳跳球僵尸]]|name=跳跳球僵尸|health=跳跳球+500|speed=快|type=普通|version=0.16}}&lt;br /&gt;
{{Card|image=[[文件:骷髅伽刚特尔.png|75px|骷髅伽刚特尔|link=骷髅伽刚特尔]]|name=骷髅伽刚特尔|health=3000|speed=慢|type=大型|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:钻石伽刚特尔.png|75px|钻石伽刚特尔|link=钻石伽刚特尔]]|name=钻石伽刚特尔|health=钻石头盔+3000|speed=慢|type=大型|version=0.21}}&lt;br /&gt;
{{Card|image=[[文件:骷髅小鬼僵尸.png|75px|骷髅小鬼僵尸|link=骷髅小鬼僵尸]]|name=骷髅小鬼僵尸|health=500|speed=快|type=普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:钻石小鬼僵尸.png|75px|钻石小鬼僵尸|link=钻石小鬼僵尸]]|name=钻石小鬼僵尸|health=钻石头盔+270|speed=快|type=普通|version=0.21}}&lt;br /&gt;
{{Card|image=[[文件:气球舞王僵尸.png|75px|气球舞王僵尸|link=气球舞王僵尸]]|name=气球舞王僵尸|health=气球+270|speed=慢|type=飞行,普通|version=0.20}}&lt;br /&gt;
{{Card|image=[[文件:白天鹅僵尸.png|75px|白天鹅僵尸|link=白天鹅僵尸]]|name=白天鹅僵尸|health=天鹅,铁桶,路障+270|speed=慢|type=车辆,飞行|version=0.21}}&lt;br /&gt;
{{Card|image=[[文件:火箭炮僵尸.png|75px|火箭炮僵尸|link=火箭炮僵尸]]|name=火箭炮僵尸|health=850|speed=快|type=车辆|version=0.21}}&lt;br /&gt;
{{Card|image=[[文件:飞行器僵尸.png|75px|飞行器僵尸|link=飞行器僵尸]]|name=飞行器僵尸|health=飞行器+270|speed=慢|type=飞行|version=0.22}}&lt;br /&gt;
{{Card|image=[[文件:胆小小鬼僵尸.png|75px|胆小鬼僵尸|link=胆小鬼僵尸]]|name=胆小鬼僵尸|health=500|speed=快|type=普通|version=0.22}}&lt;br /&gt;
{{Card|image=[[文件:传送门僵尸.png|75px|传送门僵尸|link=传送门僵尸]]|name=传送门僵尸|health=头盔,传送门+500|speed=慢|type=普通|version=0.22}}&lt;br /&gt;
{{Card|image=[[文件:罐子僵尸.png|75px|罐子僵尸|link=罐子僵尸]]|name=罐子僵尸|health=棒球帽+270|speed=慢|type=普通|version=0.9}}&lt;br /&gt;
{{Card|image=[[文件:园丁僵尸.png|75px|园丁僵尸|link=园丁僵尸]]|name=园丁僵尸|health=草帽,搬运车+500|speed=快|type=普通|version=0.9}}&lt;br /&gt;
{{Card|image=[[文件:标靶僵尸.png|75px|标靶僵尸|link=标靶僵尸]]|name=标靶僵尸|health=棒球帽,标靶+500|speed=慢|type=普通|version=0.9}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BOSS僵尸 =&lt;br /&gt;
&amp;lt;div class=&amp;quot;pvzhe-card-container&amp;quot;&amp;gt;&lt;br /&gt;
{{Card|image=[[文件:僵王博士.png|75px|僵王博士|link=僵王博士]]|name=僵王博士|health=40000|speed=慢|type=boss|version=0.13}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
== 如何贡献 ==&lt;br /&gt;
* 如果你想创建新的僵尸页面，可以在搜索框输入僵尸名称后进行创建。&lt;br /&gt;
* 编辑时请参考已有页面的格式，保持信息的一致性。&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4694</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4694"/>
		<updated>2026-06-13T03:08:47Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039;, draggable: &#039;false&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4693</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4693"/>
		<updated>2026-06-13T03:06:05Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, top: pos.top }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, top: window.innerHeight - 120 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, top: savedPos.top + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039;, draggable: &#039;false&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
    &lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4692</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4692"/>
		<updated>2026-06-13T03:03:14Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var positionKey = &#039;wiki_pet_position&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() { localStorage.setItem(affectionKey, affection); }&lt;br /&gt;
&lt;br /&gt;
        function savePosition() {&lt;br /&gt;
            var pos = $pet.position();&lt;br /&gt;
            var bottom = $(window).height() - pos.top - $pet.height();&lt;br /&gt;
            localStorage.setItem(positionKey, JSON.stringify({ left: pos.left, bottom: Math.max(0, bottom) }));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else { text += &#039; MAX&#039;; }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-heart&#039;, text: heart, css: { left: x, top: y } });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var savedPos = JSON.parse(localStorage.getItem(positionKey)) || { left: 20, bottom: 20 };&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
            class: &#039;wiki-pet&#039;,&lt;br /&gt;
            css: { opacity: 0, left: savedPos.left + &#039;px&#039;, bottom: savedPos.bottom + &#039;px&#039;, top: &#039;auto&#039;, right: &#039;auto&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039;, draggable: &#039;false&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + getLevel(affection).emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX; dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX, dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true; hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX; dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left; petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX, dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = Math.max(0, Math.min(petStartX + dx, window.innerWidth - 100));&lt;br /&gt;
            var newY = Math.max(0, Math.min(petStartY + dy, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function() {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
            savePosition();&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4691</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4691"/>
		<updated>2026-06-13T02:59:16Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
     // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 100;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var isDragging = false;&lt;br /&gt;
        var dragStartX, dragStartY, petStartX, petStartY;&lt;br /&gt;
        var hasMoved = false;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039;, draggable: &#039;false&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 拖拽功能&lt;br /&gt;
        $pet.on(&#039;mousedown&#039;, function(e) {&lt;br /&gt;
            if (e.button !== 0) return;&lt;br /&gt;
            isDragging = true;&lt;br /&gt;
            hasMoved = false;&lt;br /&gt;
            dragStartX = e.clientX;&lt;br /&gt;
            dragStartY = e.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left;&lt;br /&gt;
            petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mousemove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var dx = e.clientX - dragStartX;&lt;br /&gt;
            var dy = e.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = petStartX + dx;&lt;br /&gt;
            var newY = petStartY + dy;&lt;br /&gt;
            newX = Math.max(0, Math.min(newX, window.innerWidth - 100));&lt;br /&gt;
            newY = Math.max(0, Math.min(newY, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;mouseup&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 点击抚摸（只有没拖动时才触发）&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            if (hasMoved) return;&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 伸懒腰&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; !isDragging &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 移动端拖拽&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            isDragging = true;&lt;br /&gt;
            hasMoved = false;&lt;br /&gt;
            dragStartX = touch.clientX;&lt;br /&gt;
            dragStartY = touch.clientY;&lt;br /&gt;
            petStartX = $pet.offset().left;&lt;br /&gt;
            petStartY = $pet.offset().top;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;none&#039;);&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchmove&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            var touch = e.originalEvent.touches[0];&lt;br /&gt;
            var dx = touch.clientX - dragStartX;&lt;br /&gt;
            var dy = touch.clientY - dragStartY;&lt;br /&gt;
            if (Math.abs(dx) &amp;gt; 3 || Math.abs(dy) &amp;gt; 3) hasMoved = true;&lt;br /&gt;
            var newX = petStartX + dx;&lt;br /&gt;
            var newY = petStartY + dy;&lt;br /&gt;
            newX = Math.max(0, Math.min(newX, window.innerWidth - 100));&lt;br /&gt;
            newY = Math.max(0, Math.min(newY, window.innerHeight - 100));&lt;br /&gt;
            $pet.css({ left: newX + &#039;px&#039;, top: newY + &#039;px&#039;, bottom: &#039;auto&#039;, right: &#039;auto&#039; });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;touchend&#039;, function(e) {&lt;br /&gt;
            if (!isDragging) return;&lt;br /&gt;
            isDragging = false;&lt;br /&gt;
            $pet.css(&#039;transition&#039;, &#039;transform 0.2s&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (!hasMoved) {&lt;br /&gt;
                var now = Date.now();&lt;br /&gt;
                if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
                lastPetTime = now;&lt;br /&gt;
                setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
                var oldLevel = getLevel(affection).title;&lt;br /&gt;
                affection += affectionPerPet;&lt;br /&gt;
                saveAffection();&lt;br /&gt;
                showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
                var newLevel = getLevel(affection).title;&lt;br /&gt;
                if (newLevel !== oldLevel) {&lt;br /&gt;
                    triggerLevelUp();&lt;br /&gt;
                    $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                    setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                var offset = $pet.offset();&lt;br /&gt;
                spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4688</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4688"/>
		<updated>2026-06-13T01:47:22Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 130px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4685</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4685"/>
		<updated>2026-06-13T01:46:50Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 150px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4684</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4684"/>
		<updated>2026-06-13T01:45:44Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        // 好感度系统&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5; // 每次抚摸增加好感度&lt;br /&gt;
        var affectionCooldown = 100; // 抚摸冷却时间（毫秒）&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 飘出爱心&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 升级特效&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            // 增加好感度&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            // 升级检测&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $tooltip.text(&#039;好感度提升！&#039; + newLevel + &#039;！🎉&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // 飘爱心&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 伸懒腰&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 移动端&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4683</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4683"/>
		<updated>2026-06-13T01:43:16Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 500;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text).css(&#039;color&#039;, &#039;#fff&#039;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() { $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;); }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $affectionPanel.text(&#039;🎉 升级！&#039; + newLevel + &#039;！&#039;).css(&#039;color&#039;, &#039;#FFD700&#039;);&lt;br /&gt;
                setTimeout(function() { showAffectionPanel(); }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4682</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4682"/>
		<updated>2026-06-13T01:41:51Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        // 好感度系统&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5;&lt;br /&gt;
        var affectionCooldown = 500;&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $tooltip.text(&#039;好感度提升！&#039; + newLevel + &#039;！🎉&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    var lvl = getLevel(affection);&lt;br /&gt;
                    $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
                }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $tooltip.text(&#039;好感度提升！&#039; + newLevel + &#039;！🎉&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    var lvl = getLevel(affection);&lt;br /&gt;
                    $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
                }, 2000);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4681</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4681"/>
		<updated>2026-06-13T01:39:15Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 50px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 110px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4680</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4680"/>
		<updated>2026-06-13T01:38:31Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        // 好感度系统&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5; // 每次抚摸增加好感度&lt;br /&gt;
        var affectionCooldown = 0; // 抚摸冷却时间（毫秒）&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 飘出爱心&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 升级特效&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            // 增加好感度&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            // 升级检测&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $tooltip.text(&#039;好感度提升！&#039; + newLevel + &#039;！🎉&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // 飘爱心&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 伸懒腰&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 移动端&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4679</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4679"/>
		<updated>2026-06-13T01:36:17Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        // 好感度系统&lt;br /&gt;
        var affectionKey = &#039;wiki_pet_affection&#039;;&lt;br /&gt;
        var affection = parseInt(localStorage.getItem(affectionKey)) || 0;&lt;br /&gt;
        var affectionPerPet = 5; // 每次抚摸增加好感度&lt;br /&gt;
        var affectionCooldown = 3000; // 抚摸冷却时间（毫秒）&lt;br /&gt;
        var lastPetTime = 0;&lt;br /&gt;
        var levels = [&lt;br /&gt;
            { min: 0, title: &#039;陌生&#039;, emoji: &#039;🤔&#039; },&lt;br /&gt;
            { min: 50, title: &#039;认识&#039;, emoji: &#039;👋&#039; },&lt;br /&gt;
            { min: 150, title: &#039;友好&#039;, emoji: &#039;😊&#039; },&lt;br /&gt;
            { min: 400, title: &#039;亲密&#039;, emoji: &#039;💚&#039; },&lt;br /&gt;
            { min: 1000, title: &#039;挚友&#039;, emoji: &#039;💖&#039; },&lt;br /&gt;
            { min: 2500, title: &#039;灵魂伴侣&#039;, emoji: &#039;✨&#039; }&lt;br /&gt;
        ];&lt;br /&gt;
&lt;br /&gt;
        function getLevel(aff) {&lt;br /&gt;
            var lvl = levels[0];&lt;br /&gt;
            for (var i = levels.length - 1; i &amp;gt;= 0; i--) {&lt;br /&gt;
                if (aff &amp;gt;= levels[i].min) { lvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return lvl;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function saveAffection() {&lt;br /&gt;
            localStorage.setItem(affectionKey, affection);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function showAffectionPanel() {&lt;br /&gt;
            var lvl = getLevel(affection);&lt;br /&gt;
            var nextLvl = null;&lt;br /&gt;
            for (var i = 0; i &amp;lt; levels.length; i++) {&lt;br /&gt;
                if (affection &amp;lt; levels[i].min) { nextLvl = levels[i]; break; }&lt;br /&gt;
            }&lt;br /&gt;
            var text = lvl.emoji + &#039; &#039; + lvl.title + &#039; (&#039; + affection + &#039;)&#039;;&lt;br /&gt;
            if (nextLvl) {&lt;br /&gt;
                var progress = Math.round((affection - lvl.min) / (nextLvl.min - lvl.min) * 100);&lt;br /&gt;
                text += &#039; → &#039; + nextLvl.emoji + &#039; &#039; + progress + &#039;%&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                text += &#039; MAX&#039;;&lt;br /&gt;
            }&lt;br /&gt;
            $affectionPanel.text(text);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 飘出爱心&lt;br /&gt;
        function spawnHeart(x, y) {&lt;br /&gt;
            var hearts = [&#039;💚&#039;, &#039;💙&#039;, &#039;💛&#039;, &#039;💜&#039;, &#039;❤️&#039;, &#039;💖&#039;, &#039;✨&#039;];&lt;br /&gt;
            var heart = hearts[Math.floor(Math.random() * hearts.length)];&lt;br /&gt;
            var $heart = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                class: &#039;pet-heart&#039;,&lt;br /&gt;
                text: heart,&lt;br /&gt;
                css: { left: x, top: y }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;body&#039;).append($heart);&lt;br /&gt;
            setTimeout(function() { $heart.remove(); }, 1500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 升级特效&lt;br /&gt;
        function triggerLevelUp() {&lt;br /&gt;
            $pet.addClass(&#039;level-up&#039;);&lt;br /&gt;
            setTimeout(function() { $pet.removeClass(&#039;level-up&#039;); }, 800);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $affectionPanel = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-affection&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $affectionPanel, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        showAffectionPanel();&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                var lvl = getLevel(affection);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ &#039; + lvl.emoji);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            // 增加好感度&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            // 升级检测&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
                $tooltip.text(&#039;好感度提升！&#039; + newLevel + &#039;！🎉&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // 飘爱心&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 伸懒腰&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 移动端&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            var now = Date.now();&lt;br /&gt;
            if (now - lastPetTime &amp;lt; affectionCooldown) return;&lt;br /&gt;
            lastPetTime = now;&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
&lt;br /&gt;
            var oldLevel = getLevel(affection).title;&lt;br /&gt;
            affection += affectionPerPet;&lt;br /&gt;
            saveAffection();&lt;br /&gt;
            showAffectionPanel();&lt;br /&gt;
&lt;br /&gt;
            var newLevel = getLevel(affection).title;&lt;br /&gt;
            if (newLevel !== oldLevel) {&lt;br /&gt;
                triggerLevelUp();&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var offset = $pet.offset();&lt;br /&gt;
            spawnHeart(offset.left + 30, offset.top - 10);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4678</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4678"/>
		<updated>2026-06-13T01:35:33Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 110px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 好感度面板 */&lt;br /&gt;
.pet-affection {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: -30px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.7);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 3px 8px;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-affection {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 好感度飘出 */&lt;br /&gt;
.pet-heart {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
    animation: floatUp 1.5s ease-out forwards;&lt;br /&gt;
    font-size: 20px;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
}&lt;br /&gt;
@keyframes floatUp {&lt;br /&gt;
    0% { opacity: 1; transform: translateY(0) scale(1); }&lt;br /&gt;
    100% { opacity: 0; transform: translateY(-60px) scale(1.5); }&lt;br /&gt;
}&lt;br /&gt;
/* 升级特效 */&lt;br /&gt;
.wiki-pet.level-up {&lt;br /&gt;
    animation: levelUpGlow 0.8s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes levelUpGlow {&lt;br /&gt;
    0%, 100% { filter: drop-shadow(0 0 5px gold); }&lt;br /&gt;
    50% { filter: drop-shadow(0 0 20px gold) brightness(1.3); }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4675</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4675"/>
		<updated>2026-06-13T01:33:13Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var autoAttackTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var attackGif = &#039;https://new.pvzhe.wiki/images/b/bd/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%B0%84%E5%87%BB.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting attacking&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ 🐱&#039;);&lt;br /&gt;
                startAutoAttack();&lt;br /&gt;
            } else if (state === &#039;attack&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, attackGif);&lt;br /&gt;
                $pet.addClass(&#039;attacking&#039;);&lt;br /&gt;
                $tooltip.text(&#039;看招！❄️&#039;);&lt;br /&gt;
                stopAutoAttack();&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 600);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                stopAutoAttack();&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 自动攻击（每 8~15 秒随机一次）&lt;br /&gt;
        function startAutoAttack() {&lt;br /&gt;
            stopAutoAttack();&lt;br /&gt;
            var delay = 8000 + Math.random() * 7000; // 8~15 秒&lt;br /&gt;
            autoAttackTimer = setTimeout(function() {&lt;br /&gt;
                if (petState === &#039;idle&#039;) {&lt;br /&gt;
                    setPetState(&#039;attack&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }, delay);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        function stopAutoAttack() {&lt;br /&gt;
            clearTimeout(autoAttackTimer);&lt;br /&gt;
            autoAttackTimer = null;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;dblclick&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;attack&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 点击页面空白处攻击&lt;br /&gt;
        $(document).on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if (!$(e.target).closest(&#039;.wiki-pet&#039;).length &amp;amp;&amp;amp; petState === &#039;idle&#039;) {&lt;br /&gt;
                setPetState(&#039;attack&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 伸懒腰&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        // 启动自动攻击&lt;br /&gt;
        startAutoAttack();&lt;br /&gt;
&lt;br /&gt;
        // 移动端&lt;br /&gt;
        var touchTimer;&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            touchTimer = setTimeout(function() { setPetState(&#039;attack&#039;); }, 500);&lt;br /&gt;
        });&lt;br /&gt;
        $pet.on(&#039;touchend touchmove&#039;, function() {&lt;br /&gt;
            clearTimeout(touchTimer);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4673</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4673"/>
		<updated>2026-06-13T01:29:43Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 110px;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        left: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4672</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.js&amp;diff=4672"/>
		<updated>2026-06-13T01:28:32Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */&lt;br /&gt;
&lt;br /&gt;
// 自动加载 MediaWiki:Footer 页面内容，并插入到每个页面底部&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    const namespace = mw.config.get(&#039;wgNamespaceNumber&#039;);&lt;br /&gt;
    const action = mw.config.get(&#039;wgAction&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if (namespace !== 0 || action !== &#039;view&#039;) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fetch(&amp;quot;/api.php?action=parse&amp;amp;page=MediaWiki:Footer&amp;amp;format=json&amp;quot;)&lt;br /&gt;
        .then(res =&amp;gt; res.json())&lt;br /&gt;
        .then(data =&amp;gt; {&lt;br /&gt;
            if (data.parse &amp;amp;&amp;amp; data.parse.text) {&lt;br /&gt;
                const html = data.parse.text[&#039;*&#039;];&lt;br /&gt;
                $(&#039;#mw-content-text&#039;).append(&#039;&amp;lt;div class=&amp;quot;global-footer&amp;quot;&amp;gt;&#039; + html + &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// 用户颜色、图标、状态、师徒、昵称、里程碑、公告、植物/僵尸筛选、好友、私信 主逻辑&lt;br /&gt;
$(function () {&lt;br /&gt;
    // ==================== 动态注入彩虹样式 ====================&lt;br /&gt;
    var rainbowStyle = document.createElement(&#039;style&#039;);&lt;br /&gt;
    rainbowStyle.textContent =&lt;br /&gt;
        &#039;.rainbow-user {&#039; +&lt;br /&gt;
            &#039;font-weight: bold;&#039; +&lt;br /&gt;
            &#039;background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);&#039; +&lt;br /&gt;
            &#039;-webkit-background-clip: text;&#039; +&lt;br /&gt;
            &#039;-webkit-text-fill-color: transparent;&#039; +&lt;br /&gt;
            &#039;background-clip: text;&#039; +&lt;br /&gt;
        &#039;}&#039;;&lt;br /&gt;
    document.head.appendChild(rainbowStyle);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 配置区 ====================&lt;br /&gt;
    var mentorList = [&#039;愤怒的郎朗&#039;, &#039;Yuyaabc&#039;, &#039;虚位以待&#039;, &#039;知更鸟头号粉丝&#039;, &#039;凌玥&#039;];&lt;br /&gt;
    var newbieEditThreshold = 25;&lt;br /&gt;
    var milestoneThresholds = [10, 50, 100, 500, 1000, 2500, 5000, 10000, 20000, 50000];&lt;br /&gt;
&lt;br /&gt;
    // ==================== 辅助函数 ====================&lt;br /&gt;
    function getUserName(link) {&lt;br /&gt;
        var $span = $(link).find(&#039;span&#039;).first();&lt;br /&gt;
        if ($span.length) return $span.text().trim();&lt;br /&gt;
        return $(link).text().trim();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function isUserLink(link) {&lt;br /&gt;
        return $(link).is(&#039;a.mw-userlink&#039;) || $(link).find(&#039;span&#039;).length &amp;gt; 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getLevelIcons(editcount) {&lt;br /&gt;
        var totalStars = Math.floor(editcount / 100);&lt;br /&gt;
        if (totalStars === 0) return &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        var crowns = Math.floor(totalStars / 125);&lt;br /&gt;
        var remaining = totalStars % 125;&lt;br /&gt;
        var suns = Math.floor(remaining / 25);&lt;br /&gt;
        remaining %= 25;&lt;br /&gt;
        var moons = Math.floor(remaining / 5);&lt;br /&gt;
        var stars = remaining % 5;&lt;br /&gt;
&lt;br /&gt;
        var icons = &#039;&#039;;&lt;br /&gt;
        if (crowns &amp;gt; 0) icons += &#039;👑&#039;.repeat(crowns);&lt;br /&gt;
        if (suns &amp;gt; 0)   icons += &#039;☀️&#039;.repeat(suns);&lt;br /&gt;
        if (moons &amp;gt; 0)  icons += &#039;🌙&#039;.repeat(moons);&lt;br /&gt;
        if (stars &amp;gt; 0)  icons += &#039;⭐&#039;.repeat(stars);&lt;br /&gt;
        return icons;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateLevelIcons($link, editcount) {&lt;br /&gt;
        var iconStr = getLevelIcons(editcount);&lt;br /&gt;
        var $iconSpan = $link.next(&#039;.user-level-icons&#039;);&lt;br /&gt;
        if (iconStr === &#039;&#039;) {&lt;br /&gt;
            $iconSpan.remove();&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ($iconSpan.length === 0) {&lt;br /&gt;
            $iconSpan = $(&#039;&amp;lt;span class=&amp;quot;user-level-icons&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($iconSpan);&lt;br /&gt;
        }&lt;br /&gt;
        $iconSpan.text(iconStr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getTitleByEditcount(ec) {&lt;br /&gt;
        if (ec &amp;gt;= 10000) return &#039;🐉 神话&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 5000)  return &#039;👑 传奇&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 2500)  return &#039;🏆 大师&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 1000)  return &#039;💎 专家&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 500)   return &#039;🔥 资深&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 100)   return &#039;⭐ 活跃&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 50)    return &#039;🌳 入门&#039;;&lt;br /&gt;
        if (ec &amp;gt;= 10)    return &#039;🌿 新手&#039;;&lt;br /&gt;
        return &#039;🌱 萌新&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function addTitleTag($link, editcount) {&lt;br /&gt;
        if ($link.data(&#039;title-tag-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;title-tag-added&#039;, true);&lt;br /&gt;
        var title = getTitleByEditcount(editcount);&lt;br /&gt;
        var $tag = $(&#039;&amp;lt;span class=&amp;quot;user-title-tag&amp;quot;&amp;gt;&#039; + title + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($tag);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 核心：颜色 + 图标 + 状态 + 师徒 + 昵称 ====================&lt;br /&gt;
    function colorizeAndStatus($links) {&lt;br /&gt;
        if ($links.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $fresh = $links.filter(function () {&lt;br /&gt;
            return !$(this).data(&#039;user-status-processed&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        if ($fresh.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var users = [];&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            var name = getUserName(this);&lt;br /&gt;
            if (name &amp;amp;&amp;amp; users.indexOf(name) === -1) users.push(name);&lt;br /&gt;
        });&lt;br /&gt;
        if (users.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            $(this).data(&#039;user-status-processed&#039;, true);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var batchSize = 50;&lt;br /&gt;
        var batches = [];&lt;br /&gt;
        for (var i = 0; i &amp;lt; users.length; i += batchSize) {&lt;br /&gt;
            batches.push(users.slice(i, i + batchSize));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var processBatch = function (batch) {&lt;br /&gt;
            var api = new mw.Api();&lt;br /&gt;
            return api.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;users&#039;,&lt;br /&gt;
                ususers: batch.join(&#039;|&#039;),&lt;br /&gt;
                usprop: &#039;editcount&#039;&lt;br /&gt;
            }).then(function (data) {&lt;br /&gt;
                var classMap = {};&lt;br /&gt;
                var editCountMap = {};&lt;br /&gt;
                if (data.query &amp;amp;&amp;amp; data.query.users) {&lt;br /&gt;
                    data.query.users.forEach(function (u) {&lt;br /&gt;
                        var ec = u.editcount || 0;&lt;br /&gt;
                        editCountMap[u.name] = ec;&lt;br /&gt;
                        if (ec &amp;gt;= 5000) classMap[u.name] = &#039;rainbow-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 2500) classMap[u.name] = &#039;gold-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1000) classMap[u.name] = &#039;platinum-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 500) classMap[u.name] = &#039;silver-user&#039;;&lt;br /&gt;
                        else if (ec &amp;gt;= 1) classMap[u.name] = &#039;bronze-user&#039;;&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
                $fresh.each(function () {&lt;br /&gt;
                    var $this = $(this);&lt;br /&gt;
                    var name = getUserName(this);&lt;br /&gt;
                    var cls = classMap[name];&lt;br /&gt;
                    if (cls) {&lt;br /&gt;
                        $this.removeClass(&#039;bronze-user silver-user platinum-user gold-user rainbow-user&#039;);&lt;br /&gt;
                        $this.addClass(cls);&lt;br /&gt;
                    }&lt;br /&gt;
                    var ec = editCountMap[name];&lt;br /&gt;
                    if (typeof ec !== &#039;undefined&#039;) {&lt;br /&gt;
                        updateLevelIcons($this, ec);&lt;br /&gt;
                        var isInsideCard = $this.closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                        if (!isInsideCard) {&lt;br /&gt;
                            addTitleTag($this, ec);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        var colorPromise = $.Deferred().resolve();&lt;br /&gt;
        batches.forEach(function (batch) {&lt;br /&gt;
            colorPromise = colorPromise.then(function () {&lt;br /&gt;
                return processBatch(batch);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $fresh.each(function () {&lt;br /&gt;
            if (isUserLink(this)) {&lt;br /&gt;
                var isInsideCard = $(this).closest(&#039;.citizen-menu_card-content, .citizen-userMenu&#039;).length &amp;gt; 0;&lt;br /&gt;
                if (!isInsideCard) {&lt;br /&gt;
                    var username = getUserName(this);&lt;br /&gt;
                    addStatusDot($(this), username);&lt;br /&gt;
                    addMentorTag($(this), username);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 状态圆点 ====================&lt;br /&gt;
    function addStatusDot($link, username) {&lt;br /&gt;
        if ($link.data(&#039;status-dot-added&#039;)) return;&lt;br /&gt;
        $link.data(&#039;status-dot-added&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var $dot = $(&#039;&amp;lt;span class=&amp;quot;user-status-dot status-offline&amp;quot; title=&amp;quot;离线&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $link.after($dot);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_user_status_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 5 * 60 * 1000) {&lt;br /&gt;
                    updateDotStyle($dot, data.lastEditTime);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;usercontribs&#039;,&lt;br /&gt;
            ucuser: username,&lt;br /&gt;
            uclimit: 1,&lt;br /&gt;
            ucprop: &#039;timestamp&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var lastEditTime = null;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.usercontribs &amp;amp;&amp;amp; data.query.usercontribs.length &amp;gt; 0) {&lt;br /&gt;
                lastEditTime = data.query.usercontribs[0].timestamp;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                lastEditTime: lastEditTime,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            updateDotStyle($dot, lastEditTime);&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateDotStyle($dot, lastEditTime) {&lt;br /&gt;
        if (!lastEditTime) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var last = new Date(lastEditTime).getTime();&lt;br /&gt;
        var diffMinutes = (Date.now() - last) / 60000;&lt;br /&gt;
        if (diffMinutes &amp;lt; 15) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;在线（15分钟内活跃）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-away&#039;).addClass(&#039;status-online&#039;);&lt;br /&gt;
        } else if (diffMinutes &amp;lt; 60) {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;近期活跃（1小时内）&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-offline status-online&#039;).addClass(&#039;status-away&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $dot.attr(&#039;title&#039;, &#039;离线&#039;);&lt;br /&gt;
            $dot.removeClass(&#039;status-online status-away&#039;).addClass(&#039;status-offline&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 师徒标签 ====================&lt;br /&gt;
    function addMentorTag($link, username) {&lt;br /&gt;
        if ($link.data(&#039;mentor-tag-added&#039;)) return;&lt;br /&gt;
        if ($link.next(&#039;.user-tag&#039;).length) return;&lt;br /&gt;
&lt;br /&gt;
        var $tag;&lt;br /&gt;
&lt;br /&gt;
        if (mentorList.indexOf(username) !== -1) {&lt;br /&gt;
            $link.data(&#039;mentor-tag-added&#039;, true);&lt;br /&gt;
            $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-mentor&amp;quot;&amp;gt;导师&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $link.after($tag);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($link.data(&#039;newbie-tag-checked&#039;)) return;&lt;br /&gt;
        $link.data(&#039;newbie-tag-checked&#039;, true);&lt;br /&gt;
&lt;br /&gt;
        var cacheKey = &#039;mw_newbie_check_&#039; + mw.config.get(&#039;wgDBname&#039;) + &#039;_&#039; + username;&lt;br /&gt;
        var cached = localStorage.getItem(cacheKey);&lt;br /&gt;
        var now = Date.now();&lt;br /&gt;
        if (cached) {&lt;br /&gt;
            try {&lt;br /&gt;
                var data = JSON.parse(cached);&lt;br /&gt;
                if (now - data.timestamp &amp;lt; 60 * 60 * 1000) {&lt;br /&gt;
                    if (data.editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                        $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $link.after($tag);&lt;br /&gt;
                    }&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {}&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: username,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
            localStorage.setItem(cacheKey, JSON.stringify({&lt;br /&gt;
                editcount: editcount,&lt;br /&gt;
                timestamp: now&lt;br /&gt;
            }));&lt;br /&gt;
            if (editcount &amp;lt;= newbieEditThreshold) {&lt;br /&gt;
                if ($link.next(&#039;.user-tag-newbie&#039;).length === 0) {&lt;br /&gt;
                    $tag = $(&#039;&amp;lt;span class=&amp;quot;user-tag user-tag-newbie&amp;quot;&amp;gt;新手&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $link.after($tag);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function () {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 编辑里程碑弹窗 ====================&lt;br /&gt;
    var currentUser = mw.config.get(&#039;wgUserName&#039;);&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var api = new mw.Api();&lt;br /&gt;
        api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;users&#039;,&lt;br /&gt;
            ususers: currentUser,&lt;br /&gt;
            usprop: &#039;editcount&#039;&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var editcount = 0;&lt;br /&gt;
            if (data.query &amp;amp;&amp;amp; data.query.users &amp;amp;&amp;amp; data.query.users.length &amp;gt; 0) {&lt;br /&gt;
                editcount = data.query.users[0].editcount || 0;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var achievedMilestone = null;&lt;br /&gt;
            milestoneThresholds.forEach(function(m) {&lt;br /&gt;
                if (editcount &amp;gt;= m) achievedMilestone = m;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            if (achievedMilestone) {&lt;br /&gt;
                var storageKey = &#039;mw_milestone_shown_&#039; + currentUser + &#039;_&#039; + achievedMilestone;&lt;br /&gt;
                if (!localStorage.getItem(storageKey)) {&lt;br /&gt;
                    localStorage.setItem(storageKey, &#039;1&#039;);&lt;br /&gt;
&lt;br /&gt;
                    var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                            background: &#039;rgba(0,0,0,0.5)&#039;, &#039;z-index&#039;: 99998,&lt;br /&gt;
                            display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px 40px&#039;,&lt;br /&gt;
                            &#039;text-align&#039;: &#039;center&#039;, &#039;box-shadow&#039;: &#039;0 4px 20px rgba(0,0,0,0.3)&#039;,&lt;br /&gt;
                            &#039;max-width&#039;: &#039;400px&#039;, width: &#039;80%&#039;, position: &#039;relative&#039;&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $title = $(&#039;&amp;lt;h2&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;🎉 恭喜！&#039;,&lt;br /&gt;
                        css: { &#039;margin-bottom&#039;: &#039;15px&#039;, &#039;font-size&#039;: &#039;24px&#039;, color: &#039;#333&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $msg = $(&#039;&amp;lt;p&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;你已达到 &#039; + achievedMilestone + &#039; 次编辑！&#039;,&lt;br /&gt;
                        css: { &#039;font-size&#039;: &#039;18px&#039;, &#039;margin-bottom&#039;: &#039;25px&#039;, color: &#039;#555&#039; }&lt;br /&gt;
                    });&lt;br /&gt;
                    var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                        text: &#039;太棒了！&#039;,&lt;br /&gt;
                        css: {&lt;br /&gt;
                            background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                            padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;, &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                        },&lt;br /&gt;
                        click: function() {&lt;br /&gt;
                            $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
&lt;br /&gt;
                    $box.append($title, $msg, $btn);&lt;br /&gt;
                    $overlay.append($box);&lt;br /&gt;
                    $(&#039;body&#039;).append($overlay);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }).fail(function() {});&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 用户链接处理器启动 ====================&lt;br /&gt;
    var linkSelector = &#039;a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a&#039;;&lt;br /&gt;
    colorizeAndStatus($(linkSelector));&lt;br /&gt;
&lt;br /&gt;
    var observer = new MutationObserver(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    });&lt;br /&gt;
    observer.observe(document.body, {&lt;br /&gt;
        childList: true,&lt;br /&gt;
        subtree: true&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    setInterval(function () {&lt;br /&gt;
        colorizeAndStatus($(linkSelector));&lt;br /&gt;
    }, 3000);&lt;br /&gt;
&lt;br /&gt;
    // ==================== 植物卡片筛选 ====================&lt;br /&gt;
    if ($(&#039;#pf-name&#039;).length) {&lt;br /&gt;
        var $cards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $name = $(&#039;#pf-name&#039;);&lt;br /&gt;
        var $sunMax = $(&#039;#pf-sun-max&#039;);&lt;br /&gt;
        var $cdMax = $(&#039;#pf-cd-max&#039;);&lt;br /&gt;
        var $type = $(&#039;#pf-type&#039;);&lt;br /&gt;
        var $version = $(&#039;#pf-version&#039;);&lt;br /&gt;
        var $reset = $(&#039;#pf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterPlants() {&lt;br /&gt;
            var name = $name.val().toLowerCase();&lt;br /&gt;
            var sunRaw = $sunMax.val().trim();&lt;br /&gt;
            var cdRaw = $cdMax.val().trim();&lt;br /&gt;
            var sunTarget = sunRaw !== &#039;&#039; ? parseFloat(sunRaw) : null;&lt;br /&gt;
            var cdTarget = cdRaw !== &#039;&#039; ? parseFloat(cdRaw) : null;&lt;br /&gt;
            var type = $type.val();&lt;br /&gt;
            var version = $version.val();&lt;br /&gt;
&lt;br /&gt;
            $cards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var sun = parseFloat($card.data(&#039;sun&#039;)) || 0;&lt;br /&gt;
                var cd = parseFloat($card.data(&#039;cooldown&#039;)) || 0;&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (sunTarget !== null &amp;amp;&amp;amp; sun !== sunTarget) show = false;&lt;br /&gt;
                if (cdTarget !== null &amp;amp;&amp;amp; cd !== cdTarget) show = false;&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (s) { return s.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $name.on(&#039;input&#039;, filterPlants);&lt;br /&gt;
        $sunMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $cdMax.on(&#039;input keyup&#039;, filterPlants);&lt;br /&gt;
        $type.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $version.on(&#039;change&#039;, filterPlants);&lt;br /&gt;
        $reset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $name.val(&#039;&#039;);&lt;br /&gt;
            $sunMax.val(&#039;&#039;);&lt;br /&gt;
            $cdMax.val(&#039;&#039;);&lt;br /&gt;
            $type.val(&#039;&#039;);&lt;br /&gt;
            $version.val(&#039;&#039;);&lt;br /&gt;
            filterPlants();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 僵尸卡片筛选 ====================&lt;br /&gt;
    function getArmorArray(healthStr) {&lt;br /&gt;
        if (!healthStr || healthStr.indexOf(&#039;+&#039;) === -1) return [];&lt;br /&gt;
        var armorPart = healthStr.split(&#039;+&#039;)[0].trim();&lt;br /&gt;
        return armorPart.split(&#039;,&#039;).map(function(s) { return s.trim(); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function extractHealth(healthStr) {&lt;br /&gt;
        var matches = healthStr.match(/\d+/g);&lt;br /&gt;
        if (matches &amp;amp;&amp;amp; matches.length &amp;gt; 0) {&lt;br /&gt;
            return parseFloat(matches[matches.length - 1]) || 0;&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($(&#039;#zf-name&#039;).length) {&lt;br /&gt;
        var $zcards = $(&#039;.pvzhe-card&#039;);&lt;br /&gt;
        var $zname = $(&#039;#zf-name&#039;);&lt;br /&gt;
        var $healthMin = $(&#039;#zf-health-min&#039;);&lt;br /&gt;
        var $armor = $(&#039;#zf-armor&#039;);&lt;br /&gt;
        var $speed = $(&#039;#zf-speed&#039;);&lt;br /&gt;
        var $ztype = $(&#039;#zf-type&#039;);&lt;br /&gt;
        var $zversion = $(&#039;#zf-version&#039;);&lt;br /&gt;
        var $zreset = $(&#039;#zf-reset&#039;);&lt;br /&gt;
&lt;br /&gt;
        function filterZombies() {&lt;br /&gt;
            var name = $zname.val().toLowerCase();&lt;br /&gt;
            var healthRaw = $healthMin.val().trim();&lt;br /&gt;
            var healthTarget = healthRaw !== &#039;&#039; ? parseFloat(healthRaw) : null;&lt;br /&gt;
            var armor = $armor.val();&lt;br /&gt;
            var speed = $speed.val();&lt;br /&gt;
            var type = $ztype.val();&lt;br /&gt;
            var version = $zversion.val();&lt;br /&gt;
&lt;br /&gt;
            $zcards.each(function () {&lt;br /&gt;
                var $card = $(this);&lt;br /&gt;
                var n = $card.find(&#039;.pvzhe-card-name&#039;).text().toLowerCase();&lt;br /&gt;
                var t = ($card.data(&#039;type&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var s = ($card.data(&#039;speed&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var healthStr = ($card.data(&#039;health&#039;) || &#039;&#039;).toString();&lt;br /&gt;
                var health = extractHealth(healthStr);&lt;br /&gt;
                var armors = getArmorArray(healthStr);&lt;br /&gt;
                var v = ($card.data(&#039;version&#039;) || &#039;&#039;).toString();&lt;br /&gt;
&lt;br /&gt;
                var show = true;&lt;br /&gt;
                if (name &amp;amp;&amp;amp; n.indexOf(name) === -1) show = false;&lt;br /&gt;
                if (healthTarget !== null &amp;amp;&amp;amp; health !== healthTarget) show = false;&lt;br /&gt;
&lt;br /&gt;
                if (armor === &#039;none&#039;) {&lt;br /&gt;
                    if (armors.length &amp;gt; 0) show = false;&lt;br /&gt;
                } else if (armor) {&lt;br /&gt;
                    if (armors.indexOf(armor) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (speed) {&lt;br /&gt;
                    var cardSpeeds = s.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardSpeeds.indexOf(speed) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (type) {&lt;br /&gt;
                    var cardTypes = t.split(&#039;,&#039;).map(function (v) { return v.trim(); });&lt;br /&gt;
                    if (cardTypes.indexOf(type) === -1) show = false;&lt;br /&gt;
                }&lt;br /&gt;
                if (version &amp;amp;&amp;amp; v !== version) show = false;&lt;br /&gt;
                $card.toggleClass(&#039;hidden-card&#039;, !show);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $zname.on(&#039;input&#039;, filterZombies);&lt;br /&gt;
        $healthMin.on(&#039;input keyup&#039;, filterZombies);&lt;br /&gt;
        $armor.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $speed.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $ztype.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zversion.on(&#039;change&#039;, filterZombies);&lt;br /&gt;
        $zreset.on(&#039;click&#039;, function () {&lt;br /&gt;
            $zname.val(&#039;&#039;);&lt;br /&gt;
            $healthMin.val(&#039;&#039;);&lt;br /&gt;
            $armor.val(&#039;&#039;);&lt;br /&gt;
            $speed.val(&#039;&#039;);&lt;br /&gt;
            $ztype.val(&#039;&#039;);&lt;br /&gt;
            $zversion.val(&#039;&#039;);&lt;br /&gt;
            filterZombies();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 返回顶部按钮 ====================&lt;br /&gt;
    $(&#039;body&#039;).append(&#039;&amp;lt;button id=&amp;quot;back-to-top&amp;quot; title=&amp;quot;返回顶部&amp;quot;&amp;gt;⬆&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
    var $backBtn = $(&#039;#back-to-top&#039;);&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        $backBtn.toggle($(this).scrollTop() &amp;gt; 300);&lt;br /&gt;
    });&lt;br /&gt;
    $backBtn.click(function() {&lt;br /&gt;
        $(&#039;html, body&#039;).animate({ scrollTop: 0 }, 400);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // ==================== 好友系统 ====================&lt;br /&gt;
    var friendApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getFriendPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friends&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getFriendRequestsPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/friendrequests&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendList(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadFriendRequests(username, callback) {&lt;br /&gt;
        friendApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getFriendRequestsPageName(username),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveToPage(pageName, data, summary, callback) {&lt;br /&gt;
        friendApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: pageName,&lt;br /&gt;
            text: JSON.stringify(data, null, 2),&lt;br /&gt;
            summary: summary,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendFriendRequest(toUser) {&lt;br /&gt;
        if (!toUser || toUser === currentUser) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            if (myFriends.indexOf(toUser) !== -1) {&lt;br /&gt;
                alert(&#039;你们已经是好友了！&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            loadFriendRequests(toUser, function(requests) {&lt;br /&gt;
                var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                if (alreadySent) {&lt;br /&gt;
                    alert(&#039;你已经发送过好友请求了，请等待对方回应。&#039;);&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
                requests.push({ from: currentUser, time: Date.now() });&lt;br /&gt;
                saveToPage(getFriendRequestsPageName(toUser), requests, currentUser + &#039; 发送了好友请求&#039;, function(success) {&lt;br /&gt;
                    if (success) {&lt;br /&gt;
                        alert(&#039;好友请求已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                        updateFriendButton(toUser, &#039;pending&#039;);&lt;br /&gt;
                    } else {&lt;br /&gt;
                        alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function acceptFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends.push(fromUser);&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;添加好友: &#039; + fromUser, function() {&lt;br /&gt;
                loadFriendList(fromUser, function(theirFriends) {&lt;br /&gt;
                    theirFriends.push(currentUser);&lt;br /&gt;
                    saveToPage(getFriendPageName(fromUser), theirFriends, &#039;添加好友: &#039; + currentUser, function() {&lt;br /&gt;
                        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
                            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;接受好友请求&#039;, function() {&lt;br /&gt;
                                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
                                updateFriendButton(fromUser, &#039;added&#039;);&lt;br /&gt;
                            });&lt;br /&gt;
                        });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function rejectFriendRequest(fromUser) {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            requests = requests.filter(function(r) { return r.from !== fromUser; });&lt;br /&gt;
            saveToPage(getFriendRequestsPageName(currentUser), requests, &#039;拒绝好友请求&#039;, function() {&lt;br /&gt;
                if ($(&#039;#friend-requests-list&#039;).length) showFriendRequests();&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function removeFriend(friendName) {&lt;br /&gt;
        if (!confirm(&#039;确定要删除好友 &#039; + friendName + &#039; 吗？&#039;)) return;&lt;br /&gt;
        loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
            myFriends = myFriends.filter(function(f) { return f !== friendName; });&lt;br /&gt;
            saveToPage(getFriendPageName(currentUser), myFriends, &#039;删除好友: &#039; + friendName, function() {&lt;br /&gt;
                loadFriendList(friendName, function(theirFriends) {&lt;br /&gt;
                    theirFriends = theirFriends.filter(function(f) { return f !== currentUser; });&lt;br /&gt;
                    saveToPage(getFriendPageName(friendName), theirFriends, &#039;删除好友: &#039; + currentUser, function() {&lt;br /&gt;
                        if ($(&#039;#friend-list-container&#039;).length) showFriendList();&lt;br /&gt;
                        updateFriendButton(friendName, &#039;add&#039;);&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateFriendButton(username, status) {&lt;br /&gt;
        var $btn = $(&#039;#friend-action-btn&#039;);&lt;br /&gt;
        if (!$btn.length) return;&lt;br /&gt;
        $btn.removeClass(&#039;friend-add-btn friend-added-btn friend-pending-btn&#039;);&lt;br /&gt;
        if (status === &#039;added&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-added-btn&#039;).text(&#039;✓ 已添加&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { removeFriend(username); });&lt;br /&gt;
        } else if (status === &#039;pending&#039;) {&lt;br /&gt;
            $btn.addClass(&#039;friend-pending-btn&#039;).text(&#039;⏳ 等待确认&#039;).off(&#039;click&#039;);&lt;br /&gt;
        } else {&lt;br /&gt;
            $btn.addClass(&#039;friend-add-btn&#039;).text(&#039;+ 加好友&#039;);&lt;br /&gt;
            $btn.off(&#039;click&#039;).click(function() { sendFriendRequest(username); });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendRequests() {&lt;br /&gt;
        loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
            var $list = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
            if (!$list.length) return;&lt;br /&gt;
            $list.empty();&lt;br /&gt;
            if (requests.length === 0) {&lt;br /&gt;
                $list.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无好友请求&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            requests.forEach(function(r) {&lt;br /&gt;
                var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-request-item&#039; });&lt;br /&gt;
                $item.append(&#039;&amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(r.from) + &#039;&amp;quot;&amp;gt;&#039; + r.from + &#039;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                var $actions = $(&#039;&amp;lt;div&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-accept-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;接受&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $actions.append(&#039;&amp;lt;button class=&amp;quot;friend-reject-btn&amp;quot; data-from=&amp;quot;&#039; + r.from + &#039;&amp;quot;&amp;gt;拒绝&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $item.append($actions);&lt;br /&gt;
                $list.append($item);&lt;br /&gt;
            });&lt;br /&gt;
            $list.off(&#039;click&#039;).on(&#039;click&#039;, &#039;.friend-accept-btn&#039;, function() {&lt;br /&gt;
                acceptFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            }).on(&#039;click&#039;, &#039;.friend-reject-btn&#039;, function() {&lt;br /&gt;
                rejectFriendRequest($(this).data(&#039;from&#039;));&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showFriendList() {&lt;br /&gt;
        loadFriendList(currentUser, function(friends) {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-overlay&#039; });&lt;br /&gt;
                var $dialog = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;friend-dialog&#039; });&lt;br /&gt;
&lt;br /&gt;
                var realCount = friends.length;&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;h3&amp;gt;👥 好友列表 &amp;lt;span class=&amp;quot;friend-count&amp;quot;&amp;gt;&#039; + realCount + &#039;人&amp;lt;/span&amp;gt;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#f44336;cursor:pointer;&amp;quot; id=&amp;quot;friend-req-notice&amp;quot;&amp;gt;📩 有 &#039; + requests.length + &#039; 条好友请求，点击查看&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;div id=&amp;quot;friend-requests-list&amp;quot; style=&amp;quot;display:none;margin:10px 0;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
                if (realCount === 0) {&lt;br /&gt;
                    $dialog.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;还没有好友，去其他用户页面加好友吧！&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    var $container = $(&#039;&amp;lt;div&amp;gt;&#039;, { id: &#039;friend-list-container&#039;, style: &#039;margin:10px 0;&#039; });&lt;br /&gt;
                    friends.forEach(function(f) {&lt;br /&gt;
                        var $item = $(&#039;&amp;lt;span&amp;gt;&#039;, { class: &#039;friend-list-item&#039; });&lt;br /&gt;
                        $item.append(&#039;&amp;lt;a href=&amp;quot;/w/User:&#039; + encodeURIComponent(f) + &#039;&amp;quot;&amp;gt;&#039; + f + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; class=&amp;quot;friend-msg-link&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot; title=&amp;quot;发私信&amp;quot;&amp;gt;✉️&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
                        $item.append(&#039;&amp;lt;span class=&amp;quot;friend-remove&amp;quot; data-friend=&amp;quot;&#039; + f + &#039;&amp;quot;&amp;gt; ×&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                        $container.append($item);&lt;br /&gt;
                    });&lt;br /&gt;
                    $dialog.append($container);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                $dialog.append(&#039;&amp;lt;button style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
                $overlay.append($dialog);&lt;br /&gt;
                $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
                $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                    if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                        $overlay.remove();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;#friend-req-notice&#039;, function() {&lt;br /&gt;
                    var $reqList = $(&#039;#friend-requests-list&#039;);&lt;br /&gt;
                    $reqList.toggle();&lt;br /&gt;
                    if ($reqList.is(&#039;:visible&#039;)) showFriendRequests();&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-remove&#039;, function() {&lt;br /&gt;
                    removeFriend($(this).data(&#039;friend&#039;));&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                $dialog.on(&#039;click&#039;, &#039;.friend-msg-link&#039;, function() {&lt;br /&gt;
                    var friendName = $(this).data(&#039;friend&#039;);&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    sendMessage(friendName);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var pageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (pageUser !== currentUser) {&lt;br /&gt;
            var $btn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                id: &#039;friend-action-btn&#039;,&lt;br /&gt;
                class: &#039;friend-btn friend-add-btn&#039;,&lt;br /&gt;
                text: &#039;+ 加好友&#039;&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($btn);&lt;br /&gt;
&lt;br /&gt;
            loadFriendList(currentUser, function(myFriends) {&lt;br /&gt;
                if (myFriends.indexOf(pageUser) !== -1) {&lt;br /&gt;
                    updateFriendButton(pageUser, &#039;added&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    loadFriendRequests(pageUser, function(requests) {&lt;br /&gt;
                        var alreadySent = requests.some(function(r) { return r.from === currentUser; });&lt;br /&gt;
                        if (alreadySent) {&lt;br /&gt;
                            updateFriendButton(pageUser, &#039;pending&#039;);&lt;br /&gt;
                        } else {&lt;br /&gt;
                            $btn.click(function() { sendFriendRequest(pageUser); });&lt;br /&gt;
                        }&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        var $userMenu = $(&#039;#pt-userpage, .citizen-userMenu&#039;).first();&lt;br /&gt;
        if ($userMenu.length) {&lt;br /&gt;
            $userMenu.after(&#039; &amp;lt;a href=&amp;quot;javascript:void(0)&amp;quot; id=&amp;quot;friend-list-trigger&amp;quot; style=&amp;quot;font-size:13px;&amp;quot; title=&amp;quot;好友列表&amp;quot;&amp;gt;👥&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#friend-list-trigger&#039;, function() {&lt;br /&gt;
            showFriendList();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            loadFriendRequests(currentUser, function(requests) {&lt;br /&gt;
                var $notice = $(&#039;#friend-request-count&#039;);&lt;br /&gt;
                if (requests.length &amp;gt; 0) {&lt;br /&gt;
                    if (!$notice.length &amp;amp;&amp;amp; $(&#039;#friend-list-trigger&#039;).length) {&lt;br /&gt;
                        $(&#039;#friend-list-trigger&#039;).after(&#039;&amp;lt;span id=&amp;quot;friend-request-count&amp;quot; style=&amp;quot;color:#f44336;font-size:11px;vertical-align:super;&amp;quot;&amp;gt;&#039; + requests.length + &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    } else if ($notice.length) {&lt;br /&gt;
                        $notice.text(requests.length);&lt;br /&gt;
                    }&lt;br /&gt;
                } else {&lt;br /&gt;
                    $notice.remove();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, 60000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 私信系统 ====================&lt;br /&gt;
    var msgApi = new mw.Api();&lt;br /&gt;
&lt;br /&gt;
    function getMsgPageName(username) {&lt;br /&gt;
        return &#039;User:&#039; + username + &#039;/messages&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadMessages(callback) {&lt;br /&gt;
        if (!currentUser) { callback([]); return; }&lt;br /&gt;
        msgApi.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: getMsgPageName(currentUser),&lt;br /&gt;
            prop: &#039;revisions&#039;,&lt;br /&gt;
            rvprop: &#039;content&#039;,&lt;br /&gt;
            rvlimit: 1&lt;br /&gt;
        }).then(function(data) {&lt;br /&gt;
            var pages = data.query.pages;&lt;br /&gt;
            for (var id in pages) {&lt;br /&gt;
                if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                    try { callback(JSON.parse(pages[id].revisions[0][&#039;*&#039;])); return; } catch(e) {}&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            callback([]);&lt;br /&gt;
        }).fail(function() { callback([]); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveMessages(msgs, callback) {&lt;br /&gt;
        if (!currentUser) return;&lt;br /&gt;
        msgApi.postWithEditToken({&lt;br /&gt;
            action: &#039;edit&#039;,&lt;br /&gt;
            title: getMsgPageName(currentUser),&lt;br /&gt;
            text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
            summary: &#039;更新私信&#039;,&lt;br /&gt;
            minor: true,&lt;br /&gt;
            bot: true&lt;br /&gt;
        }).then(function() {&lt;br /&gt;
            if (callback) callback(true);&lt;br /&gt;
        }).fail(function() {&lt;br /&gt;
            if (callback) callback(false);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function getUnreadCount(msgs) {&lt;br /&gt;
        var count = 0;&lt;br /&gt;
        msgs.forEach(function(m) { if (!m.read) count++; });&lt;br /&gt;
        return count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function updateMsgBadge() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var count = getUnreadCount(msgs);&lt;br /&gt;
            var $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
            if ($badge.length === 0) {&lt;br /&gt;
                var $drawer = $(&#039;.citizen-drawer&#039;).first();&lt;br /&gt;
                if ($drawer.length) {&lt;br /&gt;
                    $drawer.css(&#039;position&#039;, &#039;relative&#039;);&lt;br /&gt;
                    $drawer.append(&#039;&amp;lt;span id=&amp;quot;msg-badge&amp;quot; class=&amp;quot;msg-badge&amp;quot; title=&amp;quot;新私信&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                    $badge = $(&#039;#msg-badge&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            if ($badge.length) {&lt;br /&gt;
                $badge.text(count).toggle(count &amp;gt; 0);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showInbox() {&lt;br /&gt;
        loadMessages(function(msgs) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
            $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:15px;&amp;quot;&amp;gt;📬 私信箱&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
            msgs.sort(function(a, b) { return b.time - a.time; });&lt;br /&gt;
&lt;br /&gt;
            if (msgs.length === 0) {&lt;br /&gt;
                $box.append(&#039;&amp;lt;p style=&amp;quot;color:#999;&amp;quot;&amp;gt;暂无消息&amp;lt;/p&amp;gt;&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                msgs.forEach(function(m, index) {&lt;br /&gt;
                    var $item = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-item&#039; + (m.read ? &#039;&#039; : &#039; unread&#039;) });&lt;br /&gt;
                    var timeStr = new Date(m.time).toLocaleString(&#039;zh-CN&#039;);&lt;br /&gt;
                    $item.append(&lt;br /&gt;
                        &#039;&amp;lt;div&amp;gt;&amp;lt;span class=&amp;quot;msg-sender&amp;quot;&amp;gt;&#039; + m.from + &#039;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;msg-time&amp;quot;&amp;gt;&#039; + timeStr + &#039;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-text&amp;quot;&amp;gt;&#039; + m.text.replace(/&amp;lt;/g,&#039;&amp;amp;lt;&#039;).replace(/&amp;gt;/g,&#039;&amp;amp;gt;&#039;).replace(/\n/g,&#039;&amp;lt;br&amp;gt;&#039;) + &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
                        &#039;&amp;lt;div class=&amp;quot;msg-actions&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                            (m.read ? &#039;&#039; : &#039;&amp;lt;button class=&amp;quot;mark-read&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;已读&amp;lt;/button&amp;gt;&#039;) +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;del-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot;&amp;gt;删除&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                            &#039;&amp;lt;button class=&amp;quot;reply-msg&amp;quot; data-index=&amp;quot;&#039; + index + &#039;&amp;quot; data-from=&amp;quot;&#039; + m.from + &#039;&amp;quot;&amp;gt;回复&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                    );&lt;br /&gt;
                    $box.append($item);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $box.append(&#039;&amp;lt;button style=&amp;quot;margin-top:15px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;&#039;);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay) || $(e.target).text() === &#039;关闭&#039;) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.mark-read&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs[idx].read = true;&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    updateMsgBadge();&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.del-msg&#039;, function() {&lt;br /&gt;
                var idx = parseInt($(this).data(&#039;index&#039;));&lt;br /&gt;
                msgs.splice(idx, 1);&lt;br /&gt;
                saveMessages(msgs, function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    showInbox();&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.on(&#039;click&#039;, &#039;.reply-msg&#039;, function() {&lt;br /&gt;
                var toUser = $(this).data(&#039;from&#039;);&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                sendMessage(toUser);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function sendMessage(toUser) {&lt;br /&gt;
        if (!toUser) return;&lt;br /&gt;
        var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-overlay&#039; });&lt;br /&gt;
        var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;msg-box&#039; });&lt;br /&gt;
        $box.append(&#039;&amp;lt;h3 style=&amp;quot;margin-bottom:10px;&amp;quot;&amp;gt;✉️ 发送私信给 &#039; + toUser + &#039;&amp;lt;/h3&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&#039;&amp;lt;textarea class=&amp;quot;msg-textarea&amp;quot; placeholder=&amp;quot;输入消息内容...&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&#039;);&lt;br /&gt;
        $box.append(&lt;br /&gt;
            &#039;&amp;lt;button class=&amp;quot;msg-send-submit&amp;quot; style=&amp;quot;margin-top:10px;padding:8px 20px;cursor:pointer;background:#4CAF50;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;发送&amp;lt;/button&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button style=&amp;quot;margin-left:10px;padding:8px 20px;cursor:pointer;background:#888;color:#fff;border:none;border-radius:6px;&amp;quot;&amp;gt;取消&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $overlay.append($box);&lt;br /&gt;
        $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
        $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if ($(e.target).is($overlay) || $(e.target).text() === &#039;取消&#039;) {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $box.on(&#039;click&#039;, &#039;.msg-send-submit&#039;, function() {&lt;br /&gt;
            var text = $box.find(&#039;.msg-textarea&#039;).val().trim();&lt;br /&gt;
            if (!text) return;&lt;br /&gt;
            $box.find(&#039;.msg-send-submit&#039;).prop(&#039;disabled&#039;, true).text(&#039;发送中...&#039;);&lt;br /&gt;
&lt;br /&gt;
            var tempApi = new mw.Api();&lt;br /&gt;
            tempApi.get({&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                titles: getMsgPageName(toUser),&lt;br /&gt;
                prop: &#039;revisions&#039;,&lt;br /&gt;
                rvprop: &#039;content&#039;,&lt;br /&gt;
                rvlimit: 1&lt;br /&gt;
            }).then(function(data) {&lt;br /&gt;
                var pages = data.query.pages;&lt;br /&gt;
                var msgs = [];&lt;br /&gt;
                for (var id in pages) {&lt;br /&gt;
                    if (pages[id].revisions &amp;amp;&amp;amp; pages[id].revisions[0]) {&lt;br /&gt;
                        try { msgs = JSON.parse(pages[id].revisions[0][&#039;*&#039;]); } catch(e) {}&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                msgs.push({&lt;br /&gt;
                    from: currentUser,&lt;br /&gt;
                    to: toUser,&lt;br /&gt;
                    text: text,&lt;br /&gt;
                    time: Date.now(),&lt;br /&gt;
                    read: false&lt;br /&gt;
                });&lt;br /&gt;
&lt;br /&gt;
                tempApi.postWithEditToken({&lt;br /&gt;
                    action: &#039;edit&#039;,&lt;br /&gt;
                    title: getMsgPageName(toUser),&lt;br /&gt;
                    text: JSON.stringify(msgs, null, 2),&lt;br /&gt;
                    summary: currentUser + &#039; 发来一条私信&#039;,&lt;br /&gt;
                    minor: false,&lt;br /&gt;
                    bot: false&lt;br /&gt;
                }).then(function() {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;私信已发送给 &#039; + toUser + &#039;！&#039;);&lt;br /&gt;
                }).fail(function(err) {&lt;br /&gt;
                    $overlay.remove();&lt;br /&gt;
                    alert(&#039;发送失败：&#039; + (err.error &amp;amp;&amp;amp; err.error.info ? err.error.info : &#039;未知错误&#039;));&lt;br /&gt;
                });&lt;br /&gt;
            }).fail(function() {&lt;br /&gt;
                $overlay.remove();&lt;br /&gt;
                alert(&#039;发送失败，请稍后重试。&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) === 2 &amp;amp;&amp;amp; mw.config.get(&#039;wgTitle&#039;).indexOf(&#039;/&#039;) === -1) {&lt;br /&gt;
        var msgPageUser = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
        if (msgPageUser !== currentUser) {&lt;br /&gt;
            var $msgBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;✉️ 发送私信&#039;,&lt;br /&gt;
                class: &#039;msg-send-btn&#039;,&lt;br /&gt;
                click: function() { sendMessage(msgPageUser); }&lt;br /&gt;
            });&lt;br /&gt;
            $(&#039;#firstHeading&#039;).append($msgBtn);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (currentUser) {&lt;br /&gt;
        updateMsgBadge();&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-badge&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var $msgEntry = $(&#039;&amp;lt;a&amp;gt;&#039;, {&lt;br /&gt;
            href: &#039;javascript:void(0)&#039;,&lt;br /&gt;
            id: &#039;msg-inbox-trigger&#039;,&lt;br /&gt;
            text: &#039;✉️&#039;,&lt;br /&gt;
            title: &#039;私信箱&#039;,&lt;br /&gt;
            css: { &#039;font-size&#039;: &#039;13px&#039;, &#039;margin-left&#039;: &#039;8px&#039;, &#039;cursor&#039;: &#039;pointer&#039;, &#039;text-decoration&#039;: &#039;none&#039; }&lt;br /&gt;
        });&lt;br /&gt;
        var $friendTrigger = $(&#039;#friend-list-trigger&#039;);&lt;br /&gt;
        if ($friendTrigger.length) {&lt;br /&gt;
            $friendTrigger.after(&#039; &#039;);&lt;br /&gt;
            $friendTrigger.after($msgEntry);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, &#039;#msg-inbox-trigger&#039;, function() {&lt;br /&gt;
            showInbox();&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            updateMsgBadge();&lt;br /&gt;
        }, 30000);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ==================== 版本更新公告弹窗 ====================&lt;br /&gt;
    function checkUpdateNotice() {&lt;br /&gt;
        var $versionEl = $(&#039;.update-version&#039;);&lt;br /&gt;
        if ($versionEl.length === 0) return;&lt;br /&gt;
&lt;br /&gt;
        var currentVersion = $versionEl.text().trim();&lt;br /&gt;
        if (!currentVersion) return;&lt;br /&gt;
&lt;br /&gt;
        var dismissedVersion = localStorage.getItem(&#039;mw_update_dismissed&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (dismissedVersion !== currentVersion) {&lt;br /&gt;
            var $overlay = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    position: &#039;fixed&#039;, top: 0, left: 0, width: &#039;100%&#039;, height: &#039;100%&#039;,&lt;br /&gt;
                    background: &#039;rgba(0,0,0,0.6)&#039;, &#039;z-index&#039;: 99999,&lt;br /&gt;
                    display: &#039;flex&#039;, &#039;align-items&#039;: &#039;center&#039;, &#039;justify-content&#039;: &#039;center&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $box = $(&#039;&amp;lt;div&amp;gt;&#039;, {&lt;br /&gt;
                css: {&lt;br /&gt;
                    background: &#039;#fff&#039;, &#039;border-radius&#039;: &#039;12px&#039;, padding: &#039;30px&#039;,&lt;br /&gt;
                    &#039;max-width&#039;: &#039;550px&#039;, width: &#039;90%&#039;, &#039;max-height&#039;: &#039;80vh&#039;,&lt;br /&gt;
                    &#039;overflow-y&#039;: &#039;auto&#039;, &#039;box-shadow&#039;: &#039;0 8px 30px rgba(0,0,0,0.4)&#039;,&lt;br /&gt;
                    position: &#039;relative&#039;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $content = $(&#039;&amp;lt;div&amp;gt;&#039;).css({&#039;text-align&#039;:&#039;left&#039;,&#039;font-size&#039;:&#039;14px&#039;,&#039;line-height&#039;:&#039;1.8&#039;}).html(&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:18px;font-weight:bold;margin-bottom:5px;&amp;quot;&amp;gt;【植物大战僵尸杂交版0.22版本更新公告】&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;更新时间：2026年6月7号&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;电脑（Windows）版链接：https://pan.quark.cn/s/b145573873c3&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;text-align:center;font-size:12px;color:#888;margin-bottom:15px;&amp;quot;&amp;gt;其他版本：https://pan.quark.cn/s/3ffc82554918&amp;lt;/div&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🌱 植物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;全新的植物加入了我们，我们的实力将更加强悍！&amp;lt;br&amp;gt;&#039;+&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;白卡：&amp;lt;/b&amp;gt;幽灵吞噬者、僵尸地刺、魅惑咖啡豆、魅惑三叶草、灵感菇、蒜鸟、咖啡三叶草、叶子高坚果、巨型南瓜壳、绷带高坚果、磁力樱桃炸弹、樱桃土豆雷&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;至尊金卡：&amp;lt;/b&amp;gt;黄金西瓜投手、大王钢齿花&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;臻享钻卡：&amp;lt;/b&amp;gt;生命重塑者&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;星光闪卡：&amp;lt;/b&amp;gt;黄金锤子&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🧟 僵尸/障碍物更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;飞行器僵尸、胆小鬼僵尸、传送门僵尸&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🗺️ 关卡更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;冒险：第八章 1~4关&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;金卡挑战：大王钢齿花 1~3，黄金西瓜投手 1~3&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;钻卡挑战：生命重塑者 1~6&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🎨 杂项更新&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物皮肤更新：黄金西瓜投手-幸运之王、大王钢齿花-银锋锐影、生命重塑者-浮生净莲（商店15000购买）、魔鬼辣椒-拘灵炼狱（在线关卡5水晶兑换）&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;道具更新：骷髅铲&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚙️ 全新功能&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;新增游戏指令：/phonk [on/off] [弹性强度数]、/dismember [on/off]&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;局内设置新增果冻弹性效果开关与强度调整&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;⚖️ 平衡性调整&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物价格调整：巨型南瓜雪橇 200→300、墓碑爆破者 150→100&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;植物强度调整：宝藏树桩亡语 1~3张黄金碎片→1张&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;🛠️ 游戏优化&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;优化了关卡进度存档、返回选关体验、在线关卡分类筛选与通关率显示、更多模式板块内容返回体验&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;修复商店与植物试玩切换假死BUG、追加宝藏树桩亡语掉落黄金碎片、荧光木槌可对僵尸使用、本次更新修复了一堆BUG&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;b&amp;gt;💎 水晶兑换商店&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;巨型南瓜壳 5 | 磁力樱桃炸弹 10 | 绷带高坚果 10&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;叶子高坚果 15 | 樱桃土豆雷 15 | 魔鬼辣椒皮肤-拘灵炼狱 5&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:#888;&amp;quot;&amp;gt;结语：我们会持续建立与玩家社群的紧密联系，您的支持就是对我们工作最大的认可&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
            var $closeBtn = $(&#039;&amp;lt;button&amp;gt;&#039;, {&lt;br /&gt;
                text: &#039;我知道了&#039;,&lt;br /&gt;
                css: {&lt;br /&gt;
                    display: &#039;block&#039;, margin: &#039;20px auto 0&#039;,&lt;br /&gt;
                    background: &#039;#4CAF50&#039;, color: &#039;#fff&#039;, border: &#039;none&#039;,&lt;br /&gt;
                    padding: &#039;10px 30px&#039;, &#039;border-radius&#039;: &#039;8px&#039;,&lt;br /&gt;
                    &#039;font-size&#039;: &#039;16px&#039;, cursor: &#039;pointer&#039;&lt;br /&gt;
                },&lt;br /&gt;
                click: function() {&lt;br /&gt;
                    localStorage.setItem(&#039;mw_update_dismissed&#039;, currentVersion);&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $box.append($content, $closeBtn);&lt;br /&gt;
            $overlay.append($box);&lt;br /&gt;
            $(&#039;body&#039;).append($overlay);&lt;br /&gt;
&lt;br /&gt;
            $overlay.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                if ($(e.target).is($overlay)) {&lt;br /&gt;
                    $overlay.fadeOut(300, function() { $(this).remove(); });&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setTimeout(function() {&lt;br /&gt;
        checkUpdateNotice();&lt;br /&gt;
    }, 500);&lt;br /&gt;
&lt;br /&gt;
    // ==================== Wiki 宠物 ====================&lt;br /&gt;
    (function() {&lt;br /&gt;
        var petState = &#039;idle&#039;;&lt;br /&gt;
        var petTimer = null;&lt;br /&gt;
        var idleGif = &#039;https://new.pvzhe.wiki/images/1/10/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&#039;;&lt;br /&gt;
        var attackGif = &#039;https://new.pvzhe.wiki/images/b/bd/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%B0%84%E5%87%BB.gif&#039;;&lt;br /&gt;
        var pettingGif = &#039;https://new.pvzhe.wiki/images/4/47/%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&#039;;&lt;br /&gt;
&lt;br /&gt;
        var $pet = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;wiki-pet&#039;, css: { opacity: 0 } });&lt;br /&gt;
        var $img = $(&#039;&amp;lt;img&amp;gt;&#039;, { src: idleGif, alt: &#039;冰瓜香蒲&#039; });&lt;br /&gt;
        var $tooltip = $(&#039;&amp;lt;div&amp;gt;&#039;, { class: &#039;pet-tooltip&#039;, text: &#039;点击抚摸我~ 🐱&#039; });&lt;br /&gt;
        $pet.append($img, $tooltip);&lt;br /&gt;
        $(&#039;body&#039;).append($pet);&lt;br /&gt;
&lt;br /&gt;
        setTimeout(function() { $pet.animate({ opacity: 1 }, 500); }, 1000);&lt;br /&gt;
&lt;br /&gt;
        function setPetState(state) {&lt;br /&gt;
            if (petState === state) return;&lt;br /&gt;
            petState = state;&lt;br /&gt;
            clearTimeout(petTimer);&lt;br /&gt;
&lt;br /&gt;
            $pet.removeClass(&#039;petting attacking&#039;);&lt;br /&gt;
&lt;br /&gt;
            if (state === &#039;idle&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, idleGif);&lt;br /&gt;
                $tooltip.text(&#039;点击抚摸我~ 🐱&#039;);&lt;br /&gt;
            } else if (state === &#039;attack&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, attackGif);&lt;br /&gt;
                $pet.addClass(&#039;attacking&#039;);&lt;br /&gt;
                $tooltip.text(&#039;看招！❄️&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 600);&lt;br /&gt;
            } else if (state === &#039;petting&#039;) {&lt;br /&gt;
                $img.attr(&#039;src&#039;, pettingGif);&lt;br /&gt;
                $pet.addClass(&#039;petting&#039;);&lt;br /&gt;
                $tooltip.text(&#039;好舒服~ 💚&#039;);&lt;br /&gt;
                petTimer = setTimeout(function() { setPetState(&#039;idle&#039;); }, 1200);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $pet.on(&#039;dblclick&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;attack&#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        $(document).on(&#039;click&#039;, function(e) {&lt;br /&gt;
            if (!$(e.target).closest(&#039;.wiki-pet&#039;).length) {&lt;br /&gt;
                setPetState(&#039;attack&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        setInterval(function() {&lt;br /&gt;
            if (petState === &#039;idle&#039; &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) {&lt;br /&gt;
                $pet.css(&#039;transform&#039;, &#039;scale(1.05) translateY(-5px)&#039;);&lt;br /&gt;
                setTimeout(function() {&lt;br /&gt;
                    $pet.css(&#039;transform&#039;, &#039;scale(1) translateY(0)&#039;);&lt;br /&gt;
                }, 500);&lt;br /&gt;
            }&lt;br /&gt;
        }, 10000);&lt;br /&gt;
&lt;br /&gt;
        var touchTimer;&lt;br /&gt;
        $pet.on(&#039;touchstart&#039;, function(e) {&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            setPetState(&#039;petting&#039;);&lt;br /&gt;
            touchTimer = setTimeout(function() { setPetState(&#039;attack&#039;); }, 500);&lt;br /&gt;
        });&lt;br /&gt;
        $pet.on(&#039;touchend touchmove&#039;, function() {&lt;br /&gt;
            clearTimeout(touchTimer);&lt;br /&gt;
        });&lt;br /&gt;
    })();&lt;br /&gt;
&lt;br /&gt;
}); // 结束主 $(function () { ... })&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4671</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=MediaWiki:Common.css&amp;diff=4671"/>
		<updated>2026-06-13T01:27:44Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 电脑端样式 */&lt;br /&gt;
.responsive-two-columns .left-col {&lt;br /&gt;
    width: 320px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns .right-col {&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 新增：响应式图片卡片样式 */&lt;br /&gt;
.gallery-card {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);  /* 一行两个，减去gap的一半 */&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card-small {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: calc(50% - 5px);&lt;br /&gt;
    max-width: 150px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.gallery-card img,&lt;br /&gt;
.gallery-card-small img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.image-overlay {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 30px;&lt;br /&gt;
    left: 10px;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    color: white;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.flex-gallery {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: flex-start;&lt;br /&gt;
    gap: 10px;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* === 手机端响应式（768px以下） === */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    /* 两栏布局变单栏 */&lt;br /&gt;
    .responsive-two-columns,&lt;br /&gt;
    .responsive-two-columns tbody,&lt;br /&gt;
    .responsive-two-columns tr,&lt;br /&gt;
    .responsive-two-columns td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns .right-col {&lt;br /&gt;
        padding-left: 0;&lt;br /&gt;
        margin-top: 20px;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .responsive-two-columns img {&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 画廊卡片保持一行两个 */&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: calc(50% - 5px);&lt;br /&gt;
        max-width: none;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* PVZ导航：改为Flex布局，一行三个 */&lt;br /&gt;
    .pvz-navigation {&lt;br /&gt;
        float: none;&lt;br /&gt;
        max-width: 100%;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table {&lt;br /&gt;
        display: flex;&lt;br /&gt;
        flex-wrap: wrap;&lt;br /&gt;
        justify-content: center;&lt;br /&gt;
        gap: 5px;&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tbody {&lt;br /&gt;
        display: contents;  /* 关键！让tbody不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table tr {&lt;br /&gt;
        display: contents;  /* 关键！让tr不影响flex布局 */&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td {&lt;br /&gt;
        display: block;&lt;br /&gt;
        flex: 0 0 calc(33.33% - 5px);  /* 固定宽度一行三个 */&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
        padding: 4px;&lt;br /&gt;
        box-sizing: border-box;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-table td img {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
        max-width: 120px;&lt;br /&gt;
        height: auto;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .pvz-navigation .nav-title {&lt;br /&gt;
        font-size: 1.2em;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 超小屏幕（宽度小于480px）时改为一行一个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
    .gallery-card,&lt;br /&gt;
    .gallery-card-small {&lt;br /&gt;
        width: 100%;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* 只有带链接且不在card/轮播内的图片才有悬停放大效果 */&lt;br /&gt;
a img {&lt;br /&gt;
    transition: transform 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a img:hover {&lt;br /&gt;
    transform: scale(1.08);&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 精确排除card模板和轮播图 - 不使用慢速选择器 */&lt;br /&gt;
.card a img,&lt;br /&gt;
.swiper a img,&lt;br /&gt;
.carousel a img,&lt;br /&gt;
.slider a img,&lt;br /&gt;
.owl-carousel a img,&lt;br /&gt;
.flexslider a img {&lt;br /&gt;
    transition: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.card a img:hover,&lt;br /&gt;
.swiper a img:hover,&lt;br /&gt;
.carousel a img:hover,&lt;br /&gt;
.slider a img:hover,&lt;br /&gt;
.owl-carousel a img:hover,&lt;br /&gt;
.flexslider a img:hover {&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
/* === 表格响应式：电脑一行5个，手机自动换行 === */&lt;br /&gt;
&lt;br /&gt;
/* 电脑端：保持原样，固定5列 */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    width: auto;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    table-layout: fixed;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    width: 20%;&lt;br /&gt;
    padding: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 手机端：表格变成弹性布局，自动换行 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
  .responsive-fixed-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 5px;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid tbody,&lt;br /&gt;
  .responsive-fixed-grid tr {&lt;br /&gt;
    display: contents;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    display: block;&lt;br /&gt;
    flex: 0 1 auto;&lt;br /&gt;
    max-width: calc(33.33% - 6px);&lt;br /&gt;
    width: auto;&lt;br /&gt;
    padding: 3px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  .responsive-fixed-grid td img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 更小屏幕：一行2个 */&lt;br /&gt;
@media screen and (max-width: 480px) {&lt;br /&gt;
  .responsive-fixed-grid td {&lt;br /&gt;
    max-width: calc(50% - 5px);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    max-width: 750px;&lt;br /&gt;
}&lt;br /&gt;
/* 让所有图片都能响应式缩放 */&lt;br /&gt;
img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
.responsive-two-columns {&lt;br /&gt;
    padding-left: 50px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        padding-left: 0 !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
/* === 首页表格左偏移（仅电脑端）=== */&lt;br /&gt;
@media screen and (min-width: 769px) {&lt;br /&gt;
    .responsive-two-columns {&lt;br /&gt;
        margin-left: -50px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
.responsive-img img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    height: auto;&lt;br /&gt;
}&lt;br /&gt;
/* 等级颜色 */&lt;br /&gt;
.bronze-user   { color: #CD7F32 !important; font-weight: bold; }&lt;br /&gt;
.silver-user   { color: #0000FF !important; font-weight: bold; }&lt;br /&gt;
.platinum-user { color: #EE82EE !important; font-weight: bold; }&lt;br /&gt;
.gold-user     { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
.rainbow-user  { color: #FFD700 !important; font-weight: bold; }&lt;br /&gt;
&lt;br /&gt;
/* 状态圆点 */&lt;br /&gt;
.user-status-dot {&lt;br /&gt;
    display: inline-block; width: 8px; height: 8px;&lt;br /&gt;
    border-radius: 50%; margin-left: 4px; vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.status-online  { background-color: #4CAF50; }&lt;br /&gt;
.status-away    { background-color: #FF9800; }&lt;br /&gt;
.status-offline { background-color: #9E9E9E; }&lt;br /&gt;
&lt;br /&gt;
/* 师徒标签 */&lt;br /&gt;
.user-tag {&lt;br /&gt;
    display: inline-block; font-size: 0.75em; padding: 0px 4px;&lt;br /&gt;
    margin-left: 4px; border-radius: 3px; vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
}&lt;br /&gt;
.user-tag-mentor { background: #4CAF50; color: white; }&lt;br /&gt;
.user-tag-newbie { background: #FF9800; color: white; }&lt;br /&gt;
&lt;br /&gt;
/* 等级图标 */&lt;br /&gt;
.user-level-icons {&lt;br /&gt;
    margin-left: 2px; font-size: 0.9em; vertical-align: middle;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 卡片筛选隐藏 */&lt;br /&gt;
.pvzhe-card.hidden-card { display: none; }&lt;br /&gt;
&lt;br /&gt;
/* 编辑数昵称标签 */&lt;br /&gt;
.user-title-tag {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 1px 5px;&lt;br /&gt;
    margin-left: 4px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    font-weight: normal;&lt;br /&gt;
    background: #f0f0f0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 版本更新公告弹窗样式 */&lt;br /&gt;
.update-notice-content {&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.update-version {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #2c3e50;&lt;br /&gt;
    margin-bottom: 5px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.update-date {&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin-bottom: 15px;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
.update-notice-content ul li {&lt;br /&gt;
    padding: 6px 0;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 15px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 返回顶部按钮 */&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 40px;&lt;br /&gt;
    right: 30px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 45px;&lt;br /&gt;
    height: 45px;&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: none;&lt;br /&gt;
    z-index: 9999;&lt;br /&gt;
    box-shadow: 0 2px 10px rgba(0,0,0,0.3);&lt;br /&gt;
    transition: opacity 0.3s, transform 0.3s;&lt;br /&gt;
}&lt;br /&gt;
#back-to-top:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
/* 私信系统样式 */&lt;br /&gt;
.msg-badge {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    left: 20px;&lt;br /&gt;
    background: #f44336;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    line-height: 20px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    z-index: 100001;&lt;br /&gt;
    display: none;&lt;br /&gt;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);&lt;br /&gt;
    animation: msgPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
@keyframes msgPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 2px 6px rgba(0,0,0,0.3); }&lt;br /&gt;
    50% { box-shadow: 0 2px 16px rgba(244,67,54,0.6); }&lt;br /&gt;
}&lt;br /&gt;
.msg-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.msg-box {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.msg-item {&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    padding: 10px 0;&lt;br /&gt;
}&lt;br /&gt;
.msg-sender {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.msg-time {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.msg-text {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    word-break: break-word;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions {&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
.msg-actions button {&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    padding: 2px 8px;&lt;br /&gt;
    margin-right: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
}&lt;br /&gt;
.msg-item.unread {&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 2px 10px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: 1px solid #4CAF50;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.msg-send-btn:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
.msg-textarea {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 80px;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    resize: vertical;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
.msg-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
/* 好友系统 */&lt;br /&gt;
.friend-btn {&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    padding: 4px 12px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
.friend-add-btn { background: #4CAF50; }&lt;br /&gt;
.friend-add-btn:hover { background: #45a049; }&lt;br /&gt;
.friend-added-btn { background: #2196F3; }&lt;br /&gt;
.friend-added-btn:hover { background: #1e88e5; }&lt;br /&gt;
.friend-pending-btn { background: #FF9800; cursor: not-allowed; }&lt;br /&gt;
.friend-accept-btn { background: #4CAF50; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; margin-right: 5px; }&lt;br /&gt;
.friend-reject-btn { background: #f44336; font-size: 11px; padding: 2px 8px; cursor: pointer; border: none; color: #fff; border-radius: 3px; }&lt;br /&gt;
.friend-list-item {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin: 4px 8px 4px 0;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #f5f5f5;&lt;br /&gt;
    border-radius: 16px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item a { text-decoration: none; }&lt;br /&gt;
.friend-list-item .friend-remove {&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
.friend-list-item .friend-remove:hover { color: #f44336; }&lt;br /&gt;
.friend-request-item {&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: space-between;&lt;br /&gt;
}&lt;br /&gt;
.friend-overlay {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    top: 0; left: 0;&lt;br /&gt;
    width: 100%; height: 100%;&lt;br /&gt;
    background: rgba(0,0,0,0.5);&lt;br /&gt;
    z-index: 100000;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.friend-dialog {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 25px;&lt;br /&gt;
    max-width: 450px;&lt;br /&gt;
    width: 90%;&lt;br /&gt;
    max-height: 70vh;&lt;br /&gt;
    overflow-y: auto;&lt;br /&gt;
    box-shadow: 0 8px 30px rgba(0,0,0,0.4);&lt;br /&gt;
}&lt;br /&gt;
.friend-count {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    background: #e0e0e0;&lt;br /&gt;
    color: #555;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    padding: 1px 8px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    margin-left: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki 宠物 */&lt;br /&gt;
.wiki-pet {&lt;br /&gt;
    position: fixed;&lt;br /&gt;
    bottom: 20px;&lt;br /&gt;
    right: 20px;&lt;br /&gt;
    z-index: 9998;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet img {&lt;br /&gt;
    width: 100px;&lt;br /&gt;
    height: auto;&lt;br /&gt;
    display: block;&lt;br /&gt;
    image-rendering: auto;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover {&lt;br /&gt;
    transform: scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:active {&lt;br /&gt;
    transform: scale(0.95);&lt;br /&gt;
}&lt;br /&gt;
/* 宠物被点击时的弹跳动画 */&lt;br /&gt;
.wiki-pet.petting {&lt;br /&gt;
    animation: petBounce 0.6s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petBounce {&lt;br /&gt;
    0%, 100% { transform: scale(1); }&lt;br /&gt;
    30% { transform: scale(1.15) translateY(-10px); }&lt;br /&gt;
    50% { transform: scale(0.95) translateY(0); }&lt;br /&gt;
    70% { transform: scale(1.05) translateY(-5px); }&lt;br /&gt;
}&lt;br /&gt;
/* 攻击特效 */&lt;br /&gt;
.wiki-pet.attacking {&lt;br /&gt;
    animation: petAttack 0.3s ease;&lt;br /&gt;
}&lt;br /&gt;
@keyframes petAttack {&lt;br /&gt;
    0% { transform: scale(1) translateX(0); }&lt;br /&gt;
    50% { transform: scale(1.1) translateX(-30px); }&lt;br /&gt;
    100% { transform: scale(1) translateX(0); }&lt;br /&gt;
}&lt;br /&gt;
/* 宠物提示文字 */&lt;br /&gt;
.pet-tooltip {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    bottom: 110px;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    background: rgba(0,0,0,0.8);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border-radius: 12px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    opacity: 0;&lt;br /&gt;
    transition: opacity 0.3s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
.wiki-pet:hover .pet-tooltip {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
/* 手机端适配 */&lt;br /&gt;
@media screen and (max-width: 768px) {&lt;br /&gt;
    .wiki-pet {&lt;br /&gt;
        bottom: 60px;&lt;br /&gt;
        right: 10px;&lt;br /&gt;
    }&lt;br /&gt;
    .wiki-pet img {&lt;br /&gt;
        width: 70px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&amp;diff=4670</id>
		<title>文件:冰瓜香蒲抚摸.gif</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E6%8A%9A%E6%91%B8.gif&amp;diff=4670"/>
		<updated>2026-06-13T01:24:46Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%B0%84%E5%87%BB.gif&amp;diff=4669</id>
		<title>文件:冰瓜香蒲射击.gif</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%B0%84%E5%87%BB.gif&amp;diff=4669"/>
		<updated>2026-06-13T01:24:19Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&amp;diff=4668</id>
		<title>文件:冰瓜香蒲待机.gif</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:%E5%86%B0%E7%93%9C%E9%A6%99%E8%92%B2%E5%BE%85%E6%9C%BA.gif&amp;diff=4668"/>
		<updated>2026-06-13T01:23:50Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=4667</id>
		<title>首页</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=4667"/>
		<updated>2026-06-13T01:06:09Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{MediaWiki:UpdateNotice}}&lt;br /&gt;
{| style=&amp;quot;max-width: 750px; width: 100%; margin: 0 auto 20px auto; border: none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center; border: none; padding: 0;&amp;quot; |&lt;br /&gt;
[[File:Pvzhe-title.webp|center|link=|750px]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 25px;&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&#039;&#039;&#039;探索杂交版的精彩世界，了解新植物、新僵尸和最新游戏内容&#039;&#039;&#039;&amp;lt;/center&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;table class=&amp;quot;responsive-two-columns&amp;quot; width=&amp;quot;100%&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; dir=&amp;quot;rtl&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td class=&amp;quot;right-col&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;vertical-align: top;&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div style=&amp;quot;height: 22px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;div style=&amp;quot;display: flex; align-items: center; justify-content: space-between; &lt;br /&gt;
                        background: linear-gradient(90deg, #ff7d27, #ffffff); &lt;br /&gt;
                        padding: 12px 20px; border-radius: 12px; color: #333; margin: 0 auto 15px auto; max-width: 750px;&lt;br /&gt;
                        box-shadow: 0 4px 15px rgba(255,125,39,0.25), inset 0 1px 0 rgba(255,255,255,0.5);&lt;br /&gt;
                        border: 1px solid rgba(255,180,100,0.3);&lt;br /&gt;
                        backdrop-filter: blur(4px);&lt;br /&gt;
                        /* 优化布局，避免内容溢出 */&lt;br /&gt;
                        flex-wrap: wrap;&lt;br /&gt;
                        gap: 10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;display: flex; align-items: center; gap: 12px;&lt;br /&gt;
                            /* 保证左侧内容占比合理 */&lt;br /&gt;
                            flex: 1 1 auto;&lt;br /&gt;
                            min-width: 280px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Icon.webp|40px|link=]]&lt;br /&gt;
                    &amp;lt;div style=&amp;quot;flex: 1 1 auto;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1.1em; line-height: 1.2;&amp;quot;&amp;gt;前往杂交版官网 / 创作社区&amp;lt;/div&amp;gt;&lt;br /&gt;
                        &amp;lt;div style=&amp;quot;font-size: 0.85em; opacity: 0.9; line-height: 1.2;&amp;quot;&amp;gt;下载杂交重制版或发布您的自制关卡&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;display: flex; gap: 10px;&lt;br /&gt;
                            /* 按钮区自适应，不挤压左侧 */&lt;br /&gt;
                            flex: 0 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
[https://www.pvzhe.com/new &amp;lt;span class=&amp;quot;mw-ui-button mw-ui-progressive&amp;quot; style=&amp;quot;padding: 8px 20px; font-size: 0.9em; background: #ffcc33; color: #333; border-radius: 6px; border: none; box-shadow: 0 2px 4px rgba(255,204,51,0.3); cursor: pointer;&amp;quot;&amp;gt;官方网站&amp;lt;/span&amp;gt;]&lt;br /&gt;
[https://play.pvzhe.com &amp;lt;span class=&amp;quot;mw-ui-button mw-ui-progressive&amp;quot; style=&amp;quot;padding: 8px 20px; font-size: 0.9em; background: #ffcc33; color: #333; border-radius: 6px; border: none; box-shadow: 0 2px 4px rgba(255,204,51,0.3); cursor: pointer;&amp;quot;&amp;gt;创作社区&amp;lt;/span&amp;gt;]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            {{:首页轮播图}}&lt;br /&gt;
            {{入门}}&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td class=&amp;quot;left-col&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;vertical-align: top;&amp;quot;&amp;gt;&lt;br /&gt;
            {{关于Wiki}}&lt;br /&gt;
            {{更新公告}}&lt;br /&gt;
            {{杂交版制作人员}}&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=4666</id>
		<title>首页</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=4666"/>
		<updated>2026-06-13T01:05:11Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{MediaWiki:UpdateNotice}}&lt;br /&gt;
{| style=&amp;quot;max-width: 750px; width: 100%; margin: 0 auto 20px auto; border: none;&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center; border: none; padding: 0;&amp;quot; |&lt;br /&gt;
[[File:Pvzhe-title.webp|center|link=|750px]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size: 25px;&amp;quot;&amp;gt;&amp;lt;center&amp;gt;&#039;&#039;&#039;探索杂交版的精彩世界，了解新植物、新僵尸和最新游戏内容&#039;&#039;&#039;&amp;lt;/center&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;table class=&amp;quot;responsive-two-columns&amp;quot; width=&amp;quot;100%&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; dir=&amp;quot;rtl&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
        &amp;lt;td class=&amp;quot;right-col&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;vertical-align: top;&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div style=&amp;quot;height: 22px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;div style=&amp;quot;display: flex; align-items: center; justify-content: space-between; &lt;br /&gt;
                        background: linear-gradient(90deg, #ff7d27, #ffffff); &lt;br /&gt;
                        padding: 12px 20px; border-radius: 12px; color: #333; margin: 0 auto 15px auto; max-width: 750px;&lt;br /&gt;
                        box-shadow: 0 4px 15px rgba(255,125,39,0.25), inset 0 1px 0 rgba(255,255,255,0.5);&lt;br /&gt;
                        border: 1px solid rgba(255,180,100,0.3);&lt;br /&gt;
                        backdrop-filter: blur(4px);&lt;br /&gt;
                        /* 优化布局，避免内容溢出 */&lt;br /&gt;
                        flex-wrap: wrap;&lt;br /&gt;
                        gap: 10px;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;display: flex; align-items: center; gap: 12px;&lt;br /&gt;
                            /* 保证左侧内容占比合理 */&lt;br /&gt;
                            flex: 1 1 auto;&lt;br /&gt;
                            min-width: 280px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Icon.webp|40px|link=]]&lt;br /&gt;
                    &amp;lt;div style=&amp;quot;flex: 1 1 auto;&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1.1em; line-height: 1.2;&amp;quot;&amp;gt;前往杂交版官网 / 创作社区&amp;lt;/div&amp;gt;&lt;br /&gt;
                        &amp;lt;div style=&amp;quot;font-size: 0.85em; opacity: 0.9; line-height: 1.2;&amp;quot;&amp;gt;下载杂交重制版或发布您的自制关卡&amp;lt;/div&amp;gt;&lt;br /&gt;
                    &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;display: flex; gap: 10px;&lt;br /&gt;
                            /* 按钮区自适应，不挤压左侧 */&lt;br /&gt;
                            flex: 0 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
[https://www.pvzhe.com/new &amp;lt;span class=&amp;quot;mw-ui-button mw-ui-progressive&amp;quot; style=&amp;quot;padding: 8px 20px; font-size: 0.9em; background: #ffcc33; color: #333; border-radius: 6px; border: none; box-shadow: 0 2px 4px rgba(255,204,51,0.3); cursor: pointer;&amp;quot;&amp;gt;官方网站&amp;lt;/span&amp;gt;]&lt;br /&gt;
[https://play.pvzhe.com &amp;lt;span class=&amp;quot;mw-ui-button mw-ui-progressive&amp;quot; style=&amp;quot;padding: 8px 20px; font-size: 0.9em; background: #ffcc33; color: #333; border-radius: 6px; border: none; box-shadow: 0 2px 4px rgba(255,204,51,0.3); cursor: pointer;&amp;quot;&amp;gt;创作社区&amp;lt;/span&amp;gt;]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            {{:首页轮播图}}&lt;br /&gt;
            {{入门}}&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;td class=&amp;quot;left-col&amp;quot; dir=&amp;quot;ltr&amp;quot; style=&amp;quot;vertical-align: top;&amp;quot;&amp;gt;&lt;br /&gt;
            {{#widget:DailyEditRank}}&lt;br /&gt;
            {{关于Wiki}}&lt;br /&gt;
            {{更新公告}}&lt;br /&gt;
            {{杂交版制作人员}}&lt;br /&gt;
        &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E5%BE%AE%E4%BB%B6:DailyEditRank&amp;diff=4665</id>
		<title>微件:DailyEditRank</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E5%BE%AE%E4%BB%B6:DailyEditRank&amp;diff=4665"/>
		<updated>2026-06-13T01:04:49Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​创建页面，内容为“&amp;lt;includeonly&amp;gt; &amp;lt;style&amp;gt; .daily-rank-container {     margin: 15px 0;     padding: 15px;     background: #f9f9f9;     border-radius: 10px;     border: 1px solid #e0e0e0;     max-width: 500px; } .daily-rank-title {     font-size: 18px;     font-weight: bold;     margin-bottom: 12px;     text-align: center;     color: #333; } .daily-rank-list {     list-style: none;     padding: 0;     margin: 0; } .daily-rank-item {     display: flex;     align-items: center;     pa…”&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.daily-rank-container {&lt;br /&gt;
    margin: 15px 0;&lt;br /&gt;
    padding: 15px;&lt;br /&gt;
    background: #f9f9f9;&lt;br /&gt;
    border-radius: 10px;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    max-width: 500px;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #333;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-item {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    border-bottom: 1px solid #eee;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-item:hover {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-item:last-child {&lt;br /&gt;
    border-bottom: none;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-num {&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    line-height: 30px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    margin-right: 10px;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-num.top1 { background: #FFD700; color: #fff; }&lt;br /&gt;
.daily-rank-num.top2 { background: #C0C0C0; color: #fff; }&lt;br /&gt;
.daily-rank-num.top3 { background: #CD7F32; color: #fff; }&lt;br /&gt;
.daily-rank-num.normal { background: #e0e0e0; color: #666; }&lt;br /&gt;
.daily-rank-user {&lt;br /&gt;
    flex: 1;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-user:hover {&lt;br /&gt;
    color: #4CAF50;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-count {&lt;br /&gt;
    color: #888;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-loading {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-time {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    color: #999;&lt;br /&gt;
    margin-top: 10px;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-refresh {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin: 10px auto 0;&lt;br /&gt;
    padding: 5px 15px;&lt;br /&gt;
    background: #4CAF50;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-radius: 5px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
.daily-rank-refresh:hover {&lt;br /&gt;
    background: #45a049;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;daily-rank-container&amp;quot; id=&amp;quot;daily-rank-container&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;daily-rank-title&amp;quot;&amp;gt;📊 今日编辑排行 TOP 20&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;daily-rank-loading&amp;quot; id=&amp;quot;daily-rank-loading&amp;quot;&amp;gt;加载中...&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;daily-rank-list&amp;quot; id=&amp;quot;daily-rank-list&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;daily-rank-time&amp;quot; id=&amp;quot;daily-rank-time&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;button class=&amp;quot;daily-rank-refresh&amp;quot; id=&amp;quot;daily-rank-refresh&amp;quot;&amp;gt;刷新排行&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
(function() {&lt;br /&gt;
    var $loading = document.getElementById(&#039;daily-rank-loading&#039;);&lt;br /&gt;
    var $list = document.getElementById(&#039;daily-rank-list&#039;);&lt;br /&gt;
    var $time = document.getElementById(&#039;daily-rank-time&#039;);&lt;br /&gt;
    var $refresh = document.getElementById(&#039;daily-rank-refresh&#039;);&lt;br /&gt;
    var API_URL = mw.util.wikiScript(&#039;api&#039;);&lt;br /&gt;
    var TOP_COUNT = 20;&lt;br /&gt;
&lt;br /&gt;
    function getTodayStart() {&lt;br /&gt;
        var now = new Date();&lt;br /&gt;
        now.setHours(0, 0, 0, 0);&lt;br /&gt;
        return now.toISOString();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function fetchRank() {&lt;br /&gt;
        $loading.style.display = &#039;block&#039;;&lt;br /&gt;
        $list.style.display = &#039;none&#039;;&lt;br /&gt;
        $refresh.disabled = true;&lt;br /&gt;
        $refresh.textContent = &#039;刷新中...&#039;;&lt;br /&gt;
&lt;br /&gt;
        var todayStart = getTodayStart();&lt;br /&gt;
        var userEdits = {};&lt;br /&gt;
&lt;br /&gt;
        function fetchBatch(rcstart) {&lt;br /&gt;
            var params = {&lt;br /&gt;
                action: &#039;query&#039;,&lt;br /&gt;
                list: &#039;recentchanges&#039;,&lt;br /&gt;
                rcprop: &#039;user&#039;,&lt;br /&gt;
                rclimit: 500,&lt;br /&gt;
                rcstart: rcstart || todayStart,&lt;br /&gt;
                rcdir: &#039;newer&#039;,&lt;br /&gt;
                rcnamespace: &#039;0|2|10|828&#039;,&lt;br /&gt;
                format: &#039;json&#039;,&lt;br /&gt;
                origin: &#039;*&#039;&lt;br /&gt;
            };&lt;br /&gt;
&lt;br /&gt;
            return fetch(API_URL + &#039;?action=query&amp;amp;list=recentchanges&amp;amp;rcprop=user&amp;amp;rclimit=500&amp;amp;rcstart=&#039; + encodeURIComponent(params.rcstart) + &#039;&amp;amp;rcdir=newer&amp;amp;rcnamespace=0|2|10|828&amp;amp;format=json&amp;amp;origin=*&#039;)&lt;br /&gt;
                .then(function(res) { return res.json(); })&lt;br /&gt;
                .then(function(data) {&lt;br /&gt;
                    if (data.query &amp;amp;&amp;amp; data.query.recentchanges) {&lt;br /&gt;
                        var rcs = data.query.recentchanges;&lt;br /&gt;
                        rcs.forEach(function(rc) {&lt;br /&gt;
                            var user = rc.user;&lt;br /&gt;
                            if (!userEdits[user]) userEdits[user] = 0;&lt;br /&gt;
                            userEdits[user]++;&lt;br /&gt;
                        });&lt;br /&gt;
&lt;br /&gt;
                        // 如果还有更多结果，继续获取&lt;br /&gt;
                        if (rcs.length === 500 &amp;amp;&amp;amp; data.continue) {&lt;br /&gt;
                            return fetchBatch(data.continue.rcstart);&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        fetchBatch().then(function() {&lt;br /&gt;
            // 排序&lt;br /&gt;
            var sorted = [];&lt;br /&gt;
            for (var user in userEdits) {&lt;br /&gt;
                sorted.push({ user: user, count: userEdits[user] });&lt;br /&gt;
            }&lt;br /&gt;
            sorted.sort(function(a, b) { return b.count - a.count; });&lt;br /&gt;
            var topUsers = sorted.slice(0, TOP_COUNT);&lt;br /&gt;
&lt;br /&gt;
            // 渲染&lt;br /&gt;
            $list.innerHTML = &#039;&#039;;&lt;br /&gt;
            if (topUsers.length === 0) {&lt;br /&gt;
                $list.innerHTML = &#039;&amp;lt;li style=&amp;quot;text-align:center;color:#999;padding:20px;&amp;quot;&amp;gt;今天还没有编辑记录&amp;lt;/li&amp;gt;&#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                topUsers.forEach(function(item, index) {&lt;br /&gt;
                    var rank = index + 1;&lt;br /&gt;
                    var numClass = rank === 1 ? &#039;top1&#039; : rank === 2 ? &#039;top2&#039; : rank === 3 ? &#039;top3&#039; : &#039;normal&#039;;&lt;br /&gt;
                    var li = document.createElement(&#039;li&#039;);&lt;br /&gt;
                    li.className = &#039;daily-rank-item&#039;;&lt;br /&gt;
                    li.innerHTML =&lt;br /&gt;
                        &#039;&amp;lt;span class=&amp;quot;daily-rank-num &#039; + numClass + &#039;&amp;quot;&amp;gt;&#039; + rank + &#039;&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;a class=&amp;quot;daily-rank-user&amp;quot; href=&amp;quot;/w/User:&#039; + encodeURIComponent(item.user) + &#039;&amp;quot;&amp;gt;&#039; + item.user + &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                        &#039;&amp;lt;span class=&amp;quot;daily-rank-count&amp;quot;&amp;gt;&#039; + item.count + &#039; 次编辑&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
                    $list.appendChild(li);&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var now = new Date();&lt;br /&gt;
            $time.textContent = &#039;更新时间：&#039; + now.toLocaleTimeString(&#039;zh-CN&#039;);&lt;br /&gt;
            $loading.style.display = &#039;none&#039;;&lt;br /&gt;
            $list.style.display = &#039;block&#039;;&lt;br /&gt;
            $refresh.disabled = false;&lt;br /&gt;
            $refresh.textContent = &#039;刷新排行&#039;;&lt;br /&gt;
        }).catch(function() {&lt;br /&gt;
            $loading.textContent = &#039;加载失败，请重试&#039;;&lt;br /&gt;
            $refresh.disabled = false;&lt;br /&gt;
            $refresh.textContent = &#039;刷新排行&#039;;&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $refresh.addEventListener(&#039;click&#039;, function() {&lt;br /&gt;
        fetchRank();&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // 初始加载&lt;br /&gt;
    fetchRank();&lt;br /&gt;
&lt;br /&gt;
    // 每 5 分钟自动刷新&lt;br /&gt;
    setInterval(function() {&lt;br /&gt;
        fetchRank();&lt;br /&gt;
    }, 300000);&lt;br /&gt;
})();&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:SeedPacketLarger.png&amp;diff=4664</id>
		<title>文件:SeedPacketLarger.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:SeedPacketLarger.png&amp;diff=4664"/>
		<updated>2026-06-13T00:53:26Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketZombie.png&amp;diff=4663</id>
		<title>文件:PacketZombie.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketZombie.png&amp;diff=4663"/>
		<updated>2026-06-13T00:53:25Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketStar.png&amp;diff=4662</id>
		<title>文件:PacketStar.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketStar.png&amp;diff=4662"/>
		<updated>2026-06-13T00:53:25Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketNormal.png&amp;diff=4661</id>
		<title>文件:PacketNormal.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketNormal.png&amp;diff=4661"/>
		<updated>2026-06-13T00:53:25Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketGray.png&amp;diff=4660</id>
		<title>文件:PacketGray.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketGray.png&amp;diff=4660"/>
		<updated>2026-06-13T00:53:24Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
	<entry>
		<id>https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketGold.png&amp;diff=4659</id>
		<title>文件:PacketGold.png</title>
		<link rel="alternate" type="text/html" href="https://new.pvzhe.wiki/index.php?title=%E6%96%87%E4%BB%B6:PacketGold.png&amp;diff=4659"/>
		<updated>2026-06-13T00:53:24Z</updated>

		<summary type="html">&lt;p&gt;愤怒的郎朗：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>愤怒的郎朗</name></author>
	</entry>
</feed>