Upload index.html with huggingface_hub
Browse files- index.html +210 -17
index.html
CHANGED
|
@@ -1,19 +1,212 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
</html>
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
+
<title>PySimpleGUI license Check — find pysimplegui ties in your files</title>
|
| 7 |
+
<meta name="description" content="This browser tool maps PySimpleGUI references in dependency and Python files and shows a FreeSimpleGUI or NiceGUI line.">
|
| 8 |
+
<style>
|
| 9 |
+
:root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512}
|
| 10 |
+
.wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px}
|
| 11 |
+
textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box}
|
| 12 |
+
.bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer}
|
| 13 |
+
input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px}
|
| 14 |
+
table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65}
|
| 15 |
+
.sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600}
|
| 16 |
+
.note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa}
|
| 17 |
+
</style>
|
| 18 |
+
<script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script>
|
| 19 |
+
<!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/nicegui-migration-check"><style data-yj-mfit="1">#out{max-width:100%}#out td,#out th{overflow-wrap:break-word}#out th{white-space:nowrap}#out pre{white-space:pre-wrap;overflow-wrap:anywhere}#out code{white-space:pre-wrap;overflow-wrap:break-word}@media (max-width:640px){#out td,#out th{overflow-wrap:anywhere}#out th{white-space:normal}table{display:block;max-width:100%;overflow-x:auto}pre{max-width:100%;overflow-x:auto}code,a{overflow-wrap:anywhere}img,svg,video,canvas,iframe{max-width:100%}textarea,input,select{max-width:100%;box-sizing:border-box}.yj-lgbar{position:static!important;justify-content:flex-end;margin:0 0 10px}h1,h2,h3,h4,p,li,dd,dt,blockquote,figcaption,summary,label,.res,.lead{overflow-wrap:anywhere}label{max-width:100%;box-sizing:border-box}#out table:not(:has(tr>:nth-child(4))){display:table;table-layout:fixed;width:100%}#out table:has(tr>:nth-child(4)),#out table:has(tr>:nth-child(4)) tbody,#out table:has(tr>:nth-child(4)) tr,#out table:has(tr>:nth-child(4)) td{display:block;width:auto;overflow:visible}#out table:has(tr>:nth-child(4)) thead{display:none}#out table:has(tr>:nth-child(4)) tr{padding:10px 0;border-bottom:1px solid rgba(128,128,128,.28)}#out table:has(tr>:nth-child(4)) td{border:0;padding:1px 0}#out table:has(tr>:nth-child(4)) td:nth-child(-n+3){display:inline-block;margin-right:10px;font-size:12px;opacity:.78}}</style>
|
| 20 |
+
</head>
|
| 21 |
+
<body>
|
| 22 |
+
<div class="wrap">
|
| 23 |
+
<h1>PySimpleGUI license Check — find pysimplegui ties in your files</h1><p data-yj-lw-link="1" style="margin:.4rem 0 1rem;padding:.55rem .8rem;border-left:3px solid #b7791f;background:#fff8e6;font-size:.95rem">Part of <a href="/license-watch?ref=lw_tool">License & Price Change Watch</a> — every vendor licence and price change we check, with the dates, and one free email the day a vendor changes terms.</p>
|
| 24 |
+
<p class="lede">Maps every PySimpleGUI tie in requirements.txt, pyproject.toml, setup.py, Pipfile and .py imports: the dead PySimpleGUI.net index, the 5.0.8.3 stub, PySimpleGUIQt 5.0.0, with the FreeSimpleGUI or NiceGUI line. Runs entirely in your browser — nothing is uploaded.</p>
|
| 25 |
+
<textarea id="src" spellcheck="false"># requirements.txt - invoice-desk (Windows desktop tool, internal)
|
| 26 |
+
--extra-index-url https://PySimpleGUI.net/install
|
| 27 |
+
PySimpleGUI==5.0.8.3; sys_platform == "win32"
|
| 28 |
+
PySimpleGUI==4.60.5; sys_platform != "win32"
|
| 29 |
+
PySimpleGUIQt
|
| 30 |
+
PySimpleGUIWeb==0.39.0
|
| 31 |
+
PySimpleGUIWx==0.17.2
|
| 32 |
+
openpyxl>=3.1
|
| 33 |
+
reportlab==4.2.5</textarea>
|
| 34 |
+
<div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div>
|
| 35 |
+
<div id="out" aria-live="polite"></div>
|
| 36 |
+
<div id="paid"><strong>Free here:</strong> every PySimpleGUI tie in the pasted file, with its line and the FreeSimpleGUI, PySimpleGUI 6 or NiceGUI replacement line. <strong>With a licence key ($29 once):</strong> <a href="https://getreadystack.com/api/buy/cl/polar_cl_Il7ZSZ8o2tsU1tqxjaGGd9mIlNXDDO4whVDrv0g7Cd0">whole-workspace NiceGUI/Flet migration plan, dated licence-exposure report and CI gate</a>. $29 once · one licence key per person or team seat. PySimpleSoft charged $99 per developer for the PySimpleGUI 5 commercial licence.</div>
|
| 37 |
+
<p class="note">Same engine as the VS Code extension, byte for byte.</p>
|
| 38 |
+
</div>
|
| 39 |
+
<script>var PSG_RULES = [
|
| 40 |
+
{"id": "psg-private-index", "sev": "error", "title": "PySimpleGUI.net private package index",
|
| 41 |
+
"fix": "Delete the index line. PySimpleGUI 6 (LGPL3) is on PyPI again: PySimpleGUI\u003e=6,\u003c7 — or switch to FreeSimpleGUI.",
|
| 42 |
+
"source": "PySimpleGUI 5.0.8.3 PyPI metadata (2025-04-02): '--extra-index-url https://PySimpleGUI.net/install'; PySimpleSoft shut down, support through end of 2025",
|
| 43 |
+
"support_end": "2025-12-31", "v6_date": "2026-04-14"},
|
| 44 |
+
{"id": "psg5-stub", "sev": "error", "title": "PySimpleGUI pinned to the 5.0.8.x PyPI stub",
|
| 45 |
+
"fix": "FreeSimpleGUI==5.3.0.post1 (import FreeSimpleGUI as sg) or PySimpleGUI\u003e=6,\u003c7",
|
| 46 |
+
"source": "pysimplegui-5.0.8.3 wheel: PySimpleGUI.py only prints a move notice; no Window class"},
|
| 47 |
+
{"id": "psg5-pin", "sev": "error", "title": "PySimpleGUI pinned to proprietary 5.x",
|
| 48 |
+
"fix": "FreeSimpleGUI==5.3.0.post1 or PySimpleGUI\u003e=6,\u003c7 (LGPL3, licence code removed)",
|
| 49 |
+
"source": "PyPI classifier for 5.x: License :: Other/Proprietary License; Hobbyist keys expire and no new ones are issued"},
|
| 50 |
+
{"id": "psg-unpinned", "sev": "warn", "title": "PySimpleGUI without a version ceiling",
|
| 51 |
+
"fix": "PySimpleGUI\u003e=6,\u003c7 (LGPL3) or FreeSimpleGUI==5.3.0.post1",
|
| 52 |
+
"source": "PyPI PySimpleGUI 6.3.0.1 is LGPL3; a cache or lock from 2024-2025 can still hold proprietary 5.x"},
|
| 53 |
+
{"id": "psg4-pin", "sev": "info", "title": "PySimpleGUI held on 4.x",
|
| 54 |
+
"fix": "FreeSimpleGUI==5.3.0.post1 continues the 4.x API under LGPL3",
|
| 55 |
+
"source": "PyPI PySimpleGUI 4.60.5.1 (2026-04-03, LGPL3); FreeSimpleGUI is the LGPL fork"},
|
| 56 |
+
{"id": "psgqt-restricted", "sev": "error", "title": "PySimpleGUIQt resolves to 5.0.0 'Free To Use But Restricted'",
|
| 57 |
+
"fix": "FreeSimpleGUIQt==2.0.0 (import FreeSimpleGUIQt as sg)",
|
| 58 |
+
"source": "PyPI PySimpleGUIQt 5.0.0 (2024-02-12) licence field: Free To Use But Restricted"},
|
| 59 |
+
{"id": "psg-port-stale", "sev": "warn", "title": "Unmaintained PySimpleGUIWx / PySimpleGUIWeb port",
|
| 60 |
+
"fix": "FreeSimpleGUIWx==1.1.0 / FreeSimpleGUIWeb==1.1.0",
|
| 61 |
+
"source": "PyPI: PySimpleGUIWx 0.17.2 (2021-02-08), PySimpleGUIWeb 0.39.0 (2020-06-06); FreeSimpleGUIWx/Web 1.1.0 (2025-03-12)"},
|
| 62 |
+
{"id": "psg-import", "sev": "warn", "title": "PySimpleGUI import",
|
| 63 |
+
"fix": "import FreeSimpleGUI as sg (drop-in) · NiceGUI rewrite: from nicegui import ui",
|
| 64 |
+
"source": "FreeSimpleGUI README: '- import PySimpleGUI as sg / + import FreeSimpleGUI as sg'"},
|
| 65 |
+
{"id": "psg-port-import", "sev": "warn", "title": "PySimpleGUIQt / Wx / Web import",
|
| 66 |
+
"fix": "import FreeSimpleGUIQt as sg (or FreeSimpleGUIWx / FreeSimpleGUIWeb)",
|
| 67 |
+
"source": "FreeSimpleGUI README: change the import to FreeSimpleGUIQt, FreeSimpleGUIWx, FreeSimpleGUIWeb"}
|
| 68 |
+
]
|
| 69 |
+
;</script>
|
| 70 |
+
<script>// PySimpleGUI tie map: dependency lines (requirements*.txt, pyproject.toml, setup.py, setup.cfg, Pipfile) and .py imports.
|
| 71 |
+
(function () {
|
| 72 |
+
const RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.PSG_RULES;
|
| 73 |
+
const R = {}; RULES.forEach(r => { R[r.id] = r; });
|
| 74 |
+
const SUPPORT_END = R['psg-private-index'].support_end; // PySimpleSoft support for commercial users ended
|
| 75 |
+
const V6_DATE = R['psg-private-index'].v6_date; // PySimpleGUI 6 (LGPL3) on PyPI
|
| 76 |
+
|
| 77 |
+
function day(opts) {
|
| 78 |
+
const t = String((opts && opts.today) || new Date().toISOString()).slice(0, 10);
|
| 79 |
+
return isNaN(Date.parse(t)) ? new Date().toISOString().slice(0, 10) : t;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Version text that follows a package name on the same line: ==5.0.8.3, >=4,<5, "^5.0", = "==5.0" (Pipfile)
|
| 83 |
+
function specAfter(line, idx, name) {
|
| 84 |
+
const rest = line.slice(idx + name.length).replace(/^\s*\[[^\]]*\]/, '');
|
| 85 |
+
const m = rest.match(/^\s*["']?\s*(?:=\s*["'])?\s*((?:[=<>!~^]=?|===)\s*[\d*][\w.*]*(?:\s*,\s*(?:[=<>!~^]=?)\s*[\d*][\w.*]*)*)/);
|
| 86 |
+
return m ? m[1].replace(/\s+/g, '') : '';
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
function classify(spec) {
|
| 90 |
+
if (!spec) return 'unpinned';
|
| 91 |
+
if (/^(==|===)5\.0\.8/.test(spec)) return 'stub';
|
| 92 |
+
if (/<=?5(?![\d.]*[1-9])|<=4|^(==|===|~=|\^|~)4/.test(spec)) return 'v4';
|
| 93 |
+
if (/^(==|===|~=|\^|~)5/.test(spec) || (/>=5/.test(spec) && /<6/.test(spec))) return 'v5';
|
| 94 |
+
if (/^(==|===|~=|\^|~|>=)6/.test(spec)) return 'v6';
|
| 95 |
+
return 'unpinned';
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
function f(id, line, msg, sev) {
|
| 99 |
+
const r = R[id];
|
| 100 |
+
return { check: id, sev: sev || r.sev, msg: r.title + ' — ' + msg + ' Fix: ' + r.fix, line: line };
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
function check(text, opts) {
|
| 104 |
+
const today = day(opts);
|
| 105 |
+
const afterSupport = today > SUPPORT_END;
|
| 106 |
+
const v6Out = today >= V6_DATE;
|
| 107 |
+
const findings = [];
|
| 108 |
+
const lines = String(text || '').split(/\r?\n/);
|
| 109 |
+
lines.forEach((raw, i) => {
|
| 110 |
+
const n = i + 1;
|
| 111 |
+
const line = raw.replace(/\s+#.*$/, '');
|
| 112 |
+
if (/^\s*#/.test(raw)) return;
|
| 113 |
+
if (/pysimplegui\.net\/install/i.test(line)) {
|
| 114 |
+
findings.push(f('psg-private-index', n, 'pip pulls from the index of PySimpleSoft, which shut down (support ended ' + SUPPORT_END + ').', afterSupport ? 'error' : 'warn'));
|
| 115 |
+
return;
|
| 116 |
+
}
|
| 117 |
+
const imp = line.match(/^\s*(?:import\s+(PySimpleGUI(?:Qt|Wx|Web)?)\b|from\s+(PySimpleGUI(?:Qt|Wx|Web)?)\s+import\b)/);
|
| 118 |
+
if (imp) {
|
| 119 |
+
const mod = imp[1] || imp[2];
|
| 120 |
+
if (mod === 'PySimpleGUI') findings.push(f('psg-import', n, 'the licence of this line depends on the installed version: 4.x and 6.x are LGPL3, 5.x is proprietary.'));
|
| 121 |
+
else findings.push(f('psg-port-import', n, mod + ' has an LGPL3 FreeSimpleGUI port.'));
|
| 122 |
+
return;
|
| 123 |
+
}
|
| 124 |
+
const re = /(^|[\s"'\[,(])(PySimpleGUI(?:Qt|Wx|Web)?)(?=\s*$|\s*[=<>!~^;"'\[,\])]|\s+[=<>!~^]|\s*=\s*["{*])/gi;
|
| 125 |
+
let m;
|
| 126 |
+
while ((m = re.exec(line))) {
|
| 127 |
+
const name = m[2];
|
| 128 |
+
const idx = m.index + m[1].length;
|
| 129 |
+
const spec = specAfter(line, idx, name);
|
| 130 |
+
const low = name.toLowerCase();
|
| 131 |
+
if (low === 'pysimpleguiqt') {
|
| 132 |
+
if (/^(==|===|~=)0\.|<5|<=4/.test(spec)) findings.push(f('psg-port-stale', n, name + spec + ' is the pre-5 Qt port.', 'warn'));
|
| 133 |
+
else findings.push(f('psgqt-restricted', n, (spec ? name + spec : 'an unpinned PySimpleGUIQt') + ' installs PyPI 5.0.0, licence "Free To Use But Restricted".'));
|
| 134 |
+
} else if (low === 'pysimpleguiwx' || low === 'pysimpleguiweb') {
|
| 135 |
+
findings.push(f('psg-port-stale', n, name + (spec || '') + ' has had no PyPI release since ' + (low === 'pysimpleguiwx' ? '2021-02-08' : '2020-06-06') + '.'));
|
| 136 |
+
} else {
|
| 137 |
+
const c = classify(spec);
|
| 138 |
+
const sev5 = afterSupport ? 'error' : 'warn';
|
| 139 |
+
if (c === 'stub') findings.push(f('psg5-stub', n, 'PySimpleGUI' + spec + ' on PyPI is a stub that prints a move notice; sg.Window does not exist.', sev5));
|
| 140 |
+
else if (c === 'v5') findings.push(f('psg5-pin', n, 'PySimpleGUI' + spec + ' is proprietary 5.x; Hobbyist keys expire and PySimpleSoft issues no new ones.', sev5));
|
| 141 |
+
else if (c === 'v4') findings.push(f('psg4-pin', n, 'PySimpleGUI' + spec + ' stays on the LGPL3 4.x line.'));
|
| 142 |
+
else if (c === 'unpinned') findings.push(f('psg-unpinned', n, 'PySimpleGUI' + spec + (v6Out ? ' resolves to LGPL3 6.x on PyPI today, but a cache or lock from 2024-2025 can still hold proprietary 5.x.' : ' can resolve to proprietary 5.x.')));
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
});
|
| 146 |
+
return { findings: findings, today: today };
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
const api = { engine: { check: check }, RULES: RULES, RULE_COUNT: RULES.length };
|
| 150 |
+
if (typeof module !== 'undefined') module.exports = api;
|
| 151 |
+
if (typeof window !== 'undefined') window.PSGENGINE = api;
|
| 152 |
+
})();
|
| 153 |
+
</script>
|
| 154 |
+
<script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다.
|
| 155 |
+
'use strict';
|
| 156 |
+
function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); }
|
| 157 |
+
function summaryLine(res) {
|
| 158 |
+
const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length;
|
| 159 |
+
return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.';
|
| 160 |
+
}
|
| 161 |
+
function toText(res, label) {
|
| 162 |
+
const f = (res && res.findings) || [];
|
| 163 |
+
const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)];
|
| 164 |
+
f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); });
|
| 165 |
+
return lines.join('\n');
|
| 166 |
+
}
|
| 167 |
+
function toHtml(res) {
|
| 168 |
+
const f = (res && res.findings) || [];
|
| 169 |
+
if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>';
|
| 170 |
+
const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join('');
|
| 171 |
+
return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>';
|
| 172 |
+
}
|
| 173 |
+
var PSGREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml };
|
| 174 |
+
if (typeof module !== 'undefined' && module.exports) module.exports = PSGREPORT;
|
| 175 |
+
else window.PSGREPORT = PSGREPORT;
|
| 176 |
+
</script>
|
| 177 |
+
<script>
|
| 178 |
+
(function(){
|
| 179 |
+
var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today');
|
| 180 |
+
today.value=new Date().toISOString().slice(0,10);
|
| 181 |
+
function run(){ try { var res=window.PSGENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.PSGREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } }
|
| 182 |
+
go.onclick=run; if (src.value.trim()) run();
|
| 183 |
+
})();
|
| 184 |
+
</script>
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
<section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.nicegui-migration-check" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'nicegui-migration-check',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/nicegui-migration-check" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'nicegui-migration-check',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.nicegui-migration-check</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/team" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
|
| 188 |
+
<section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind NiceGUI Migration Check: PySimpleGUI Licence Gate every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"nicegui-migration-check",lang:"en",source:"rule_alert"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);document.addEventListener("click",function(ev){var b=ev.target&&ev.target.closest?ev.target.closest("button,input[type=submit]"):null;if(b&&!b.closest("[data-yj],[data-yj-cta],[data-yj-install],[data-yj-alert],.yj-find,.yj-related,#yj-ask,.yjp"))mv(ev);},true);})();</script></section>
|
| 189 |
+
|
| 190 |
+
<section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the full version <span class="yj-price">$29</span></h2><p class="yj-cta-paid" style="margin:.25rem 0 .6rem;color:#1f2a37">Whole-workspace NiceGUI/Flet migration plan, a dated licence-exposure report and a CI gate that fails new PySimpleGUI 5 use.</p><p class="yj-cta-pay" style="margin:.25rem 0 1rem;color:#5b6b7c;font-size:.94rem">One payment, one licence key for this tool. The key is shown right after payment.</p><p class="yj-cta-anchor" style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">PySimpleSoft sold the PySimpleGUI 5 commercial licence at $99 per developer (PySimpleGUI 5.0.8.3 PyPI notice, read 2026-10-10).</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_Il7ZSZ8o2tsU1tqxjaGGd9mIlNXDDO4whVDrv0g7Cd0" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
|
| 191 |
+
<!--yj-embed-s178--><details id="embed" data-yj="yj-embed" style="max-width:46rem;margin:1.6rem auto;padding:.85rem 1.1rem;border:1px solid #8884;border-radius:10px"><summary style="cursor:pointer;font-weight:600">Embed this tool on your site (free)</summary><p style="margin:.6rem 0;opacity:.85">Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.</p><textarea readonly rows="6" style="width:100%;font:12px/1.4 ui-monospace,Menlo,Consolas,monospace;border:1px solid #8886;border-radius:7px;padding:.5rem"><iframe src="https://getreadystack.com/embed/nicegui-migration-check/" title="NiceGUI Migration Check: PySimpleGUI Licence Gate — free online check" loading="lazy" data-rs-embed="en-nicegui-migration-check" style="width:100%;max-width:760px;height:640px;border:1px solid #e3e3e3;border-radius:10px"></iframe>
|
| 192 |
+
<p style="font-size:13px;margin:6px 0 0"><a href="https://getreadystack.com/tools/nicegui-migration-check">NiceGUI Migration Check: PySimpleGUI Licence Gate — free online check</a> by <a href="https://getreadystack.com/">ReadyStack</a></p>
|
| 193 |
+
<script>window.addEventListener("message",function(e){if(e.origin!=="https://getreadystack.com"||!e.data||e.data.type!=="readystack-embed")return;var f=document.querySelectorAll("iframe[data-rs-embed]");for(var i=0;i<f.length;i++){if(f[i].contentWindow===e.source)f[i].style.height=Math.min(e.data.h+6,8000)+"px";}});</script></textarea><p style="margin:.5rem 0 0"><button type="button" data-yj="yj-embed-copy" style="font:inherit;padding:8px 14px;border:1px solid #8884;border-radius:9px;background:transparent;cursor:pointer">Copy code</button> <a href="/embed/">All embeddable tools</a></p><p style="margin:.7rem 0 0;font-size:.92em;opacity:.9">For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. <a href="/embed/pro/?ref=embed_box">See Pro →</a></p></details><script data-yj="yj-embed">(function(){var b=document.querySelector("[data-yj=yj-embed-copy]");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var a=b.closest("details").querySelector("textarea");var v=a.value;function d(){b.textContent="Copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(v).then(d,function(){a.select();});}else{a.select();}});})();</script><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script>
|
| 194 |
+
<script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
|
| 195 |
+
|
| 196 |
+
<script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script>
|
| 197 |
+
|
| 198 |
+
<script data-yj="yj-prefill-s181 v1">(function(){try{var q=new URLSearchParams(location.search);if(!q.toString())return;var P={"R": {"employee": ["employee|w-?2\\b|arbeitnehmer|angestellt|会社員|従業員|給与所得|trabajador|asalariad|empregad|clt\\b|salari", "Employee"], "self": ["self-?employ|freelanc|sole (trader|prop)|selbst(ä|ae)ndig|freiberuf|個人事業|フリーランス|aut(ó|o)nom|\\bmei\\b", "Freelancer / self-employed"], "landlord": ["landlord|rental|vermiet|大家|不動産|arrendador|alquiler|locador|aluguel", "Landlord"], "investor": ["invest|trader|anleger|投資|inversor|investidor", "Investor / trader"], "employer": ["employer|arbeitgeber|雇用主|事業主|empleador|empregador", "Employer"], "seller": ["seller|online shop|h(ä|ae)ndler|販売|vendedor|e-?commerce", "Online seller"]}, "C": {"US": "^(us|usa)$|united states|estados unidos|vereinigte staaten|アメリカ|米国", "UK": "^(uk|gb)$|united kingdom|great britain|reino unido|vereinigtes k|イギリス|英国", "DE": "^de$|germany|deutschland|alemania|alemanha|ドイツ", "JP": "^jp$|japan|jap(ó|ã|o)n?|日本", "ES": "^es$|spain|españa|espana|espanha|spanien|スペイン", "BR": "^br$|brazil|brasil|ブラジル"}, "B": "your 2027 dates", "L": "en"};function ours(el){return !!(el&&el.closest&&el.closest("[data-yj],[data-yj-cta],[data-yj-cal],.yj-email-gate,.yj-find,.yj-related,#yj-ask,#yjgo,#yjr,header,footer,nav"));}function fields(){var r=document.querySelector("main")||document.body;return [].filter.call(r.querySelectorAll("input,select,textarea"),function(el){var t=(el.type||"").toLowerCase();return !ours(el)&&!el.disabled&&["email","hidden","search","password","file","submit","button","reset","image"].indexOf(t)<0;});}function key(el){return el.getAttribute("data-k")||el.id||el.name||"";}function fire(el){["input","change"].forEach(function(n){try{el.dispatchEvent(new Event(n,{bubbles:true}))}catch(e){}});}function setv(el,v){v=String(v).slice(0,80);var t=(el.type||"").toLowerCase(),tg=el.tagName;if(tg=="SELECT"){var o=[].filter.call(el.options,function(o){return o.value==v||o.text.trim()==v})[0];if(!o)return false;el.value=o.value;}else if(t=="checkbox"||t=="radio"){if(!/^(1|0|true|false|on|off|yes|no)$/i.test(v))return false;el.checked=/^(1|true|on|yes)$/i.test(v);}else if(t=="number"||t=="range"){var n=parseFloat(v.replace(/\s/g,"").replace(",","."));if(!isFinite(n))return false;el.value=String(n);}else if(t=="date"){if(!/^\d{4}-\d{2}-\d{2}$/.test(v))return false;el.value=v;}else{if(/[<>]/.test(v))return false;el.value=v;}fire(el);return true;}function pick(el,rx){if(el.tagName!="SELECT")return false;var re=new RegExp(rx,"i");var o=[].filter.call(el.options,function(o){return re.test(o.value)||re.test(o.text)})[0];if(!o||el.value==o.value)return false;el.value=o.value;fire(el);return true;}function run(){var F=fields(),done={},n=0;q.forEach(function(v,k){if(n>=20||/^(ref|role|cc|utm_.*|fbclid|gclid)$/.test(k)||!/^[A-Za-z0-9_-]{1,40}$/.test(k))return;F.forEach(function(el){if(key(el)===k&&!done[k]&&setv(el,v)){done[k]=1;n++;}});});var cc=(q.get("cc")||"").toUpperCase().replace(/[^A-Z]/g,"");if(P.C[cc])F.forEach(function(el){var k=key(el);if(!done[k]&&/country|land|pa(i|í)s|pays|国/i.test(k+" "+(el.id||""))&&pick(el,P.C[cc])){done[k]=1;n++;}});var ro=(q.get("role")||"").replace(/[^a-z]/g,""),R=P.R[ro];if(R)F.forEach(function(el){var k=key(el);if(!done[k]&&el.tagName=="SELECT"&&[].some.call(el.options,function(o){return [].some.call(Object.keys(P.R),function(x){return new RegExp(P.R[x][0],"i").test(o.text)})})&&pick(el,R[0])){done[k]=1;n++;}});if(q.get("ref")=="calendar"){var h=document.querySelector("main h1")||document.querySelector("h1");var d=document.createElement("div");d.setAttribute("data-yj","yj-prefill-back");d.style.cssText="margin:.4rem 0 .8rem;font:15px/1.5 system-ui,sans-serif;opacity:.9";var a=document.createElement("a");a.href="/"+P.L+"/calendar/?ref=tool"+(R?"&role="+ro:"")+(P.C[cc]?"&cc="+cc:"");a.textContent=(R?R[1]+" \u00b7 ":"")+P.B+" \u2192";d.appendChild(a);if(h&&h.parentNode)h.parentNode.insertBefore(d,h.nextSibling);}document.documentElement.setAttribute("data-yj-prefilled",String(n));}if(document.readyState=="loading")document.addEventListener("DOMContentLoaded",run);else run();}catch(e){}})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div><section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-10-10">Updated 2026-10-10</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-10-10","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku596874_result_card.jpg" alt="Migrate from PySimpleGUI 5 to NiceGUI: six ties in one requirements.txt" loading="lazy" style="max-width:100%;border-radius:6px"></p>
|
| 199 |
+
<p>Six PySimpleGUI ties turned up in one 9-line requirements.txt, the file a Python developer keeps for an internal Windows desktop tool at a small company in the US or Europe. Three are errors, two are warnings and one is an info line:</p>
|
| 200 |
+
<table><thead><tr><th>Line</th><th>PySimpleGUI line</th><th>Replacement line</th></tr></thead><tbody><tr><td>2</td><td>--extra-index-url https://PySimpleGUI.net/install</td><td>delete; PySimpleGUI>=6,<7 is LGPL3 on PyPI</td></tr><tr><td>3</td><td>PySimpleGUI==5.0.8.3</td><td>FreeSimpleGUI==5.3.0.post1 or nicegui==3.18.0</td></tr><tr><td>4</td><td>PySimpleGUI==4.60.5</td><td>FreeSimpleGUI==5.3.0.post1</td></tr><tr><td>5</td><td>PySimpleGUIQt</td><td>FreeSimpleGUIQt==2.0.0</td></tr><tr><td>6</td><td>PySimpleGUIWeb==0.39.0</td><td>FreeSimpleGUIWeb==1.1.0</td></tr><tr><td>7</td><td>PySimpleGUIWx==0.17.2</td><td>FreeSimpleGUIWx==1.1.0</td></tr></tbody></table>
|
| 201 |
+
<p>The errors are the ones that break a fresh install. On 2026-10-10 the PySimpleGUI.net/install index returned HTTP 404, so pip falls back to PyPI. On PyPI, PySimpleGUI 5.0.8.3 is a stub: its PySimpleGUI.py only prints "PySimpleGUI is now located on a private PyPI server". There is no Window class in it, so the tool dies on its first sg.Window call. A bare PySimpleGUIQt installs version 5.0.0, and its PyPI licence field reads "Free To Use But Restricted".</p>
|
| 202 |
+
<h3>What PySimpleSoft changed, and when</h3>
|
| 203 |
+
<p>PySimpleGUI 5 launched as a paid product in February 2024. Hobbyists registered a free key, and companies were expected to buy a commercial licence at $99 per developer. The notice on the 5.0.8.3 PyPI page says only 600 people paid that $99. PySimpleSoft announced the shutdown in February 2025 and kept support for commercial users through the end of 2025. Hobbyist keys run until they expire, and no new ones are issued.</p>
|
| 204 |
+
<p>On 2026-04-14 PySimpleGUI 6 was published on PyPI under LGPL3, with the licensing and security components removed. The latest is 6.3.0.1 from 2026-08-16. So the old answer, "PySimpleGUI needs a paid licence", is now only true for the 5.x line. Many answers written before April 2026 still give it.</p>
|
| 205 |
+
<h3>Three ways out</h3>
|
| 206 |
+
<ol><li>FreeSimpleGUI 5.3.0.post1 is the LGPL fork of the last free release. Its README shows the whole change as one line: import FreeSimpleGUI as sg. The Qt, Wx and Web ports have FreeSimpleGUIQt 2.0.0, FreeSimpleGUIWx 1.1.0 and FreeSimpleGUIWeb 1.1.0.</li><li>PySimpleGUI 6 under LGPL3: pin PySimpleGUI>=6,<7 and delete the private index line. It is one maintainer's code, and the README says pull requests are not accepted.</li><li>NiceGUI 3.18.0 (MIT) or Flet 1.0.4 (Apache-2.0): a rewrite. sg.Text becomes ui.label, sg.Button becomes ui.button, and the window.read() loop becomes callbacks. It is a bigger job, but it gives you a maintained toolkit and a browser UI.</li></ol>
|
| 207 |
+
<h3>How the check reads a file</h3>
|
| 208 |
+
<p>The extension has 9 rules. It reads requirements*.txt, pyproject.toml (PEP 621 and Poetry), setup.py, setup.cfg, Pipfile and imports in .py files. A version ceiling decides the rule: ==5.0.8.3 is the stub, >=5,<6 is proprietary 5.x, <5 is the LGPL3 4.x line, and >=6 is clean. An as-of date input changes severity, too. Before 2026-01-01 the 5.x lines are warnings, because support still ran. After that date they are errors.</p>
|
| 209 |
+
<p>The migrated file has FreeSimpleGUI==5.3.0.post1, FreeSimpleGUIQt==2.0.0, nicegui==3.18.0 and flet==1.0.4, and it gives zero findings.</p>
|
| 210 |
+
<h3>Free and with a key</h3>
|
| 211 |
+
<p>The open file is free, with every tie and every replacement line. A one-time key adds the whole-workspace migration plan, a dated licence-exposure report for the company, and a CI gate that fails a build adding new PySimpleGUI 5 use.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku596874_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku596874_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does NiceGUI Migration Check do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads requirements.txt, pyproject.toml, setup.py, setup.cfg, Pipfile and Python imports and lists every PySimpleGUI tie: the PySimpleGUI.net/install private index, the PySimpleGUI==5.0.8.3 PyPI stub, proprietary 5.x pins, a bare PySimpleGUIQt that installs the restricted 5.0.0, the old Wx and Web ports and each import. Every finding carries its line number and the FreeSimpleGUI, PySimpleGUI 6 or NiceGUI replacement line. It has 9 rules.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is NiceGUI Migration Check for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It is for Python developers and small internal-tools teams who built desktop utilities on PySimpleGUI between 2018 and 2025 and now have to decide where to go: FreeSimpleGUI as a drop-in, PySimpleGUI 6 under LGPL3, or a rewrite in NiceGUI or Flet. It also suits the person at a company who must answer which projects ever pulled proprietary PySimpleGUI 5.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just grep for PySimpleGUI or ask a chatbot?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A text search finds the name but not the meaning of each line. A bare PySimpleGUIQt installs version 5.0.0, whose PyPI licence field says Free To Use But Restricted. PySimpleGUI==5.0.8.3 is a stub that only prints a move notice. PySimpleGUI 6 has been LGPL3 since 2026-04-14, which many answers written earlier still miss.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what needs a licence key?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free and without a key: the open file is checked on save or on command, and every PySimpleGUI tie is listed with its line and the replacement line. Nothing in that answer is hidden. A one-time licence key adds the whole-workspace migration plan with sg elements mapped to NiceGUI or Flet, a dated licence-exposure report and a CI gate for new PySimpleGUI 5 use.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What did staying on PySimpleGUI 5 cost?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">PySimpleSoft sold the PySimpleGUI 5 commercial licence at 99 US dollars per developer, according to the notice on the PySimpleGUI 5.0.8.3 PyPI page, which also says only 600 people paid it. PySimpleSoft has shut down and support ended with 2025. FreeSimpleGUI and PySimpleGUI 6 are LGPL3, NiceGUI is MIT and Flet is Apache-2.0.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does NiceGUI Migration Check do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads requirements.txt, pyproject.toml, setup.py, setup.cfg, Pipfile and Python imports and lists every PySimpleGUI tie: the PySimpleGUI.net/install private index, the PySimpleGUI==5.0.8.3 PyPI stub, proprietary 5.x pins, a bare PySimpleGUIQt that installs the restricted 5.0.0, the old Wx and Web ports and each import. Every finding carries its line number and the FreeSimpleGUI, PySimpleGUI 6 or NiceGUI replacement line. It has 9 rules."}}, {"@type": "Question", "name": "Who is NiceGUI Migration Check for?", "acceptedAnswer": {"@type": "Answer", "text": "It is for Python developers and small internal-tools teams who built desktop utilities on PySimpleGUI between 2018 and 2025 and now have to decide where to go: FreeSimpleGUI as a drop-in, PySimpleGUI 6 under LGPL3, or a rewrite in NiceGUI or Flet. It also suits the person at a company who must answer which projects ever pulled proprietary PySimpleGUI 5."}}, {"@type": "Question", "name": "Why not just grep for PySimpleGUI or ask a chatbot?", "acceptedAnswer": {"@type": "Answer", "text": "A text search finds the name but not the meaning of each line. A bare PySimpleGUIQt installs version 5.0.0, whose PyPI licence field says Free To Use But Restricted. PySimpleGUI==5.0.8.3 is a stub that only prints a move notice. PySimpleGUI 6 has been LGPL3 since 2026-04-14, which many answers written earlier still miss."}}, {"@type": "Question", "name": "What is free and what needs a licence key?", "acceptedAnswer": {"@type": "Answer", "text": "Free and without a key: the open file is checked on save or on command, and every PySimpleGUI tie is listed with its line and the replacement line. Nothing in that answer is hidden. A one-time licence key adds the whole-workspace migration plan with sg elements mapped to NiceGUI or Flet, a dated licence-exposure report and a CI gate for new PySimpleGUI 5 use."}}, {"@type": "Question", "name": "What did staying on PySimpleGUI 5 cost?", "acceptedAnswer": {"@type": "Answer", "text": "PySimpleSoft sold the PySimpleGUI 5 commercial licence at 99 US dollars per developer, according to the notice on the PySimpleGUI 5.0.8.3 PyPI page, which also says only 600 people paid it. PySimpleSoft has shut down and support ended with 2025. FreeSimpleGUI and PySimpleGUI 6 are LGPL3, NiceGUI is MIT and Flet is Apache-2.0."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:596874,slug:"nicegui-migration-check",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/dotnet-eol-support-gate?ref=related"><span class="yj-rel-t">.NET EOL & CRA Support Window Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/cinc-migration-check?ref=related"><span class="yj-rel-t">Cinc Migration Check: Chef Infra licence gate lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/pekko-migration-gate?ref=related"><span class="yj-rel-t">Pekko Migration Gate — Akka BSL licence check</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/pyside6-migration-lint?ref=related"><span class="yj-rel-t">PySide6 Migration Lint: PyQt5/PyQt6 Licence Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/pypdf-migration-check?ref=related"><span class="yj-rel-t">pypdf Migration Check - PyMuPDF AGPL Licence Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/pyproject-release-gate?ref=related"><span class="yj-rel-t">pyproject.toml Release Gate (PEP 639)</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body>
|
| 212 |
</html>
|