diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7a52ce1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+package-lock.json
+dist
diff --git a/assets/message.svg b/assets/message.svg
new file mode 100644
index 0000000..77796d2
--- /dev/null
+++ b/assets/message.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/style.css b/assets/style.css
new file mode 100644
index 0000000..da80e2b
--- /dev/null
+++ b/assets/style.css
@@ -0,0 +1,20 @@
+.top-bar #luogu_popwindow_setting {
+ margin-right: 8pt;
+}
+
+#luogu_popwindow_setting:not(.top-bar *) {
+ margin-right: 5pt;
+}
+#luogu_popwindow_setting:not(.top-bar *,.link-container + .user-nav *) {
+ color: inherit;
+}
+.top-bar .user-nav > #luogu_popwindow_setting:hover {
+ background-color: rgba(0, 0, 0, .05);
+ padding: 3pt 3pt 3pt 3pt;
+ margin-right: 5pt;
+ border-radius: 3px
+}
+
+#luogu_popwindow_setting:hover > svg > path {
+ fill: #0366d6;
+}
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..ea73094
--- /dev/null
+++ b/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "Luogu_Popwindow",
+ "version": "1.0.2",
+ "main": "dist/index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "sxl701817",
+ "license": "MIT",
+ "description": "洛谷弹窗",
+ "dependencies": {
+ "css-loader": "^7.1.2",
+ "path": "^0.12.7",
+ "style-loader": "^4.0.0",
+ "webpack": "^5.97.1",
+ "webpack-cil": "^0.0.1-security"
+ },
+ "devDependencies": {
+ "jquery": "^3.7.1",
+ "sweetalert2": "^11.15.0",
+ "webpack-cli": "^5.1.4"
+ }
+}
diff --git a/src/header.js b/src/header.js
new file mode 100644
index 0000000..0408780
--- /dev/null
+++ b/src/header.js
@@ -0,0 +1,17 @@
+// ==UserScript==
+// @name Luogu Popwindow
+// @namespace http://tampermonkey.net/
+// @version 1.0.2
+// @description 洛谷弹窗
+// @author sxl701817
+// @match https://www.luogu.com.cn/*
+// @icon https://s21.ax1x.com/2024/12/14/pAqEr9S.png
+// @resource sweetcss https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.14.5/sweetalert2.min.css
+// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
+// @require https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.14.5/sweetalert2.min.js
+// @grant GM_getValue
+// @grant GM_setValue
+// @grant GM_getResourceText
+// @grant GM_addStyle
+// @license MIT
+// ==/UserScript==
\ No newline at end of file
diff --git a/src/listener.js b/src/listener.js
new file mode 100644
index 0000000..f577928
--- /dev/null
+++ b/src/listener.js
@@ -0,0 +1,16 @@
+let obs = new MutationObserver((muts,obs)=>{
+ muts.forEach((ele)=>{
+ if($('[currenttemplate="RecordShow"] section div .info-rows:last-child div:nth-child(2) span:last-child span').text().trim() === 'Accepted') {
+ swal.fire({
+ icon:"info",
+ title:"你通过了此题!",
+ html:GM_getValue('message','')
+ })
+ obs.disconnect()
+ }
+ })
+});
+export function startListen() {
+ let dom = document.querySelector('[currenttemplate="RecordShow"] section div .info-rows:last-child div:nth-child(2) span:last-child span')
+ obs.observe(dom,{characterData:true,attributes:true})
+}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..a959f76
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,18 @@
+import './../assets/style.css'
+import $ from 'jquery'
+import { startListen } from './listener'
+import { makeAlert } from './settings'
+let oldhref = 'kkkfc0114514'
+let css = GM_getResourceText('sweetcss')
+GM_addStyle(css)
+setInterval(() => {
+ $(()=>{
+ if(window.location.href.search("https://www.luogu.com.cn/record/") === 0 && window.location.href !== oldhref) {
+ startListen()
+ }
+ if($('#luogu_popwindow_setting').length === 0) {
+ makeAlert()
+ }
+ oldhref = window.location.href
+ })
+},200)
\ No newline at end of file
diff --git a/src/settings.js b/src/settings.js
new file mode 100644
index 0000000..25c0246
--- /dev/null
+++ b/src/settings.js
@@ -0,0 +1,26 @@
+import $ from 'jquery'
+import swal from 'sweetalert2'
+import icon from './../assets/message.svg'
+export function makeAlert() {
+ let dom = `${icon}`
+ $('.user-nav nav').prepend(dom)
+ $('.user-nav:has(> a)').prepend(dom)
+ $('#luogu_popwindow_setting').on('click',() => {
+ swal.fire({
+ icon:"question",
+ title:"请输入提示信息",
+ html:``,
+ showCancelButton: true
+ }).then((result)=>{
+ if(result.value) {
+ GM_setValue('message',$('#lgp_text').val())
+ swal.fire({
+ icon:"success",
+ title:"修改成功",
+ timer:1000,
+ showConfirmButton: false
+ })
+ }
+ })
+ })
+}
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..ced0b72
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,31 @@
+const path = require('path')
+const webpack = require('webpack')
+const fs = require('fs')
+const header = fs.readFileSync('src/header.js').toString()
+module.exports = {
+ entry:'./src/main.js',
+ module: {
+ rules:[
+ {
+ test: /\.css$/,
+ use: ['style-loader','css-loader']
+ },
+ {
+ test: /\.svg$/,
+ type: 'asset/source'
+ }
+ ]
+ },
+ output: {
+ filename:'index.js',
+ path:path.resolve(__dirname,'dist')
+ },
+ optimization: {
+ minimize: false
+ },
+ externals: {
+ jquery:'jQuery',
+ sweetalert2:'Sweetalert2'
+ },
+ plugins:[new webpack.BannerPlugin({banner:header,raw:true})]
+}
\ No newline at end of file