diff --git a/chatbot.js b/chatbot.js
index d2656fb..e6f92c5 100644
--- a/chatbot.js
+++ b/chatbot.js
@@ -33,8 +33,8 @@ const CANNED = [
a: 'Join free with just your email at https://instantadpay.com/my, no wallet and no password needed. Your wallet only comes out when you buy a package or switch on payouts, and the site walks you through it.' },
{ re: /(referral link|invite link|share link|refer)/i,
a: 'You get your share link the moment you sign in, free members included. One tip: switch on payouts (one free wallet step in Members) before your people start buying, because the contract locks each buyer to their sponsor at their first purchase.' },
- { re: /(promo tools?|social posts?|email swipes?|banners?|handouts?|flyers?|text a friend|objection|share buttons?)/i,
- a: 'Promo tools (Members > Promo tools) has pill menus for each kit: Social posts (X, Facebook, LinkedIn, Telegram or WhatsApp, with post and share buttons), Text a friend (SMS-sized messages with Text it, WhatsApp, Telegram and Copy), Email swipes (short, standard, long, follow-up), Banners (every standard ad size plus square, story and Telegram sizes, download or copy URL), printable Handouts with your QR code (Open your handouts), your Banner wall link, and an Objection handling bank with the truth plus a ready-to-send reply. Everything is personalized with your invite link.' },
+ { re: /(promo tools?|social posts?|email swipes?|banners?|text a friend|objection|share buttons?)/i,
+ a: 'Promo tools (Members > Promo tools) has pill menus for each kit: Social posts (X, Facebook, LinkedIn, Telegram or WhatsApp, with post and share buttons), Text a friend (SMS-sized messages with Text it, WhatsApp, Telegram and Copy), Email swipes (short, standard, long, follow-up), Banners (every standard ad size plus square, story and Telegram sizes, download or copy URL), your Banner wall link, and an Objection handling bank with the truth plus a ready-to-send reply. Everything is personalized with your invite link.' },
{ re: /(solo ad|inbox ad|inbox)/i,
a: 'Solo ads are full-message ads delivered straight into member inboxes on-site. Compose one under Campaigns (pick "Solo ad"): subject line, a rich-text message with a real editor (bold, headings, lists, links), an attached image or video if you want one, and a call-to-action button with your own label. You pay 5 credits per guaranteed delivery, 10 deliveries minimum. On the reading side, your Inbox section collects solos from other members — give one a real read (10 seconds on the open message) and claim 2 credits, up to 5 rewarded reads a day. You never receive your own solo.' },
{ re: /(chat|message (my )?(sponsor|upline|team|downline)|talk to (my )?sponsor|contact (my )?sponsor|ask (my )?sponsor|reach (my )?sponsor)/i,
@@ -55,7 +55,7 @@ function systemPrompt() {
FACTS:
- Free to join with email only (6-digit code sign-in, no passwords). Wallet appears only at purchase or payout activation. Every new member gets a small welcome batch of ad credits — unlocked by the WELCOME TOUR on first sign-in: they visit their upline's line-banner sites (up to 3, 10 seconds each — the same 3 levels the contract pays), then claim the credits. Members with no upline banners get the credits instantly.
-- PROMO TOOLS (Members > Promo tools, pill menu): Social posts for X/Facebook/LinkedIn/Telegram-WhatsApp with post/share buttons; Text a friend (5 SMS-sized messages with Text it / WhatsApp / Telegram / Copy); Email swipes (short, standard, long, follow-up); Banners in every standard ad size plus 1080x1080, 1080x1920 and 1280x720 (download or copy URL); printable half-sheet Handouts at /flyers with the member's own QR code and invite link (two per letter page with a cut line); the member's Banner wall link; an Objection handling bank (truth + ready-to-send reply); a Videos tab (hook videos in production). Every piece carries the member's invite link; angle links add ?v=instant|adspend|free|ledger. Members who want copy in their own voice can use mybrandedvoice.com.
+- PROMO TOOLS (Members > Promo tools, pill menu): Social posts for X/Facebook/LinkedIn/Telegram-WhatsApp with post/share buttons; Text a friend (5 SMS-sized messages with Text it / WhatsApp / Telegram / Copy); Email swipes (short, standard, long, follow-up); Banners in every standard ad size plus 1080x1080, 1080x1920 and 1280x720 (download or copy URL); the member's Banner wall link; an Objection handling bank (truth + ready-to-send reply); a Videos tab (hook videos in production). Every piece carries the member's invite link; angle links add ?v=instant|adspend|free|ledger. Members who want copy in their own voice can use mybrandedvoice.com.
- LINE BANNER (free, set in Profile): every member can set a destination URL (must allow framing) plus an optional banner image. It is shown to their next THREE levels of new members during welcome tours (position 1 for directs, 2, 3 below), and on their public BANNER WALL at /wall/ — a shareable page showing their line ladder with their join link. Free viral traffic that compounds as the team grows; no credits spent.
- Ad packages: Micro $5/500 credits, Activation $20/2,000, Builder $50/5,500, Growth $100/12,000, Leader $250/32,500. Dollar-priced, settled in POL (Polygon) at the live Chainlink rate. 1 credit = 1 cent of ad delivery.
- Live formats: display banners (per impression), text ads (per impression), full-screen LOGIN ADS (per day: right after a member signs in they land on a sponsor interstitial — they click "Open Ad", the advertiser's page opens in a NEW tab, a countdown runs on the interstitial, and at zero a "Go to dashboard" button appears. Just a CTA link is enough; an optional banner image can be the clickable creative. No framing requirement since it opens in its own tab), WATCH-TO-EARN VIDEO ADS (advertiser uploads an MP4/WebM or gives a direct https .mp4/.webm link and picks a required watch length — 10s/30s/60s — which sets the per-view price; viewers watch in an escape-proof player under Earn credits > Watch videos, the watch time is enforced on the server clock, and they earn credits per completed watch; you never see your own videos), and solo ads. Banner ads also require a size (standard IAB sizes like 728x90, 300x250). Coming: featured rotation with disclosed rotation size, verified-visit packs.
diff --git a/public/assets/flyers.js b/public/assets/flyers.js
deleted file mode 100644
index 6e73afc..0000000
--- a/public/assets/flyers.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Printable half-sheet handouts with the member's QR + invite link.
-// The ref token (username, share code or member #) comes from ?ref=, then
-// localStorage (set by Promo tools), then the signed-in account.
-(function () {
- 'use strict';
- var $ = function (id) { return document.getElementById(id); };
- var ORIGIN = location.origin;
- var DESIGNS = [
- { angle: 'instant', tag: 'Polygon · same-transaction payouts', h: 'Advertise & earn. Paid on-chain, instantly.',
- lead: 'Every ad package splits to real wallets the second it sells. No pending. No withdraw button.',
- bullets: ['Free to join with just an email', 'Ad packages from $5, seven ad formats', 'Every payout public on the blockchain'] },
- { angle: 'adspend', tag: 'For marketers who buy traffic', h: 'You were buying ads anyway.',
- lead: 'Here the ad spend in your line pays you, in the same transaction, on a public ledger.',
- bullets: ['Banners, text, login, solo, video, featured, visits', 'Dwell-timed views: real people, not scripts', '50 / 20 / 10 sponsor split, written in code'] },
- { angle: 'free', tag: 'Costs nothing to try', h: 'Watch first. Spend never.',
- lead: 'Join free, view a few ads, earn credits, and run your first campaign for zero dollars.',
- bullets: ['Email sign-in, no password, no wallet needed', 'Earn credits for your attention every day', 'Upgrade only if you want more reach'] }
- ];
- function getRef() {
- var q = new URLSearchParams(location.search).get('ref');
- if (q && /^[A-Za-z0-9_]{1,20}$/.test(q)) return q;
- try { var s = localStorage.getItem('iap.ref'); if (s && /^[A-Za-z0-9_]{1,20}$/.test(s)) return s; } catch (e) {}
- return '';
- }
- function qrSvg(url) {
- try { var q = qrcode(0, 'M'); q.addData(url); q.make(); return q.createSvgTag({ cellSize: 4, margin: 2, scalable: true }); } catch (e) { return ''; }
- }
- function el(tag, cls, html) { var d = document.createElement(tag); if (cls) d.className = cls; if (html != null) d.innerHTML = html; return d; }
- function card(d, url, shortUrl) {
- var hs = el('div', 'hs');
- hs.appendChild(el('div', 'lines'));
- var inner = el('div', 'in');
- var logo = el('img', 'logo'); logo.src = '/logo.png'; logo.alt = 'InstantAdPay'; inner.appendChild(logo);
- inner.appendChild(el('span', 'tag', d.tag));
- inner.appendChild(el('h2', null, d.h));
- inner.appendChild(el('p', 'lead', d.lead));
- var ul = el('ul'); d.bullets.forEach(function (b) { ul.appendChild(el('li', null, b)); }); inner.appendChild(ul);
- inner.appendChild(el('div', 'foot', 'Scan the code or visit ' + shortUrl + ''));
- hs.appendChild(inner);
- var ov = el('div', 'hs-qrov');
- ov.appendChild(el('div', 'q', url ? qrSvg(url) : ''));
- ov.appendChild(el('div', 'scan', 'SCAN ME'));
- ov.appendChild(el('div', 'lnk', shortUrl));
- hs.appendChild(ov);
- hs.appendChild(el('div', 'hs-disc', 'Advertising, not investing. No income is guaranteed; results depend on your effort. Crypto carries risk of loss.'));
- return hs;
- }
- function build(ref) {
- var wrap = $('halfsheets'); wrap.innerHTML = '';
- DESIGNS.forEach(function (d) {
- var url = ref ? ORIGIN + '/join/' + ref + '?v=' + d.angle : '';
- var shortUrl = ref ? 'instantadpay.com/join/' + ref : 'instantadpay.com';
- var page = el('div', 'hs-page');
- var pr = el('button', 'btn small hs-print', 'Print this one'); pr.type = 'button';
- pr.addEventListener('click', function () {
- document.body.classList.add('print-one'); page.classList.add('printing');
- window.print();
- setTimeout(function () { document.body.classList.remove('print-one'); page.classList.remove('printing'); }, 400);
- });
- page.appendChild(pr);
- page.appendChild(card(d, url, shortUrl));
- page.appendChild(el('div', 'hs-cut', '✂ cut here'));
- var copy = card(d, url, shortUrl); copy.classList.add('hs-copy'); page.appendChild(copy);
- wrap.appendChild(page);
- });
- }
- var input = $('flRef');
- var ref = getRef();
- if (ref) input.value = ref;
- build(ref);
- input.addEventListener('input', function () {
- var v = input.value.trim();
- if (!v || /^[A-Za-z0-9_]{1,20}$/.test(v)) { build(v); try { if (v) localStorage.setItem('iap.ref', v); } catch (e) {} }
- });
- if (!ref) { // signed-in member without a stored ref: ask the site
- fetch('/api/me').then(function (r) { return r.json(); }).then(function (me) {
- var t = me && me.signedIn && (me.username || me.refCode || me.memberId);
- if (t && !input.value) { input.value = String(t); build(String(t)); }
- }).catch(function () {});
- }
-})();
diff --git a/public/assets/my.js b/public/assets/my.js
index 0594cce..85e2dba 100644
--- a/public/assets/my.js
+++ b/public/assets/my.js
@@ -1013,7 +1013,7 @@
b.addEventListener('click', () => setEarnSub(b.dataset.earn)));
// promo tools: pill menu switches between posts / swipes / banners / wall / videos
function setPromoSub(name) {
- const ids = ['posts', 'text', 'swipe', 'banners', 'flyers', 'wall', 'objections', 'videos'];
+ const ids = ['posts', 'text', 'swipe', 'banners', 'wall', 'objections', 'videos'];
if (!ids.includes(name)) name = 'posts';
ids.forEach(id => { const el = $('promo-' + id); if (el) el.hidden = id !== name; });
document.querySelectorAll('.promo-pills [data-promo]').forEach(b => {
diff --git a/public/assets/promo.js b/public/assets/promo.js
index 0e23a73..0ec37b1 100644
--- a/public/assets/promo.js
+++ b/public/assets/promo.js
@@ -143,9 +143,6 @@ window.IAPPromo = (function () {
d.appendChild(body); ob.appendChild(d);
}
}
- // handouts link
- if ($('flyersOpen')) $('flyersOpen').href = '/flyers' + (token ? '?ref=' + encodeURIComponent(token) : '');
- try { if (token) localStorage.setItem('iap.ref', String(token)); } catch (e) {}
}
return { fill, POSTS, TEXTS, SWIPES, OBJECTIONS };
diff --git a/public/assets/qrlib.js b/public/assets/qrlib.js
deleted file mode 100644
index 76889b5..0000000
--- a/public/assets/qrlib.js
+++ /dev/null
@@ -1,2297 +0,0 @@
-//---------------------------------------------------------------------
-//
-// QR Code Generator for JavaScript
-//
-// Copyright (c) 2009 Kazuhiko Arase
-//
-// URL: http://www.d-project.com/
-//
-// Licensed under the MIT license:
-// http://www.opensource.org/licenses/mit-license.php
-//
-// The word 'QR Code' is registered trademark of
-// DENSO WAVE INCORPORATED
-// http://www.denso-wave.com/qrcode/faqpatent-e.html
-//
-//---------------------------------------------------------------------
-
-var qrcode = function() {
-
- //---------------------------------------------------------------------
- // qrcode
- //---------------------------------------------------------------------
-
- /**
- * qrcode
- * @param typeNumber 1 to 40
- * @param errorCorrectionLevel 'L','M','Q','H'
- */
- var qrcode = function(typeNumber, errorCorrectionLevel) {
-
- var PAD0 = 0xEC;
- var PAD1 = 0x11;
-
- var _typeNumber = typeNumber;
- var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];
- var _modules = null;
- var _moduleCount = 0;
- var _dataCache = null;
- var _dataList = [];
-
- var _this = {};
-
- var makeImpl = function(test, maskPattern) {
-
- _moduleCount = _typeNumber * 4 + 17;
- _modules = function(moduleCount) {
- var modules = new Array(moduleCount);
- for (var row = 0; row < moduleCount; row += 1) {
- modules[row] = new Array(moduleCount);
- for (var col = 0; col < moduleCount; col += 1) {
- modules[row][col] = null;
- }
- }
- return modules;
- }(_moduleCount);
-
- setupPositionProbePattern(0, 0);
- setupPositionProbePattern(_moduleCount - 7, 0);
- setupPositionProbePattern(0, _moduleCount - 7);
- setupPositionAdjustPattern();
- setupTimingPattern();
- setupTypeInfo(test, maskPattern);
-
- if (_typeNumber >= 7) {
- setupTypeNumber(test);
- }
-
- if (_dataCache == null) {
- _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);
- }
-
- mapData(_dataCache, maskPattern);
- };
-
- var setupPositionProbePattern = function(row, col) {
-
- for (var r = -1; r <= 7; r += 1) {
-
- if (row + r <= -1 || _moduleCount <= row + r) continue;
-
- for (var c = -1; c <= 7; c += 1) {
-
- if (col + c <= -1 || _moduleCount <= col + c) continue;
-
- if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
- || (0 <= c && c <= 6 && (r == 0 || r == 6) )
- || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
- _modules[row + r][col + c] = true;
- } else {
- _modules[row + r][col + c] = false;
- }
- }
- }
- };
-
- var getBestMaskPattern = function() {
-
- var minLostPoint = 0;
- var pattern = 0;
-
- for (var i = 0; i < 8; i += 1) {
-
- makeImpl(true, i);
-
- var lostPoint = QRUtil.getLostPoint(_this);
-
- if (i == 0 || minLostPoint > lostPoint) {
- minLostPoint = lostPoint;
- pattern = i;
- }
- }
-
- return pattern;
- };
-
- var setupTimingPattern = function() {
-
- for (var r = 8; r < _moduleCount - 8; r += 1) {
- if (_modules[r][6] != null) {
- continue;
- }
- _modules[r][6] = (r % 2 == 0);
- }
-
- for (var c = 8; c < _moduleCount - 8; c += 1) {
- if (_modules[6][c] != null) {
- continue;
- }
- _modules[6][c] = (c % 2 == 0);
- }
- };
-
- var setupPositionAdjustPattern = function() {
-
- var pos = QRUtil.getPatternPosition(_typeNumber);
-
- for (var i = 0; i < pos.length; i += 1) {
-
- for (var j = 0; j < pos.length; j += 1) {
-
- var row = pos[i];
- var col = pos[j];
-
- if (_modules[row][col] != null) {
- continue;
- }
-
- for (var r = -2; r <= 2; r += 1) {
-
- for (var c = -2; c <= 2; c += 1) {
-
- if (r == -2 || r == 2 || c == -2 || c == 2
- || (r == 0 && c == 0) ) {
- _modules[row + r][col + c] = true;
- } else {
- _modules[row + r][col + c] = false;
- }
- }
- }
- }
- }
- };
-
- var setupTypeNumber = function(test) {
-
- var bits = QRUtil.getBCHTypeNumber(_typeNumber);
-
- for (var i = 0; i < 18; i += 1) {
- var mod = (!test && ( (bits >> i) & 1) == 1);
- _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
- }
-
- for (var i = 0; i < 18; i += 1) {
- var mod = (!test && ( (bits >> i) & 1) == 1);
- _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
- }
- };
-
- var setupTypeInfo = function(test, maskPattern) {
-
- var data = (_errorCorrectionLevel << 3) | maskPattern;
- var bits = QRUtil.getBCHTypeInfo(data);
-
- // vertical
- for (var i = 0; i < 15; i += 1) {
-
- var mod = (!test && ( (bits >> i) & 1) == 1);
-
- if (i < 6) {
- _modules[i][8] = mod;
- } else if (i < 8) {
- _modules[i + 1][8] = mod;
- } else {
- _modules[_moduleCount - 15 + i][8] = mod;
- }
- }
-
- // horizontal
- for (var i = 0; i < 15; i += 1) {
-
- var mod = (!test && ( (bits >> i) & 1) == 1);
-
- if (i < 8) {
- _modules[8][_moduleCount - i - 1] = mod;
- } else if (i < 9) {
- _modules[8][15 - i - 1 + 1] = mod;
- } else {
- _modules[8][15 - i - 1] = mod;
- }
- }
-
- // fixed module
- _modules[_moduleCount - 8][8] = (!test);
- };
-
- var mapData = function(data, maskPattern) {
-
- var inc = -1;
- var row = _moduleCount - 1;
- var bitIndex = 7;
- var byteIndex = 0;
- var maskFunc = QRUtil.getMaskFunction(maskPattern);
-
- for (var col = _moduleCount - 1; col > 0; col -= 2) {
-
- if (col == 6) col -= 1;
-
- while (true) {
-
- for (var c = 0; c < 2; c += 1) {
-
- if (_modules[row][col - c] == null) {
-
- var dark = false;
-
- if (byteIndex < data.length) {
- dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
- }
-
- var mask = maskFunc(row, col - c);
-
- if (mask) {
- dark = !dark;
- }
-
- _modules[row][col - c] = dark;
- bitIndex -= 1;
-
- if (bitIndex == -1) {
- byteIndex += 1;
- bitIndex = 7;
- }
- }
- }
-
- row += inc;
-
- if (row < 0 || _moduleCount <= row) {
- row -= inc;
- inc = -inc;
- break;
- }
- }
- }
- };
-
- var createBytes = function(buffer, rsBlocks) {
-
- var offset = 0;
-
- var maxDcCount = 0;
- var maxEcCount = 0;
-
- var dcdata = new Array(rsBlocks.length);
- var ecdata = new Array(rsBlocks.length);
-
- for (var r = 0; r < rsBlocks.length; r += 1) {
-
- var dcCount = rsBlocks[r].dataCount;
- var ecCount = rsBlocks[r].totalCount - dcCount;
-
- maxDcCount = Math.max(maxDcCount, dcCount);
- maxEcCount = Math.max(maxEcCount, ecCount);
-
- dcdata[r] = new Array(dcCount);
-
- for (var i = 0; i < dcdata[r].length; i += 1) {
- dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
- }
- offset += dcCount;
-
- var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
- var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
-
- var modPoly = rawPoly.mod(rsPoly);
- ecdata[r] = new Array(rsPoly.getLength() - 1);
- for (var i = 0; i < ecdata[r].length; i += 1) {
- var modIndex = i + modPoly.getLength() - ecdata[r].length;
- ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
- }
- }
-
- var totalCodeCount = 0;
- for (var i = 0; i < rsBlocks.length; i += 1) {
- totalCodeCount += rsBlocks[i].totalCount;
- }
-
- var data = new Array(totalCodeCount);
- var index = 0;
-
- for (var i = 0; i < maxDcCount; i += 1) {
- for (var r = 0; r < rsBlocks.length; r += 1) {
- if (i < dcdata[r].length) {
- data[index] = dcdata[r][i];
- index += 1;
- }
- }
- }
-
- for (var i = 0; i < maxEcCount; i += 1) {
- for (var r = 0; r < rsBlocks.length; r += 1) {
- if (i < ecdata[r].length) {
- data[index] = ecdata[r][i];
- index += 1;
- }
- }
- }
-
- return data;
- };
-
- var createData = function(typeNumber, errorCorrectionLevel, dataList) {
-
- var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);
-
- var buffer = qrBitBuffer();
-
- for (var i = 0; i < dataList.length; i += 1) {
- var data = dataList[i];
- buffer.put(data.getMode(), 4);
- buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
- data.write(buffer);
- }
-
- // calc num max data.
- var totalDataCount = 0;
- for (var i = 0; i < rsBlocks.length; i += 1) {
- totalDataCount += rsBlocks[i].dataCount;
- }
-
- if (buffer.getLengthInBits() > totalDataCount * 8) {
- throw 'code length overflow. ('
- + buffer.getLengthInBits()
- + '>'
- + totalDataCount * 8
- + ')';
- }
-
- // end code
- if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
- buffer.put(0, 4);
- }
-
- // padding
- while (buffer.getLengthInBits() % 8 != 0) {
- buffer.putBit(false);
- }
-
- // padding
- while (true) {
-
- if (buffer.getLengthInBits() >= totalDataCount * 8) {
- break;
- }
- buffer.put(PAD0, 8);
-
- if (buffer.getLengthInBits() >= totalDataCount * 8) {
- break;
- }
- buffer.put(PAD1, 8);
- }
-
- return createBytes(buffer, rsBlocks);
- };
-
- _this.addData = function(data, mode) {
-
- mode = mode || 'Byte';
-
- var newData = null;
-
- switch(mode) {
- case 'Numeric' :
- newData = qrNumber(data);
- break;
- case 'Alphanumeric' :
- newData = qrAlphaNum(data);
- break;
- case 'Byte' :
- newData = qr8BitByte(data);
- break;
- case 'Kanji' :
- newData = qrKanji(data);
- break;
- default :
- throw 'mode:' + mode;
- }
-
- _dataList.push(newData);
- _dataCache = null;
- };
-
- _this.isDark = function(row, col) {
- if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
- throw row + ',' + col;
- }
- return _modules[row][col];
- };
-
- _this.getModuleCount = function() {
- return _moduleCount;
- };
-
- _this.make = function() {
- if (_typeNumber < 1) {
- var typeNumber = 1;
-
- for (; typeNumber < 40; typeNumber++) {
- var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);
- var buffer = qrBitBuffer();
-
- for (var i = 0; i < _dataList.length; i++) {
- var data = _dataList[i];
- buffer.put(data.getMode(), 4);
- buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
- data.write(buffer);
- }
-
- var totalDataCount = 0;
- for (var i = 0; i < rsBlocks.length; i++) {
- totalDataCount += rsBlocks[i].dataCount;
- }
-
- if (buffer.getLengthInBits() <= totalDataCount * 8) {
- break;
- }
- }
-
- _typeNumber = typeNumber;
- }
-
- makeImpl(false, getBestMaskPattern() );
- };
-
- _this.createTableTag = function(cellSize, margin) {
-
- cellSize = cellSize || 2;
- margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
-
- var qrHtml = '';
-
- qrHtml += '
';
- qrHtml += '';
-
- for (var r = 0; r < _this.getModuleCount(); r += 1) {
-
- qrHtml += '
';
-
- for (var c = 0; c < _this.getModuleCount(); c += 1) {
- qrHtml += '
Three half-sheet designs, two per letter page with a cut line. Each one carries your personal QR code and invite link, so a scan lands the prospect in your line. Print in color; the QR scans in black and white too.
-
Opened from Promo tools? It is filled in for you.
-
-
-
-
-
-
-
diff --git a/public/my.html b/public/my.html
index 5116691..45b7d2e 100644
--- a/public/my.html
+++ b/public/my.html
@@ -543,7 +543,6 @@
-
@@ -577,12 +576,6 @@
group sizes. Pair one with your invite link. Download, or copy the image URL for ad networks.
-
-
Printable handouts
-
Old-school still works. Three half-sheet designs, two per letter page with a cut line,
- each with your QR code and invite link baked in. Coffee shops, gyms, community boards, laundromats.