{"id":1917,"date":"2026-09-09T16:11:24","date_gmt":"2026-09-09T08:11:24","guid":{"rendered":"https:\/\/www.aitoolsoft.com\/?page_id=1917"},"modified":"2026-09-10T08:52:57","modified_gmt":"2026-09-10T00:52:57","slug":"qr-generator","status":"publish","type":"page","link":"https:\/\/www.aitoolsoft.com\/fr\/qr-generator.html","title":{"rendered":"G\u00e9n\u00e9rateur de codes QR"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1917\" class=\"elementor elementor-1917\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-540fb9f e-flex e-con-boxed e-con e-parent\" data-id=\"540fb9f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-74afb4f elementor-widget elementor-widget-html\" data-id=\"74afb4f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>.ats-tools{--ink:#172033;--muted:#667085;--line:#e5e9f2;--blue:#3567e5;--violet:#7158e8;font-family:Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;color:var(--ink);background:#f6f8fc;line-height:1.6;font-size:16px;padding-bottom:64px}.ats-tools *{box-sizing:border-box}.ats-tools .at-wrap{width:min(1180px,calc(100% - 40px));margin:auto}.ats-tools .at-intro{padding:42px 0 28px}.ats-tools .at-breadcrumb{font-size:14px;color:var(--muted)}.ats-tools a{color:var(--blue);text-underline-offset:3px}.ats-tools h1{font-size:clamp(32px,4vw,48px);line-height:1.12;letter-spacing:-.04em;margin:16px 0;color:var(--ink)}.ats-tools h2{font-size:24px;line-height:1.3;color:var(--ink);margin:0 0 16px}.ats-tools h3{font-size:18px;color:var(--ink)}.ats-tools .at-lead{max-width:760px;color:var(--muted);margin:0}.ats-tools .at-shell{border:1px solid var(--line);border-radius:24px;background:#fff;box-shadow:0 18px 48px #17203309;overflow:hidden}.ats-tools .at-topbar{padding:17px 24px;border-bottom:1px solid var(--line);display:flex;gap:16px;justify-content:space-between;flex-wrap:wrap;background:#fbfcff}.ats-tools .at-private{color:#157253;font-size:14px}.ats-tools .at-workspace{padding:24px;display:grid;grid-template-columns:300px minmax(0,1fr);gap:28px}.ats-tools .at-controls{display:flex;flex-direction:column;gap:16px}.ats-tools label{font-size:14px;font-weight:600;display:block}.ats-tools input:not([type=checkbox]):not([type=range]),.ats-tools select,.ats-tools textarea{display:block;width:100%;font:inherit;color:var(--ink);border:1px solid #cbd4e3;border-radius:10px;background:#fff;padding:10px 12px;min-height:44px;margin-top:6px}.ats-tools input[type=color]{padding:4px!important;height:44px}.ats-tools input[type=range]{width:100%;accent-color:var(--blue);margin:12px 0}.ats-tools input[type=checkbox]{accent-color:var(--blue);width:18px;height:18px;vertical-align:middle;margin-right:8px}.ats-tools textarea{resize:vertical;min-height:200px;font-family:ui-monospace,SFMono-Regular,monospace;font-size:14px;line-height:1.65}.ats-tools button,.ats-tools .at-button{min-height:44px;border:1px solid var(--line);border-radius:10px;padding:10px 16px;font:600 14px\/1.5 Inter,system-ui,sans-serif;cursor:pointer;background:white;color:var(--ink);text-decoration:none;display:inline-flex;justify-content:center;align-items:center;gap:8px}.ats-tools .at-primary{background:linear-gradient(125deg,var(--blue),var(--violet));color:white;border:0}.ats-tools button:disabled{opacity:.45;cursor:not-allowed}.ats-tools :is(button,input,select,textarea,a):focus-visible{outline:3px solid #8da9ff;outline-offset:3px}.ats-tools .at-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}.ats-tools .at-stage{display:grid;place-items:center;min-height:340px;padding:24px;border-radius:16px;background:repeating-conic-gradient(#f0f3f8 0 25%,#fff 0 50%) 50%\/20px 20px;border:1px solid var(--line);overflow:auto}.ats-tools canvas,.ats-tools .at-stage img{max-width:100%;max-height:490px;object-fit:contain;width:auto;height:auto}.ats-tools .at-empty{text-align:center;color:var(--muted);max-width:300px}.ats-tools .at-empty span{display:block;font-size:44px;color:var(--blue);margin-bottom:14px}.ats-tools .at-status{font-size:14px;min-height:24px;color:var(--muted);margin:14px 0 0;overflow-wrap:anywhere}.ats-tools .at-status[data-error=true]{color:#b42318}.ats-tools .at-note{font-size:14px;color:var(--muted);margin:0}.ats-tools .at-checks{display:flex;flex-wrap:wrap;gap:12px}.ats-tools .at-output{min-width:0}.ats-tools .at-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}.ats-tools .at-card{padding:18px;border:1px solid var(--line);border-radius:16px;background:#fff;min-width:0}.ats-tools .at-card p{color:var(--muted);font-size:14px}.ats-tools .at-card img{display:block;max-width:100%;height:auto}.ats-tools .at-wide{grid-column:1\/-1}.ats-tools .at-codepair{display:grid;grid-template-columns:1fr 1fr;gap:20px}.ats-tools .at-codepair textarea{min-height:380px}.ats-tools .at-password{font:600 24px\/1.6 ui-monospace,monospace;overflow-wrap:anywhere;white-space:pre-wrap;padding:28px;background:#f5f7fe;border:1px solid var(--line);border-radius:16px;min-height:160px;user-select:all}.ats-tools .at-help{margin-top:40px;display:grid;grid-template-columns:1fr 1fr;gap:32px}.ats-tools .at-help p,.ats-tools .at-help li{color:var(--muted)}.ats-tools details{padding:14px 0;border-bottom:1px solid var(--line)}.ats-tools summary{cursor:pointer;font-weight:600}.ats-tools .at-related{margin-top:36px}.ats-tools .at-related nav{display:flex;gap:10px;flex-wrap:wrap}.ats-tools .at-related a{font-size:14px;border:1px solid var(--line);border-radius:999px;padding:8px 14px;text-decoration:none;background:white}.ats-tools .at-frame img{height:88px;margin:auto;object-fit:contain}.ats-tools .at-frame .at-actions{gap:5px}.ats-tools .at-frame button{padding:6px 9px}.ats-tools .at-frame-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px}.ats-tools [hidden]{display:none!important}.ats-tools .at-drop{padding:18px;border:2px dashed #cbd5ea;border-radius:16px;background:#f8faff}.ats-tools .at-drop.is-over{background:#e9efff;border-color:var(--blue)}.ats-tools progress{width:100%;accent-color:var(--blue)}\n@media(max-width:820px){.ats-tools .at-workspace{grid-template-columns:1fr}.ats-tools .at-controls{display:grid;grid-template-columns:1fr 1fr}.ats-tools .at-controls .at-drop,.ats-tools .at-controls .at-note{grid-column:1\/-1}.ats-tools .at-codepair{grid-template-columns:1fr}.ats-tools .at-codepair textarea{min-height:240px}}\n@media(max-width:540px){.ats-tools .at-wrap{width:calc(100% - 28px)}.ats-tools .at-workspace{padding:16px}.ats-tools .at-controls,.ats-tools .at-help{grid-template-columns:1fr}.ats-tools .at-topbar{padding:16px}.ats-tools .at-stage{min-height:240px;padding:12px}.ats-tools .at-intro{padding-top:28px}.ats-tools .at-password{font-size:18px;padding:18px}}\n\n\/* Match the established background-editor page, without changing tool controls. *\/\n.ats-tools[data-tool]{position:relative;left:50%;width:100vw;max-width:none;margin-left:-50vw;margin-right:-50vw;background:#fff;padding-bottom:0}\n.ats-tools[data-tool]>.at-hero{padding:84px 0 70px;background:radial-gradient(circle at 82% 12%,rgba(113,88,232,.16),transparent 30%),radial-gradient(circle at 15% 86%,rgba(53,103,229,.14),transparent 30%),linear-gradient(145deg,#fbfcff,#f3f6fc)}\n.ats-tools .at-kicker{display:inline-flex;padding:8px 13px;border:1px solid #dce4f5;border-radius:999px;background:#fff;color:#3e5fa8;font-size:14px;font-weight:800;letter-spacing:.055em;text-transform:uppercase}\n.ats-tools[data-tool] h1{max-width:880px;margin:22px 0 18px;color:var(--ink);font-size:clamp(44px,7vw,76px);line-height:1;letter-spacing:-.055em;font-weight:700}\n.ats-tools[data-tool] .at-lead{max-width:760px;font-size:19px;line-height:1.72;margin:0}\n.ats-tools .at-notice{display:inline-flex;margin-top:22px;padding:10px 13px;border-radius:12px;background:#fff;color:#4d5b73;font-size:14px;box-shadow:0 8px 24px rgba(23,32,51,.06)}\n.ats-tools[data-tool]>.at-tool-section,.ats-tools[data-tool]>.at-workflow,.ats-tools[data-tool]>.at-questions{padding:72px 0}\n.ats-tools[data-tool] h2{margin:0 0 12px;font-size:clamp(31px,4vw,48px);letter-spacing:-.04em;line-height:1.2;font-weight:700}\n.ats-tools .at-sub{max-width:720px;margin:0;color:var(--muted);font-size:18px;line-height:1.7}\n.ats-tools[data-tool] .at-shell{margin-top:32px;box-shadow:0 18px 55px rgba(23,32,51,.09)}\n.ats-tools[data-tool] .at-topbar{padding:20px 22px;align-items:center;background:#fbfcfe}\n.ats-tools[data-tool] .at-topbar strong{font-size:18px}\n.ats-tools .at-info-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin-top:30px}\n.ats-tools .at-info-card{padding:25px;border:1px solid var(--line);border-radius:18px;background:#fff}\n.ats-tools .at-info-card h3{display:block;margin:0 0 9px;font-size:18px;line-height:1.5;font-weight:700}\n.ats-tools .at-info-card p{margin:0;color:var(--muted);font-size:16px;line-height:1.65}\n.ats-tools .at-workflow{background:#121b2d;color:#fff}\n.ats-tools .at-workflow h2,.ats-tools .at-workflow h3{color:#fff}\n.ats-tools .at-workflow .at-sub,.ats-tools .at-workflow .at-info-card p{color:#bec7d7}\n.ats-tools .at-workflow .at-info-card{border-color:#2b3850;background:#18243a}\n.ats-tools .at-questions .at-related{margin-top:40px;padding-top:26px;border-top:1px solid var(--line)}\n.ats-tools .at-questions .at-related h3{font-size:18px;margin:0 0 14px}\n.at-runtime-warning{width:min(1180px,calc(100% - 40px));margin:20px auto;padding:14px 16px;border:1px solid #f3c7c2;border-radius:12px;background:#fff4f2;color:#b42318;font:600 14px\/1.5 Inter,system-ui,sans-serif}\n@media(max-width:820px){.ats-tools .at-info-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}\n@media(max-width:580px){.ats-tools[data-tool]>.at-hero{padding:66px 0 54px}.ats-tools[data-tool]>.at-tool-section,.ats-tools[data-tool]>.at-workflow,.ats-tools[data-tool]>.at-questions{padding:56px 0}.ats-tools[data-tool] .at-wrap{width:calc(100% - 28px)}.ats-tools .at-info-grid{grid-template-columns:1fr}.ats-tools[data-tool] .at-topbar{padding:17px}.ats-tools[data-tool] h1{overflow-wrap:break-word}}\n<\/style><main id=\"aitoolsoft-qr-generator\" class=\"ats-tools\" data-tool=\"qr-generator\"><section class=\"at-hero\" aria-labelledby=\"tool-title\"><div class=\"at-wrap\"><span class=\"at-kicker\">Online QR tool<\/span><h1 id=\"tool-title\">Make your next link easy to scan.<\/h1><p class=\"at-lead\">Create a QR code for a link or plain text. Customize its size and colors, then download a PNG or scalable SVG.<\/p><span class=\"at-notice\">Your text is encoded on this device, without a tracking redirect.<\/span><\/div><\/section>\n <section class=\"at-tool-section\" aria-labelledby=\"workspace-title\"><div class=\"at-wrap\"><h2 id=\"workspace-title\">Create a QR code ready to share<\/h2><p class=\"at-sub\">Enter your link or text, choose the appearance and export an image for your screen or print layout.<\/p><div class=\"at-shell\"><div class=\"at-topbar\"><strong>QR code generator<\/strong><span class=\"at-private\">\u25cf Browser-based processing<\/span><\/div><div class=\"at-workspace\"><div class=\"at-controls\"><label for=\"text\">Link or text<textarea id=\"text\" maxlength=\"1500\" placeholder=\"https:\/\/example.com\"><\/textarea><\/label><label for=\"size\">Minimum image size<select id=\"size\"><option value=\"256\">256 px<\/option><option value=\"512\">512 px<\/option><option value=\"1024\">1024 px<\/option><\/select><\/label><label for=\"level\">Error correction<select id=\"level\"><option value=\"M\">Medium (M)<\/option><option value=\"L\">Low (L)<\/option><option value=\"Q\">Quartile (Q)<\/option><option value=\"H\">High (H)<\/option><\/select><\/label><label for=\"foreground\">Code color<input id=\"foreground\" type=\"color\" value=\"#172033\" ><\/label><label for=\"background\">Background color<input id=\"background\" type=\"color\" value=\"#ffffff\" ><\/label><button type=\"button\" id=\"generate\" class=\"at-primary\" >Generate QR code<\/button><\/div><div class=\"at-output\"><div id=\"stage\" class=\"at-stage\"><div class=\"at-empty\"><span aria-hidden=\"true\">\u25a7<\/span>Your preview will appear here.<\/div><\/div><div class=\"at-actions\"><button type=\"button\" id=\"png\" class=\"at-primary\" disabled>Download PNG<\/button><button type=\"button\" id=\"svg\" class=\"\" disabled>Download SVG<\/button><\/div><p class=\"at-note\">A four-module quiet zone is included. Test your code before printing.<\/p><p id=\"status\" class=\"at-status\" role=\"status\" aria-live=\"polite\">Loading tool\u2026<\/p><\/div><\/div><\/div><\/div><\/section>\n <section class=\"at-workflow\" aria-labelledby=\"workflow-title\"><div class=\"at-wrap\"><h2 id=\"workflow-title\">A focused workflow<\/h2><p class=\"at-sub\">Turn your content into a QR code, then check it before sharing.<\/p><div class=\"at-info-grid\"><article class=\"at-info-card\"><h3>1. Add a link or text<\/h3><p>Enter your link or text.<\/p><\/article><article class=\"at-info-card\"><h3>2. Choose your settings<\/h3><p>Choose size, colors and error correction.<\/p><\/article><article class=\"at-info-card\"><h3>3. Download and test<\/h3><p>Generate, download and test with your phone before sharing.<\/p><\/article><\/div><\/div><\/section>\n <section class=\"at-questions\" aria-labelledby=\"questions-title\"><div class=\"at-wrap\"><h2 id=\"questions-title\">Common questions<\/h2><div class=\"at-info-grid\"><article class=\"at-info-card\"><h3>Will the code expire?<\/h3><p>The QR image has no expiry and does not use a tracking redirect. A linked website can still change or become unavailable.<\/p><\/article><article class=\"at-info-card\"><h3>How can I make scanning reliable?<\/h3><p>Keep a dark foreground on a light background, preserve the quiet zone, and test the exported code at its intended size.<\/p><\/article><article class=\"at-info-card\"><h3>Should I download PNG or SVG?<\/h3><p>PNG is useful for everyday image sharing. SVG stays sharp when resized for print or design work. Test either format at the size you plan to use.<\/p><\/article><\/div><div class=\"at-related\"><h3>More online tools<\/h3><nav aria-label=\"Related tools\"><a href=\"https:\/\/www.aitoolsoft.com\/watermark-remover.html\">Watermark remover<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-background-editor.html\">Background editor<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-compressor.html\">Image compressor<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-format-converter.html\">Image converter<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-cropper.html\">Image cropper<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-border.html\">Image border<\/a><a href=\"https:\/\/www.aitoolsoft.com\/favicon-generator.html\">Favicon generator<\/a><a href=\"https:\/\/www.aitoolsoft.com\/youtube-thumbnail-generator.html\">YouTube thumbnails<\/a><a href=\"https:\/\/www.aitoolsoft.com\/image-to-base64.html\">Image to Base64<\/a><a href=\"https:\/\/www.aitoolsoft.com\/json-formatter.html\">JSON formatter<\/a><a href=\"https:\/\/www.aitoolsoft.com\/password-generator.html\">Password generator<\/a><a href=\"https:\/\/www.aitoolsoft.com\/gif-maker.html\">GIF maker<\/a><\/nav><\/div><\/div><\/section><\/main><noscript><p class=\"at-runtime-warning\">JavaScript is required to use this tool.<\/p><\/noscript><script>(function(){'use strict';function boot(){const root=document.getElementById('aitoolsoft-qr-generator');if(!root||root.dataset.runtimeReady==='true')return;try{\n\/\/---------------------------------------------------------------------\n\/\/\n\/\/ QR Code Generator for JavaScript\n\/\/\n\/\/ Copyright (c) 2009 Kazuhiko Arase\n\/\/\n\/\/ URL: http:\/\/www.d-project.com\/\n\/\/\n\/\/ Licensed under the MIT license:\n\/\/  http:\/\/www.opensource.org\/licenses\/mit-license.php\n\/\/\n\/\/ The word 'QR Code' is registered trademark of\n\/\/ DENSO WAVE INCORPORATED\n\/\/  http:\/\/www.denso-wave.com\/qrcode\/faqpatent-e.html\n\/\/\n\/\/---------------------------------------------------------------------\n\nvar qrcode = function() {\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrcode\n  \/\/---------------------------------------------------------------------\n\n  \/**\n   * qrcode\n   * @param typeNumber 1 to 40\n   * @param errorCorrectionLevel 'L','M','Q','H'\n   *\/\n  var qrcode = function(typeNumber, errorCorrectionLevel) {\n\n    var PAD0 = 0xEC;\n    var PAD1 = 0x11;\n\n    var _typeNumber = typeNumber;\n    var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];\n    var _modules = null;\n    var _moduleCount = 0;\n    var _dataCache = null;\n    var _dataList = [];\n\n    var _this = {};\n\n    var makeImpl = function(test, maskPattern) {\n\n      _moduleCount = _typeNumber * 4 + 17;\n      _modules = function(moduleCount) {\n        var modules = new Array(moduleCount);\n        for (var row = 0; row < moduleCount; row += 1) {\n          modules[row] = new Array(moduleCount);\n          for (var col = 0; col < moduleCount; col += 1) {\n            modules[row][col] = null;\n          }\n        }\n        return modules;\n      }(_moduleCount);\n\n      setupPositionProbePattern(0, 0);\n      setupPositionProbePattern(_moduleCount - 7, 0);\n      setupPositionProbePattern(0, _moduleCount - 7);\n      setupPositionAdjustPattern();\n      setupTimingPattern();\n      setupTypeInfo(test, maskPattern);\n\n      if (_typeNumber >= 7) {\n        setupTypeNumber(test);\n      }\n\n      if (_dataCache == null) {\n        _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);\n      }\n\n      mapData(_dataCache, maskPattern);\n    };\n\n    var setupPositionProbePattern = function(row, col) {\n\n      for (var r = -1; r <= 7; r += 1) {\n\n        if (row + r <= -1 || _moduleCount <= row + r) continue;\n\n        for (var c = -1; c <= 7; c += 1) {\n\n          if (col + c <= -1 || _moduleCount <= col + c) continue;\n\n          if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n              || (0 <= c && c <= 6 && (r == 0 || r == 6) )\n              || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n            _modules[row + r][col + c] = true;\n          } else {\n            _modules[row + r][col + c] = false;\n          }\n        }\n      }\n    };\n\n    var getBestMaskPattern = function() {\n\n      var minLostPoint = 0;\n      var pattern = 0;\n\n      for (var i = 0; i < 8; i += 1) {\n\n        makeImpl(true, i);\n\n        var lostPoint = QRUtil.getLostPoint(_this);\n\n        if (i == 0 || minLostPoint > lostPoint) {\n          minLostPoint = lostPoint;\n          pattern = i;\n        }\n      }\n\n      return pattern;\n    };\n\n    var setupTimingPattern = function() {\n\n      for (var r = 8; r < _moduleCount - 8; r += 1) {\n        if (_modules[r][6] != null) {\n          continue;\n        }\n        _modules[r][6] = (r % 2 == 0);\n      }\n\n      for (var c = 8; c < _moduleCount - 8; c += 1) {\n        if (_modules[6][c] != null) {\n          continue;\n        }\n        _modules[6][c] = (c % 2 == 0);\n      }\n    };\n\n    var setupPositionAdjustPattern = function() {\n\n      var pos = QRUtil.getPatternPosition(_typeNumber);\n\n      for (var i = 0; i < pos.length; i += 1) {\n\n        for (var j = 0; j < pos.length; j += 1) {\n\n          var row = pos[i];\n          var col = pos[j];\n\n          if (_modules[row][col] != null) {\n            continue;\n          }\n\n          for (var r = -2; r <= 2; r += 1) {\n\n            for (var c = -2; c <= 2; c += 1) {\n\n              if (r == -2 || r == 2 || c == -2 || c == 2\n                  || (r == 0 && c == 0) ) {\n                _modules[row + r][col + c] = true;\n              } else {\n                _modules[row + r][col + c] = false;\n              }\n            }\n          }\n        }\n      }\n    };\n\n    var setupTypeNumber = function(test) {\n\n      var bits = QRUtil.getBCHTypeNumber(_typeNumber);\n\n      for (var i = 0; i < 18; i += 1) {\n        var mod = (!test && ( (bits >> i) & 1) == 1);\n        _modules[Math.floor(i \/ 3)][i % 3 + _moduleCount - 8 - 3] = mod;\n      }\n\n      for (var i = 0; i < 18; i += 1) {\n        var mod = (!test && ( (bits >> i) & 1) == 1);\n        _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i \/ 3)] = mod;\n      }\n    };\n\n    var setupTypeInfo = function(test, maskPattern) {\n\n      var data = (_errorCorrectionLevel << 3) | maskPattern;\n      var bits = QRUtil.getBCHTypeInfo(data);\n\n      \/\/ vertical\n      for (var i = 0; i < 15; i += 1) {\n\n        var mod = (!test && ( (bits >> i) & 1) == 1);\n\n        if (i < 6) {\n          _modules[i][8] = mod;\n        } else if (i < 8) {\n          _modules[i + 1][8] = mod;\n        } else {\n          _modules[_moduleCount - 15 + i][8] = mod;\n        }\n      }\n\n      \/\/ horizontal\n      for (var i = 0; i < 15; i += 1) {\n\n        var mod = (!test && ( (bits >> i) & 1) == 1);\n\n        if (i < 8) {\n          _modules[8][_moduleCount - i - 1] = mod;\n        } else if (i < 9) {\n          _modules[8][15 - i - 1 + 1] = mod;\n        } else {\n          _modules[8][15 - i - 1] = mod;\n        }\n      }\n\n      \/\/ fixed module\n      _modules[_moduleCount - 8][8] = (!test);\n    };\n\n    var mapData = function(data, maskPattern) {\n\n      var inc = -1;\n      var row = _moduleCount - 1;\n      var bitIndex = 7;\n      var byteIndex = 0;\n      var maskFunc = QRUtil.getMaskFunction(maskPattern);\n\n      for (var col = _moduleCount - 1; col > 0; col -= 2) {\n\n        if (col == 6) col -= 1;\n\n        while (true) {\n\n          for (var c = 0; c < 2; c += 1) {\n\n            if (_modules[row][col - c] == null) {\n\n              var dark = false;\n\n              if (byteIndex < data.length) {\n                dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n              }\n\n              var mask = maskFunc(row, col - c);\n\n              if (mask) {\n                dark = !dark;\n              }\n\n              _modules[row][col - c] = dark;\n              bitIndex -= 1;\n\n              if (bitIndex == -1) {\n                byteIndex += 1;\n                bitIndex = 7;\n              }\n            }\n          }\n\n          row += inc;\n\n          if (row < 0 || _moduleCount <= row) {\n            row -= inc;\n            inc = -inc;\n            break;\n          }\n        }\n      }\n    };\n\n    var createBytes = function(buffer, rsBlocks) {\n\n      var offset = 0;\n\n      var maxDcCount = 0;\n      var maxEcCount = 0;\n\n      var dcdata = new Array(rsBlocks.length);\n      var ecdata = new Array(rsBlocks.length);\n\n      for (var r = 0; r < rsBlocks.length; r += 1) {\n\n        var dcCount = rsBlocks[r].dataCount;\n        var ecCount = rsBlocks[r].totalCount - dcCount;\n\n        maxDcCount = Math.max(maxDcCount, dcCount);\n        maxEcCount = Math.max(maxEcCount, ecCount);\n\n        dcdata[r] = new Array(dcCount);\n\n        for (var i = 0; i < dcdata[r].length; i += 1) {\n          dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];\n        }\n        offset += dcCount;\n\n        var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);\n        var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);\n\n        var modPoly = rawPoly.mod(rsPoly);\n        ecdata[r] = new Array(rsPoly.getLength() - 1);\n        for (var i = 0; i < ecdata[r].length; i += 1) {\n          var modIndex = i + modPoly.getLength() - ecdata[r].length;\n          ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;\n        }\n      }\n\n      var totalCodeCount = 0;\n      for (var i = 0; i < rsBlocks.length; i += 1) {\n        totalCodeCount += rsBlocks[i].totalCount;\n      }\n\n      var data = new Array(totalCodeCount);\n      var index = 0;\n\n      for (var i = 0; i < maxDcCount; i += 1) {\n        for (var r = 0; r < rsBlocks.length; r += 1) {\n          if (i < dcdata[r].length) {\n            data[index] = dcdata[r][i];\n            index += 1;\n          }\n        }\n      }\n\n      for (var i = 0; i < maxEcCount; i += 1) {\n        for (var r = 0; r < rsBlocks.length; r += 1) {\n          if (i < ecdata[r].length) {\n            data[index] = ecdata[r][i];\n            index += 1;\n          }\n        }\n      }\n\n      return data;\n    };\n\n    var createData = function(typeNumber, errorCorrectionLevel, dataList) {\n\n      var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);\n\n      var buffer = qrBitBuffer();\n\n      for (var i = 0; i < dataList.length; i += 1) {\n        var data = dataList[i];\n        buffer.put(data.getMode(), 4);\n        buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n        data.write(buffer);\n      }\n\n      \/\/ calc num max data.\n      var totalDataCount = 0;\n      for (var i = 0; i < rsBlocks.length; i += 1) {\n        totalDataCount += rsBlocks[i].dataCount;\n      }\n\n      if (buffer.getLengthInBits() > totalDataCount * 8) {\n        throw 'code length overflow. ('\n          + buffer.getLengthInBits()\n          + '>'\n          + totalDataCount * 8\n          + ')';\n      }\n\n      \/\/ end code\n      if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n        buffer.put(0, 4);\n      }\n\n      \/\/ padding\n      while (buffer.getLengthInBits() % 8 != 0) {\n        buffer.putBit(false);\n      }\n\n      \/\/ padding\n      while (true) {\n\n        if (buffer.getLengthInBits() >= totalDataCount * 8) {\n          break;\n        }\n        buffer.put(PAD0, 8);\n\n        if (buffer.getLengthInBits() >= totalDataCount * 8) {\n          break;\n        }\n        buffer.put(PAD1, 8);\n      }\n\n      return createBytes(buffer, rsBlocks);\n    };\n\n    _this.addData = function(data, mode) {\n\n      mode = mode || 'Byte';\n\n      var newData = null;\n\n      switch(mode) {\n      case 'Numeric' :\n        newData = qrNumber(data);\n        break;\n      case 'Alphanumeric' :\n        newData = qrAlphaNum(data);\n        break;\n      case 'Byte' :\n        newData = qr8BitByte(data);\n        break;\n      case 'Kanji' :\n        newData = qrKanji(data);\n        break;\n      default :\n        throw 'mode:' + mode;\n      }\n\n      _dataList.push(newData);\n      _dataCache = null;\n    };\n\n    _this.isDark = function(row, col) {\n      if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {\n        throw row + ',' + col;\n      }\n      return _modules[row][col];\n    };\n\n    _this.getModuleCount = function() {\n      return _moduleCount;\n    };\n\n    _this.make = function() {\n      if (_typeNumber < 1) {\n        var typeNumber = 1;\n\n        for (; typeNumber < 40; typeNumber++) {\n          var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);\n          var buffer = qrBitBuffer();\n\n          for (var i = 0; i < _dataList.length; i++) {\n            var data = _dataList[i];\n            buffer.put(data.getMode(), 4);\n            buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n            data.write(buffer);\n          }\n\n          var totalDataCount = 0;\n          for (var i = 0; i < rsBlocks.length; i++) {\n            totalDataCount += rsBlocks[i].dataCount;\n          }\n\n          if (buffer.getLengthInBits() <= totalDataCount * 8) {\n            break;\n          }\n        }\n\n        _typeNumber = typeNumber;\n      }\n\n      makeImpl(false, getBestMaskPattern() );\n    };\n\n    _this.createTableTag = function(cellSize, margin) {\n\n      cellSize = cellSize || 2;\n      margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n      var qrHtml = '';\n\n      qrHtml += '<table style=\"';\n      qrHtml += ' border-width: 0px; border-style: none;';\n      qrHtml += ' border-collapse: collapse;';\n      qrHtml += ' padding: 0px; margin: ' + margin + 'px;';\n      qrHtml += '\">';\n      qrHtml += '<tbody>';\n\n      for (var r = 0; r < _this.getModuleCount(); r += 1) {\n\n        qrHtml += '<tr>';\n\n        for (var c = 0; c < _this.getModuleCount(); c += 1) {\n          qrHtml += '<td style=\"';\n          qrHtml += ' border-width: 0px; border-style: none;';\n          qrHtml += ' border-collapse: collapse;';\n          qrHtml += ' padding: 0px; margin: 0px;';\n          qrHtml += ' width: ' + cellSize + 'px;';\n          qrHtml += ' height: ' + cellSize + 'px;';\n          qrHtml += ' background-color: ';\n          qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';\n          qrHtml += ';';\n          qrHtml += '\"\/>';\n        }\n\n        qrHtml += '<\/tr>';\n      }\n\n      qrHtml += '<\/tbody>';\n      qrHtml += '<\/table>';\n\n      return qrHtml;\n    };\n\n    _this.createSvgTag = function(cellSize, margin, alt, title) {\n\n      var opts = {};\n      if (typeof arguments[0] == 'object') {\n        \/\/ Called by options.\n        opts = arguments[0];\n        \/\/ overwrite cellSize and margin.\n        cellSize = opts.cellSize;\n        margin = opts.margin;\n        alt = opts.alt;\n        title = opts.title;\n      }\n\n      cellSize = cellSize || 2;\n      margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n      \/\/ Compose alt property surrogate\n      alt = (typeof alt === 'string') ? {text: alt} : alt || {};\n      alt.text = alt.text || null;\n      alt.id = (alt.text) ? alt.id || 'qrcode-description' : null;\n\n      \/\/ Compose title property surrogate\n      title = (typeof title === 'string') ? {text: title} : title || {};\n      title.text = title.text || null;\n      title.id = (title.text) ? title.id || 'qrcode-title' : null;\n\n      var size = _this.getModuleCount() * cellSize + margin * 2;\n      var c, mc, r, mr, qrSvg='', rect;\n\n      rect = 'l' + cellSize + ',0 0,' + cellSize +\n        ' -' + cellSize + ',0 0,-' + cellSize + 'z ';\n\n      qrSvg += '<svg version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"';\n      qrSvg += !opts.scalable ? ' width=\"' + size + 'px\" height=\"' + size + 'px\"' : '';\n      qrSvg += ' viewBox=\"0 0 ' + size + ' ' + size + '\" ';\n      qrSvg += ' preserveAspectRatio=\"xMinYMin meet\"';\n      qrSvg += (title.text || alt.text) ? ' role=\"img\" aria-labelledby=\"' +\n          escapeXml([title.id, alt.id].join(' ').trim() ) + '\"' : '';\n      qrSvg += '>';\n      qrSvg += (title.text) ? '<title id=\"' + escapeXml(title.id) + '\">' +\n          escapeXml(title.text) + '<\/title>' : '';\n      qrSvg += (alt.text) ? '<description id=\"' + escapeXml(alt.id) + '\">' +\n          escapeXml(alt.text) + '<\/description>' : '';\n      qrSvg += '<rect width=\"100%\" height=\"100%\" fill=\"white\" cx=\"0\" cy=\"0\"\/>';\n      qrSvg += '<path d=\"';\n\n      for (r = 0; r < _this.getModuleCount(); r += 1) {\n        mr = r * cellSize + margin;\n        for (c = 0; c < _this.getModuleCount(); c += 1) {\n          if (_this.isDark(r, c) ) {\n            mc = c*cellSize+margin;\n            qrSvg += 'M' + mc + ',' + mr + rect;\n          }\n        }\n      }\n\n      qrSvg += '\" stroke=\"transparent\" fill=\"black\"\/>';\n      qrSvg += '<\/svg>';\n\n      return qrSvg;\n    };\n\n    _this.createDataURL = function(cellSize, margin) {\n\n      cellSize = cellSize || 2;\n      margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n      var size = _this.getModuleCount() * cellSize + margin * 2;\n      var min = margin;\n      var max = size - margin;\n\n      return createDataURL(size, size, function(x, y) {\n        if (min <= x && x < max && min <= y && y < max) {\n          var c = Math.floor( (x - min) \/ cellSize);\n          var r = Math.floor( (y - min) \/ cellSize);\n          return _this.isDark(r, c)? 0 : 1;\n        } else {\n          return 1;\n        }\n      } );\n    };\n\n    _this.createImgTag = function(cellSize, margin, alt) {\n\n      cellSize = cellSize || 2;\n      margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n      var size = _this.getModuleCount() * cellSize + margin * 2;\n\n      var img = '';\n      img += '<img';\n      img += '\\u0020src=\"';\n      img += _this.createDataURL(cellSize, margin);\n      img += '\"';\n      img += '\\u0020width=\"';\n      img += size;\n      img += '\"';\n      img += '\\u0020height=\"';\n      img += size;\n      img += '\"';\n      if (alt) {\n        img += '\\u0020alt=\"';\n        img += escapeXml(alt);\n        img += '\"';\n      }\n      img += '\/>';\n\n      return img;\n    };\n\n    var escapeXml = function(s) {\n      var escaped = '';\n      for (var i = 0; i < s.length; i += 1) {\n        var c = s.charAt(i);\n        switch(c) {\n        case '<': escaped += '&lt;'; break;\n        case '>': escaped += '&gt;'; break;\n        case '&': escaped += '&amp;'; break;\n        case '\"': escaped += '&quot;'; break;\n        default : escaped += c; break;\n        }\n      }\n      return escaped;\n    };\n\n    var _createHalfASCII = function(margin) {\n      var cellSize = 1;\n      margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n      var size = _this.getModuleCount() * cellSize + margin * 2;\n      var min = margin;\n      var max = size - margin;\n\n      var y, x, r1, r2, p;\n\n      var blocks = {\n        '\u2588\u2588': '\u2588',\n        '\u2588 ': '\u2580',\n        ' \u2588': '\u2584',\n        '  ': ' '\n      };\n\n      var blocksLastLineNoMargin = {\n        '\u2588\u2588': '\u2580',\n        '\u2588 ': '\u2580',\n        ' \u2588': ' ',\n        '  ': ' '\n      };\n\n      var ascii = '';\n      for (y = 0; y < size; y += 2) {\n        r1 = Math.floor((y - min) \/ cellSize);\n        r2 = Math.floor((y + 1 - min) \/ cellSize);\n        for (x = 0; x < size; x += 1) {\n          p = '\u2588';\n\n          if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) \/ cellSize))) {\n            p = ' ';\n          }\n\n          if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) \/ cellSize))) {\n            p += ' ';\n          }\n          else {\n            p += '\u2588';\n          }\n\n          \/\/ Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n          ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p];\n        }\n\n        ascii += '\\n';\n      }\n\n      if (size % 2 && margin > 0) {\n        return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('\u2580');\n      }\n\n      return ascii.substring(0, ascii.length-1);\n    };\n\n    _this.createASCII = function(cellSize, margin) {\n      cellSize = cellSize || 1;\n\n      if (cellSize < 2) {\n        return _createHalfASCII(margin);\n      }\n\n      cellSize -= 1;\n      margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n      var size = _this.getModuleCount() * cellSize + margin * 2;\n      var min = margin;\n      var max = size - margin;\n\n      var y, x, r, p;\n\n      var white = Array(cellSize+1).join('\u2588\u2588');\n      var black = Array(cellSize+1).join('  ');\n\n      var ascii = '';\n      var line = '';\n      for (y = 0; y < size; y += 1) {\n        r = Math.floor( (y - min) \/ cellSize);\n        line = '';\n        for (x = 0; x < size; x += 1) {\n          p = 1;\n\n          if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) \/ cellSize))) {\n            p = 0;\n          }\n\n          \/\/ Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n          line += p ? white : black;\n        }\n\n        for (r = 0; r < cellSize; r += 1) {\n          ascii += line + '\\n';\n        }\n      }\n\n      return ascii.substring(0, ascii.length-1);\n    };\n\n    _this.renderTo2dContext = function(context, cellSize) {\n      cellSize = cellSize || 2;\n      var length = _this.getModuleCount();\n      for (var row = 0; row < length; row++) {\n        for (var col = 0; col < length; col++) {\n          context.fillStyle = _this.isDark(row, col) ? 'black' : 'white';\n          context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);\n        }\n      }\n    }\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrcode.stringToBytes\n  \/\/---------------------------------------------------------------------\n\n  qrcode.stringToBytesFuncs = {\n    'default' : function(s) {\n      var bytes = [];\n      for (var i = 0; i < s.length; i += 1) {\n        var c = s.charCodeAt(i);\n        bytes.push(c & 0xff);\n      }\n      return bytes;\n    }\n  };\n\n  qrcode.stringToBytes = qrcode.stringToBytesFuncs['default'];\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrcode.createStringToBytes\n  \/\/---------------------------------------------------------------------\n\n  \/**\n   * @param unicodeData base64 string of byte array.\n   * [16bit Unicode],[16bit Bytes], ...\n   * @param numChars\n   *\/\n  qrcode.createStringToBytes = function(unicodeData, numChars) {\n\n    \/\/ create conversion map.\n\n    var unicodeMap = function() {\n\n      var bin = base64DecodeInputStream(unicodeData);\n      var read = function() {\n        var b = bin.read();\n        if (b == -1) throw 'eof';\n        return b;\n      };\n\n      var count = 0;\n      var unicodeMap = {};\n      while (true) {\n        var b0 = bin.read();\n        if (b0 == -1) break;\n        var b1 = read();\n        var b2 = read();\n        var b3 = read();\n        var k = String.fromCharCode( (b0 << 8) | b1);\n        var v = (b2 << 8) | b3;\n        unicodeMap[k] = v;\n        count += 1;\n      }\n      if (count != numChars) {\n        throw count + ' != ' + numChars;\n      }\n\n      return unicodeMap;\n    }();\n\n    var unknownChar = '?'.charCodeAt(0);\n\n    return function(s) {\n      var bytes = [];\n      for (var i = 0; i < s.length; i += 1) {\n        var c = s.charCodeAt(i);\n        if (c < 128) {\n          bytes.push(c);\n        } else {\n          var b = unicodeMap[s.charAt(i)];\n          if (typeof b == 'number') {\n            if ( (b & 0xff) == b) {\n              \/\/ 1byte\n              bytes.push(b);\n            } else {\n              \/\/ 2bytes\n              bytes.push(b >>> 8);\n              bytes.push(b & 0xff);\n            }\n          } else {\n            bytes.push(unknownChar);\n          }\n        }\n      }\n      return bytes;\n    };\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRMode\n  \/\/---------------------------------------------------------------------\n\n  var QRMode = {\n    MODE_NUMBER :    1 << 0,\n    MODE_ALPHA_NUM : 1 << 1,\n    MODE_8BIT_BYTE : 1 << 2,\n    MODE_KANJI :     1 << 3\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRErrorCorrectionLevel\n  \/\/---------------------------------------------------------------------\n\n  var QRErrorCorrectionLevel = {\n    L : 1,\n    M : 0,\n    Q : 3,\n    H : 2\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRMaskPattern\n  \/\/---------------------------------------------------------------------\n\n  var QRMaskPattern = {\n    PATTERN000 : 0,\n    PATTERN001 : 1,\n    PATTERN010 : 2,\n    PATTERN011 : 3,\n    PATTERN100 : 4,\n    PATTERN101 : 5,\n    PATTERN110 : 6,\n    PATTERN111 : 7\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRUtil\n  \/\/---------------------------------------------------------------------\n\n  var QRUtil = function() {\n\n    var PATTERN_POSITION_TABLE = [\n      [],\n      [6, 18],\n      [6, 22],\n      [6, 26],\n      [6, 30],\n      [6, 34],\n      [6, 22, 38],\n      [6, 24, 42],\n      [6, 26, 46],\n      [6, 28, 50],\n      [6, 30, 54],\n      [6, 32, 58],\n      [6, 34, 62],\n      [6, 26, 46, 66],\n      [6, 26, 48, 70],\n      [6, 26, 50, 74],\n      [6, 30, 54, 78],\n      [6, 30, 56, 82],\n      [6, 30, 58, 86],\n      [6, 34, 62, 90],\n      [6, 28, 50, 72, 94],\n      [6, 26, 50, 74, 98],\n      [6, 30, 54, 78, 102],\n      [6, 28, 54, 80, 106],\n      [6, 32, 58, 84, 110],\n      [6, 30, 58, 86, 114],\n      [6, 34, 62, 90, 118],\n      [6, 26, 50, 74, 98, 122],\n      [6, 30, 54, 78, 102, 126],\n      [6, 26, 52, 78, 104, 130],\n      [6, 30, 56, 82, 108, 134],\n      [6, 34, 60, 86, 112, 138],\n      [6, 30, 58, 86, 114, 142],\n      [6, 34, 62, 90, 118, 146],\n      [6, 30, 54, 78, 102, 126, 150],\n      [6, 24, 50, 76, 102, 128, 154],\n      [6, 28, 54, 80, 106, 132, 158],\n      [6, 32, 58, 84, 110, 136, 162],\n      [6, 26, 54, 82, 110, 138, 166],\n      [6, 30, 58, 86, 114, 142, 170]\n    ];\n    var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);\n    var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);\n    var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);\n\n    var _this = {};\n\n    var getBCHDigit = function(data) {\n      var digit = 0;\n      while (data != 0) {\n        digit += 1;\n        data >>>= 1;\n      }\n      return digit;\n    };\n\n    _this.getBCHTypeInfo = function(data) {\n      var d = data << 10;\n      while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {\n        d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );\n      }\n      return ( (data << 10) | d) ^ G15_MASK;\n    };\n\n    _this.getBCHTypeNumber = function(data) {\n      var d = data << 12;\n      while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {\n        d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );\n      }\n      return (data << 12) | d;\n    };\n\n    _this.getPatternPosition = function(typeNumber) {\n      return PATTERN_POSITION_TABLE[typeNumber - 1];\n    };\n\n    _this.getMaskFunction = function(maskPattern) {\n\n      switch (maskPattern) {\n\n      case QRMaskPattern.PATTERN000 :\n        return function(i, j) { return (i + j) % 2 == 0; };\n      case QRMaskPattern.PATTERN001 :\n        return function(i, j) { return i % 2 == 0; };\n      case QRMaskPattern.PATTERN010 :\n        return function(i, j) { return j % 3 == 0; };\n      case QRMaskPattern.PATTERN011 :\n        return function(i, j) { return (i + j) % 3 == 0; };\n      case QRMaskPattern.PATTERN100 :\n        return function(i, j) { return (Math.floor(i \/ 2) + Math.floor(j \/ 3) ) % 2 == 0; };\n      case QRMaskPattern.PATTERN101 :\n        return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };\n      case QRMaskPattern.PATTERN110 :\n        return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };\n      case QRMaskPattern.PATTERN111 :\n        return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };\n\n      default :\n        throw 'bad maskPattern:' + maskPattern;\n      }\n    };\n\n    _this.getErrorCorrectPolynomial = function(errorCorrectLength) {\n      var a = qrPolynomial([1], 0);\n      for (var i = 0; i < errorCorrectLength; i += 1) {\n        a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );\n      }\n      return a;\n    };\n\n    _this.getLengthInBits = function(mode, type) {\n\n      if (1 <= type && type < 10) {\n\n        \/\/ 1 - 9\n\n        switch(mode) {\n        case QRMode.MODE_NUMBER    : return 10;\n        case QRMode.MODE_ALPHA_NUM : return 9;\n        case QRMode.MODE_8BIT_BYTE : return 8;\n        case QRMode.MODE_KANJI     : return 8;\n        default :\n          throw 'mode:' + mode;\n        }\n\n      } else if (type < 27) {\n\n        \/\/ 10 - 26\n\n        switch(mode) {\n        case QRMode.MODE_NUMBER    : return 12;\n        case QRMode.MODE_ALPHA_NUM : return 11;\n        case QRMode.MODE_8BIT_BYTE : return 16;\n        case QRMode.MODE_KANJI     : return 10;\n        default :\n          throw 'mode:' + mode;\n        }\n\n      } else if (type < 41) {\n\n        \/\/ 27 - 40\n\n        switch(mode) {\n        case QRMode.MODE_NUMBER    : return 14;\n        case QRMode.MODE_ALPHA_NUM : return 13;\n        case QRMode.MODE_8BIT_BYTE : return 16;\n        case QRMode.MODE_KANJI     : return 12;\n        default :\n          throw 'mode:' + mode;\n        }\n\n      } else {\n        throw 'type:' + type;\n      }\n    };\n\n    _this.getLostPoint = function(qrcode) {\n\n      var moduleCount = qrcode.getModuleCount();\n\n      var lostPoint = 0;\n\n      \/\/ LEVEL1\n\n      for (var row = 0; row < moduleCount; row += 1) {\n        for (var col = 0; col < moduleCount; col += 1) {\n\n          var sameCount = 0;\n          var dark = qrcode.isDark(row, col);\n\n          for (var r = -1; r <= 1; r += 1) {\n\n            if (row + r < 0 || moduleCount <= row + r) {\n              continue;\n            }\n\n            for (var c = -1; c <= 1; c += 1) {\n\n              if (col + c < 0 || moduleCount <= col + c) {\n                continue;\n              }\n\n              if (r == 0 && c == 0) {\n                continue;\n              }\n\n              if (dark == qrcode.isDark(row + r, col + c) ) {\n                sameCount += 1;\n              }\n            }\n          }\n\n          if (sameCount > 5) {\n            lostPoint += (3 + sameCount - 5);\n          }\n        }\n      };\n\n      \/\/ LEVEL2\n\n      for (var row = 0; row < moduleCount - 1; row += 1) {\n        for (var col = 0; col < moduleCount - 1; col += 1) {\n          var count = 0;\n          if (qrcode.isDark(row, col) ) count += 1;\n          if (qrcode.isDark(row + 1, col) ) count += 1;\n          if (qrcode.isDark(row, col + 1) ) count += 1;\n          if (qrcode.isDark(row + 1, col + 1) ) count += 1;\n          if (count == 0 || count == 4) {\n            lostPoint += 3;\n          }\n        }\n      }\n\n      \/\/ LEVEL3\n\n      for (var row = 0; row < moduleCount; row += 1) {\n        for (var col = 0; col < moduleCount - 6; col += 1) {\n          if (qrcode.isDark(row, col)\n              && !qrcode.isDark(row, col + 1)\n              &&  qrcode.isDark(row, col + 2)\n              &&  qrcode.isDark(row, col + 3)\n              &&  qrcode.isDark(row, col + 4)\n              && !qrcode.isDark(row, col + 5)\n              &&  qrcode.isDark(row, col + 6) ) {\n            lostPoint += 40;\n          }\n        }\n      }\n\n      for (var col = 0; col < moduleCount; col += 1) {\n        for (var row = 0; row < moduleCount - 6; row += 1) {\n          if (qrcode.isDark(row, col)\n              && !qrcode.isDark(row + 1, col)\n              &&  qrcode.isDark(row + 2, col)\n              &&  qrcode.isDark(row + 3, col)\n              &&  qrcode.isDark(row + 4, col)\n              && !qrcode.isDark(row + 5, col)\n              &&  qrcode.isDark(row + 6, col) ) {\n            lostPoint += 40;\n          }\n        }\n      }\n\n      \/\/ LEVEL4\n\n      var darkCount = 0;\n\n      for (var col = 0; col < moduleCount; col += 1) {\n        for (var row = 0; row < moduleCount; row += 1) {\n          if (qrcode.isDark(row, col) ) {\n            darkCount += 1;\n          }\n        }\n      }\n\n      var ratio = Math.abs(100 * darkCount \/ moduleCount \/ moduleCount - 50) \/ 5;\n      lostPoint += ratio * 10;\n\n      return lostPoint;\n    };\n\n    return _this;\n  }();\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRMath\n  \/\/---------------------------------------------------------------------\n\n  var QRMath = function() {\n\n    var EXP_TABLE = new Array(256);\n    var LOG_TABLE = new Array(256);\n\n    \/\/ initialize tables\n    for (var i = 0; i < 8; i += 1) {\n      EXP_TABLE[i] = 1 << i;\n    }\n    for (var i = 8; i < 256; i += 1) {\n      EXP_TABLE[i] = EXP_TABLE[i - 4]\n        ^ EXP_TABLE[i - 5]\n        ^ EXP_TABLE[i - 6]\n        ^ EXP_TABLE[i - 8];\n    }\n    for (var i = 0; i < 255; i += 1) {\n      LOG_TABLE[EXP_TABLE[i] ] = i;\n    }\n\n    var _this = {};\n\n    _this.glog = function(n) {\n\n      if (n < 1) {\n        throw 'glog(' + n + ')';\n      }\n\n      return LOG_TABLE[n];\n    };\n\n    _this.gexp = function(n) {\n\n      while (n < 0) {\n        n += 255;\n      }\n\n      while (n >= 256) {\n        n -= 255;\n      }\n\n      return EXP_TABLE[n];\n    };\n\n    return _this;\n  }();\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrPolynomial\n  \/\/---------------------------------------------------------------------\n\n  function qrPolynomial(num, shift) {\n\n    if (typeof num.length == 'undefined') {\n      throw num.length + '\/' + shift;\n    }\n\n    var _num = function() {\n      var offset = 0;\n      while (offset < num.length && num[offset] == 0) {\n        offset += 1;\n      }\n      var _num = new Array(num.length - offset + shift);\n      for (var i = 0; i < num.length - offset; i += 1) {\n        _num[i] = num[i + offset];\n      }\n      return _num;\n    }();\n\n    var _this = {};\n\n    _this.getAt = function(index) {\n      return _num[index];\n    };\n\n    _this.getLength = function() {\n      return _num.length;\n    };\n\n    _this.multiply = function(e) {\n\n      var num = new Array(_this.getLength() + e.getLength() - 1);\n\n      for (var i = 0; i < _this.getLength(); i += 1) {\n        for (var j = 0; j < e.getLength(); j += 1) {\n          num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );\n        }\n      }\n\n      return qrPolynomial(num, 0);\n    };\n\n    _this.mod = function(e) {\n\n      if (_this.getLength() - e.getLength() < 0) {\n        return _this;\n      }\n\n      var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );\n\n      var num = new Array(_this.getLength() );\n      for (var i = 0; i < _this.getLength(); i += 1) {\n        num[i] = _this.getAt(i);\n      }\n\n      for (var i = 0; i < e.getLength(); i += 1) {\n        num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);\n      }\n\n      \/\/ recursive call\n      return qrPolynomial(num, 0).mod(e);\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ QRRSBlock\n  \/\/---------------------------------------------------------------------\n\n  var QRRSBlock = function() {\n\n    var RS_BLOCK_TABLE = [\n\n      \/\/ L\n      \/\/ M\n      \/\/ Q\n      \/\/ H\n\n      \/\/ 1\n      [1, 26, 19],\n      [1, 26, 16],\n      [1, 26, 13],\n      [1, 26, 9],\n\n      \/\/ 2\n      [1, 44, 34],\n      [1, 44, 28],\n      [1, 44, 22],\n      [1, 44, 16],\n\n      \/\/ 3\n      [1, 70, 55],\n      [1, 70, 44],\n      [2, 35, 17],\n      [2, 35, 13],\n\n      \/\/ 4\n      [1, 100, 80],\n      [2, 50, 32],\n      [2, 50, 24],\n      [4, 25, 9],\n\n      \/\/ 5\n      [1, 134, 108],\n      [2, 67, 43],\n      [2, 33, 15, 2, 34, 16],\n      [2, 33, 11, 2, 34, 12],\n\n      \/\/ 6\n      [2, 86, 68],\n      [4, 43, 27],\n      [4, 43, 19],\n      [4, 43, 15],\n\n      \/\/ 7\n      [2, 98, 78],\n      [4, 49, 31],\n      [2, 32, 14, 4, 33, 15],\n      [4, 39, 13, 1, 40, 14],\n\n      \/\/ 8\n      [2, 121, 97],\n      [2, 60, 38, 2, 61, 39],\n      [4, 40, 18, 2, 41, 19],\n      [4, 40, 14, 2, 41, 15],\n\n      \/\/ 9\n      [2, 146, 116],\n      [3, 58, 36, 2, 59, 37],\n      [4, 36, 16, 4, 37, 17],\n      [4, 36, 12, 4, 37, 13],\n\n      \/\/ 10\n      [2, 86, 68, 2, 87, 69],\n      [4, 69, 43, 1, 70, 44],\n      [6, 43, 19, 2, 44, 20],\n      [6, 43, 15, 2, 44, 16],\n\n      \/\/ 11\n      [4, 101, 81],\n      [1, 80, 50, 4, 81, 51],\n      [4, 50, 22, 4, 51, 23],\n      [3, 36, 12, 8, 37, 13],\n\n      \/\/ 12\n      [2, 116, 92, 2, 117, 93],\n      [6, 58, 36, 2, 59, 37],\n      [4, 46, 20, 6, 47, 21],\n      [7, 42, 14, 4, 43, 15],\n\n      \/\/ 13\n      [4, 133, 107],\n      [8, 59, 37, 1, 60, 38],\n      [8, 44, 20, 4, 45, 21],\n      [12, 33, 11, 4, 34, 12],\n\n      \/\/ 14\n      [3, 145, 115, 1, 146, 116],\n      [4, 64, 40, 5, 65, 41],\n      [11, 36, 16, 5, 37, 17],\n      [11, 36, 12, 5, 37, 13],\n\n      \/\/ 15\n      [5, 109, 87, 1, 110, 88],\n      [5, 65, 41, 5, 66, 42],\n      [5, 54, 24, 7, 55, 25],\n      [11, 36, 12, 7, 37, 13],\n\n      \/\/ 16\n      [5, 122, 98, 1, 123, 99],\n      [7, 73, 45, 3, 74, 46],\n      [15, 43, 19, 2, 44, 20],\n      [3, 45, 15, 13, 46, 16],\n\n      \/\/ 17\n      [1, 135, 107, 5, 136, 108],\n      [10, 74, 46, 1, 75, 47],\n      [1, 50, 22, 15, 51, 23],\n      [2, 42, 14, 17, 43, 15],\n\n      \/\/ 18\n      [5, 150, 120, 1, 151, 121],\n      [9, 69, 43, 4, 70, 44],\n      [17, 50, 22, 1, 51, 23],\n      [2, 42, 14, 19, 43, 15],\n\n      \/\/ 19\n      [3, 141, 113, 4, 142, 114],\n      [3, 70, 44, 11, 71, 45],\n      [17, 47, 21, 4, 48, 22],\n      [9, 39, 13, 16, 40, 14],\n\n      \/\/ 20\n      [3, 135, 107, 5, 136, 108],\n      [3, 67, 41, 13, 68, 42],\n      [15, 54, 24, 5, 55, 25],\n      [15, 43, 15, 10, 44, 16],\n\n      \/\/ 21\n      [4, 144, 116, 4, 145, 117],\n      [17, 68, 42],\n      [17, 50, 22, 6, 51, 23],\n      [19, 46, 16, 6, 47, 17],\n\n      \/\/ 22\n      [2, 139, 111, 7, 140, 112],\n      [17, 74, 46],\n      [7, 54, 24, 16, 55, 25],\n      [34, 37, 13],\n\n      \/\/ 23\n      [4, 151, 121, 5, 152, 122],\n      [4, 75, 47, 14, 76, 48],\n      [11, 54, 24, 14, 55, 25],\n      [16, 45, 15, 14, 46, 16],\n\n      \/\/ 24\n      [6, 147, 117, 4, 148, 118],\n      [6, 73, 45, 14, 74, 46],\n      [11, 54, 24, 16, 55, 25],\n      [30, 46, 16, 2, 47, 17],\n\n      \/\/ 25\n      [8, 132, 106, 4, 133, 107],\n      [8, 75, 47, 13, 76, 48],\n      [7, 54, 24, 22, 55, 25],\n      [22, 45, 15, 13, 46, 16],\n\n      \/\/ 26\n      [10, 142, 114, 2, 143, 115],\n      [19, 74, 46, 4, 75, 47],\n      [28, 50, 22, 6, 51, 23],\n      [33, 46, 16, 4, 47, 17],\n\n      \/\/ 27\n      [8, 152, 122, 4, 153, 123],\n      [22, 73, 45, 3, 74, 46],\n      [8, 53, 23, 26, 54, 24],\n      [12, 45, 15, 28, 46, 16],\n\n      \/\/ 28\n      [3, 147, 117, 10, 148, 118],\n      [3, 73, 45, 23, 74, 46],\n      [4, 54, 24, 31, 55, 25],\n      [11, 45, 15, 31, 46, 16],\n\n      \/\/ 29\n      [7, 146, 116, 7, 147, 117],\n      [21, 73, 45, 7, 74, 46],\n      [1, 53, 23, 37, 54, 24],\n      [19, 45, 15, 26, 46, 16],\n\n      \/\/ 30\n      [5, 145, 115, 10, 146, 116],\n      [19, 75, 47, 10, 76, 48],\n      [15, 54, 24, 25, 55, 25],\n      [23, 45, 15, 25, 46, 16],\n\n      \/\/ 31\n      [13, 145, 115, 3, 146, 116],\n      [2, 74, 46, 29, 75, 47],\n      [42, 54, 24, 1, 55, 25],\n      [23, 45, 15, 28, 46, 16],\n\n      \/\/ 32\n      [17, 145, 115],\n      [10, 74, 46, 23, 75, 47],\n      [10, 54, 24, 35, 55, 25],\n      [19, 45, 15, 35, 46, 16],\n\n      \/\/ 33\n      [17, 145, 115, 1, 146, 116],\n      [14, 74, 46, 21, 75, 47],\n      [29, 54, 24, 19, 55, 25],\n      [11, 45, 15, 46, 46, 16],\n\n      \/\/ 34\n      [13, 145, 115, 6, 146, 116],\n      [14, 74, 46, 23, 75, 47],\n      [44, 54, 24, 7, 55, 25],\n      [59, 46, 16, 1, 47, 17],\n\n      \/\/ 35\n      [12, 151, 121, 7, 152, 122],\n      [12, 75, 47, 26, 76, 48],\n      [39, 54, 24, 14, 55, 25],\n      [22, 45, 15, 41, 46, 16],\n\n      \/\/ 36\n      [6, 151, 121, 14, 152, 122],\n      [6, 75, 47, 34, 76, 48],\n      [46, 54, 24, 10, 55, 25],\n      [2, 45, 15, 64, 46, 16],\n\n      \/\/ 37\n      [17, 152, 122, 4, 153, 123],\n      [29, 74, 46, 14, 75, 47],\n      [49, 54, 24, 10, 55, 25],\n      [24, 45, 15, 46, 46, 16],\n\n      \/\/ 38\n      [4, 152, 122, 18, 153, 123],\n      [13, 74, 46, 32, 75, 47],\n      [48, 54, 24, 14, 55, 25],\n      [42, 45, 15, 32, 46, 16],\n\n      \/\/ 39\n      [20, 147, 117, 4, 148, 118],\n      [40, 75, 47, 7, 76, 48],\n      [43, 54, 24, 22, 55, 25],\n      [10, 45, 15, 67, 46, 16],\n\n      \/\/ 40\n      [19, 148, 118, 6, 149, 119],\n      [18, 75, 47, 31, 76, 48],\n      [34, 54, 24, 34, 55, 25],\n      [20, 45, 15, 61, 46, 16]\n    ];\n\n    var qrRSBlock = function(totalCount, dataCount) {\n      var _this = {};\n      _this.totalCount = totalCount;\n      _this.dataCount = dataCount;\n      return _this;\n    };\n\n    var _this = {};\n\n    var getRsBlockTable = function(typeNumber, errorCorrectionLevel) {\n\n      switch(errorCorrectionLevel) {\n      case QRErrorCorrectionLevel.L :\n        return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n      case QRErrorCorrectionLevel.M :\n        return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n      case QRErrorCorrectionLevel.Q :\n        return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n      case QRErrorCorrectionLevel.H :\n        return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n      default :\n        return undefined;\n      }\n    };\n\n    _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {\n\n      var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);\n\n      if (typeof rsBlock == 'undefined') {\n        throw 'bad rs block @ typeNumber:' + typeNumber +\n            '\/errorCorrectionLevel:' + errorCorrectionLevel;\n      }\n\n      var length = rsBlock.length \/ 3;\n\n      var list = [];\n\n      for (var i = 0; i < length; i += 1) {\n\n        var count = rsBlock[i * 3 + 0];\n        var totalCount = rsBlock[i * 3 + 1];\n        var dataCount = rsBlock[i * 3 + 2];\n\n        for (var j = 0; j < count; j += 1) {\n          list.push(qrRSBlock(totalCount, dataCount) );\n        }\n      }\n\n      return list;\n    };\n\n    return _this;\n  }();\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrBitBuffer\n  \/\/---------------------------------------------------------------------\n\n  var qrBitBuffer = function() {\n\n    var _buffer = [];\n    var _length = 0;\n\n    var _this = {};\n\n    _this.getBuffer = function() {\n      return _buffer;\n    };\n\n    _this.getAt = function(index) {\n      var bufIndex = Math.floor(index \/ 8);\n      return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n    };\n\n    _this.put = function(num, length) {\n      for (var i = 0; i < length; i += 1) {\n        _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n      }\n    };\n\n    _this.getLengthInBits = function() {\n      return _length;\n    };\n\n    _this.putBit = function(bit) {\n\n      var bufIndex = Math.floor(_length \/ 8);\n      if (_buffer.length <= bufIndex) {\n        _buffer.push(0);\n      }\n\n      if (bit) {\n        _buffer[bufIndex] |= (0x80 >>> (_length % 8) );\n      }\n\n      _length += 1;\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrNumber\n  \/\/---------------------------------------------------------------------\n\n  var qrNumber = function(data) {\n\n    var _mode = QRMode.MODE_NUMBER;\n    var _data = data;\n\n    var _this = {};\n\n    _this.getMode = function() {\n      return _mode;\n    };\n\n    _this.getLength = function(buffer) {\n      return _data.length;\n    };\n\n    _this.write = function(buffer) {\n\n      var data = _data;\n\n      var i = 0;\n\n      while (i + 2 < data.length) {\n        buffer.put(strToNum(data.substring(i, i + 3) ), 10);\n        i += 3;\n      }\n\n      if (i < data.length) {\n        if (data.length - i == 1) {\n          buffer.put(strToNum(data.substring(i, i + 1) ), 4);\n        } else if (data.length - i == 2) {\n          buffer.put(strToNum(data.substring(i, i + 2) ), 7);\n        }\n      }\n    };\n\n    var strToNum = function(s) {\n      var num = 0;\n      for (var i = 0; i < s.length; i += 1) {\n        num = num * 10 + chatToNum(s.charAt(i) );\n      }\n      return num;\n    };\n\n    var chatToNum = function(c) {\n      if ('0' <= c && c <= '9') {\n        return c.charCodeAt(0) - '0'.charCodeAt(0);\n      }\n      throw 'illegal char :' + c;\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrAlphaNum\n  \/\/---------------------------------------------------------------------\n\n  var qrAlphaNum = function(data) {\n\n    var _mode = QRMode.MODE_ALPHA_NUM;\n    var _data = data;\n\n    var _this = {};\n\n    _this.getMode = function() {\n      return _mode;\n    };\n\n    _this.getLength = function(buffer) {\n      return _data.length;\n    };\n\n    _this.write = function(buffer) {\n\n      var s = _data;\n\n      var i = 0;\n\n      while (i + 1 < s.length) {\n        buffer.put(\n          getCode(s.charAt(i) ) * 45 +\n          getCode(s.charAt(i + 1) ), 11);\n        i += 2;\n      }\n\n      if (i < s.length) {\n        buffer.put(getCode(s.charAt(i) ), 6);\n      }\n    };\n\n    var getCode = function(c) {\n\n      if ('0' <= c && c <= '9') {\n        return c.charCodeAt(0) - '0'.charCodeAt(0);\n      } else if ('A' <= c && c <= 'Z') {\n        return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;\n      } else {\n        switch (c) {\n        case ' ' : return 36;\n        case '$' : return 37;\n        case '%' : return 38;\n        case '*' : return 39;\n        case '+' : return 40;\n        case '-' : return 41;\n        case '.' : return 42;\n        case '\/' : return 43;\n        case ':' : return 44;\n        default :\n          throw 'illegal char :' + c;\n        }\n      }\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qr8BitByte\n  \/\/---------------------------------------------------------------------\n\n  var qr8BitByte = function(data) {\n\n    var _mode = QRMode.MODE_8BIT_BYTE;\n    var _data = data;\n    var _bytes = qrcode.stringToBytes(data);\n\n    var _this = {};\n\n    _this.getMode = function() {\n      return _mode;\n    };\n\n    _this.getLength = function(buffer) {\n      return _bytes.length;\n    };\n\n    _this.write = function(buffer) {\n      for (var i = 0; i < _bytes.length; i += 1) {\n        buffer.put(_bytes[i], 8);\n      }\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ qrKanji\n  \/\/---------------------------------------------------------------------\n\n  var qrKanji = function(data) {\n\n    var _mode = QRMode.MODE_KANJI;\n    var _data = data;\n\n    var stringToBytes = qrcode.stringToBytesFuncs['SJIS'];\n    if (!stringToBytes) {\n      throw 'sjis not supported.';\n    }\n    !function(c, code) {\n      \/\/ self test for sjis support.\n      var test = stringToBytes(c);\n      if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {\n        throw 'sjis not supported.';\n      }\n    }('\\u53cb', 0x9746);\n\n    var _bytes = stringToBytes(data);\n\n    var _this = {};\n\n    _this.getMode = function() {\n      return _mode;\n    };\n\n    _this.getLength = function(buffer) {\n      return ~~(_bytes.length \/ 2);\n    };\n\n    _this.write = function(buffer) {\n\n      var data = _bytes;\n\n      var i = 0;\n\n      while (i + 1 < data.length) {\n\n        var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);\n\n        if (0x8140 <= c && c <= 0x9FFC) {\n          c -= 0x8140;\n        } else if (0xE040 <= c && c <= 0xEBBF) {\n          c -= 0xC140;\n        } else {\n          throw 'illegal char at ' + (i + 1) + '\/' + c;\n        }\n\n        c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);\n\n        buffer.put(c, 13);\n\n        i += 2;\n      }\n\n      if (i < data.length) {\n        throw 'illegal char at ' + (i + 1);\n      }\n    };\n\n    return _this;\n  };\n\n  \/\/=====================================================================\n  \/\/ GIF Support etc.\n  \/\/\n\n  \/\/---------------------------------------------------------------------\n  \/\/ byteArrayOutputStream\n  \/\/---------------------------------------------------------------------\n\n  var byteArrayOutputStream = function() {\n\n    var _bytes = [];\n\n    var _this = {};\n\n    _this.writeByte = function(b) {\n      _bytes.push(b & 0xff);\n    };\n\n    _this.writeShort = function(i) {\n      _this.writeByte(i);\n      _this.writeByte(i >>> 8);\n    };\n\n    _this.writeBytes = function(b, off, len) {\n      off = off || 0;\n      len = len || b.length;\n      for (var i = 0; i < len; i += 1) {\n        _this.writeByte(b[i + off]);\n      }\n    };\n\n    _this.writeString = function(s) {\n      for (var i = 0; i < s.length; i += 1) {\n        _this.writeByte(s.charCodeAt(i) );\n      }\n    };\n\n    _this.toByteArray = function() {\n      return _bytes;\n    };\n\n    _this.toString = function() {\n      var s = '';\n      s += '[';\n      for (var i = 0; i < _bytes.length; i += 1) {\n        if (i > 0) {\n          s += ',';\n        }\n        s += _bytes[i];\n      }\n      s += ']';\n      return s;\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ base64EncodeOutputStream\n  \/\/---------------------------------------------------------------------\n\n  var base64EncodeOutputStream = function() {\n\n    var _buffer = 0;\n    var _buflen = 0;\n    var _length = 0;\n    var _base64 = '';\n\n    var _this = {};\n\n    var writeEncoded = function(b) {\n      _base64 += String.fromCharCode(encode(b & 0x3f) );\n    };\n\n    var encode = function(n) {\n      if (n < 0) {\n        \/\/ error.\n      } else if (n < 26) {\n        return 0x41 + n;\n      } else if (n < 52) {\n        return 0x61 + (n - 26);\n      } else if (n < 62) {\n        return 0x30 + (n - 52);\n      } else if (n == 62) {\n        return 0x2b;\n      } else if (n == 63) {\n        return 0x2f;\n      }\n      throw 'n:' + n;\n    };\n\n    _this.writeByte = function(n) {\n\n      _buffer = (_buffer << 8) | (n & 0xff);\n      _buflen += 8;\n      _length += 1;\n\n      while (_buflen >= 6) {\n        writeEncoded(_buffer >>> (_buflen - 6) );\n        _buflen -= 6;\n      }\n    };\n\n    _this.flush = function() {\n\n      if (_buflen > 0) {\n        writeEncoded(_buffer << (6 - _buflen) );\n        _buffer = 0;\n        _buflen = 0;\n      }\n\n      if (_length % 3 != 0) {\n        \/\/ padding\n        var padlen = 3 - _length % 3;\n        for (var i = 0; i < padlen; i += 1) {\n          _base64 += '=';\n        }\n      }\n    };\n\n    _this.toString = function() {\n      return _base64;\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ base64DecodeInputStream\n  \/\/---------------------------------------------------------------------\n\n  var base64DecodeInputStream = function(str) {\n\n    var _str = str;\n    var _pos = 0;\n    var _buffer = 0;\n    var _buflen = 0;\n\n    var _this = {};\n\n    _this.read = function() {\n\n      while (_buflen < 8) {\n\n        if (_pos >= _str.length) {\n          if (_buflen == 0) {\n            return -1;\n          }\n          throw 'unexpected end of file.\/' + _buflen;\n        }\n\n        var c = _str.charAt(_pos);\n        _pos += 1;\n\n        if (c == '=') {\n          _buflen = 0;\n          return -1;\n        } else if (c.match(\/^\\s$\/) ) {\n          \/\/ ignore if whitespace.\n          continue;\n        }\n\n        _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );\n        _buflen += 6;\n      }\n\n      var n = (_buffer >>> (_buflen - 8) ) & 0xff;\n      _buflen -= 8;\n      return n;\n    };\n\n    var decode = function(c) {\n      if (0x41 <= c && c <= 0x5a) {\n        return c - 0x41;\n      } else if (0x61 <= c && c <= 0x7a) {\n        return c - 0x61 + 26;\n      } else if (0x30 <= c && c <= 0x39) {\n        return c - 0x30 + 52;\n      } else if (c == 0x2b) {\n        return 62;\n      } else if (c == 0x2f) {\n        return 63;\n      } else {\n        throw 'c:' + c;\n      }\n    };\n\n    return _this;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ gifImage (B\/W)\n  \/\/---------------------------------------------------------------------\n\n  var gifImage = function(width, height) {\n\n    var _width = width;\n    var _height = height;\n    var _data = new Array(width * height);\n\n    var _this = {};\n\n    _this.setPixel = function(x, y, pixel) {\n      _data[y * _width + x] = pixel;\n    };\n\n    _this.write = function(out) {\n\n      \/\/---------------------------------\n      \/\/ GIF Signature\n\n      out.writeString('GIF87a');\n\n      \/\/---------------------------------\n      \/\/ Screen Descriptor\n\n      out.writeShort(_width);\n      out.writeShort(_height);\n\n      out.writeByte(0x80); \/\/ 2bit\n      out.writeByte(0);\n      out.writeByte(0);\n\n      \/\/---------------------------------\n      \/\/ Global Color Map\n\n      \/\/ black\n      out.writeByte(0x00);\n      out.writeByte(0x00);\n      out.writeByte(0x00);\n\n      \/\/ white\n      out.writeByte(0xff);\n      out.writeByte(0xff);\n      out.writeByte(0xff);\n\n      \/\/---------------------------------\n      \/\/ Image Descriptor\n\n      out.writeString(',');\n      out.writeShort(0);\n      out.writeShort(0);\n      out.writeShort(_width);\n      out.writeShort(_height);\n      out.writeByte(0);\n\n      \/\/---------------------------------\n      \/\/ Local Color Map\n\n      \/\/---------------------------------\n      \/\/ Raster Data\n\n      var lzwMinCodeSize = 2;\n      var raster = getLZWRaster(lzwMinCodeSize);\n\n      out.writeByte(lzwMinCodeSize);\n\n      var offset = 0;\n\n      while (raster.length - offset > 255) {\n        out.writeByte(255);\n        out.writeBytes(raster, offset, 255);\n        offset += 255;\n      }\n\n      out.writeByte(raster.length - offset);\n      out.writeBytes(raster, offset, raster.length - offset);\n      out.writeByte(0x00);\n\n      \/\/---------------------------------\n      \/\/ GIF Terminator\n      out.writeString(';');\n    };\n\n    var bitOutputStream = function(out) {\n\n      var _out = out;\n      var _bitLength = 0;\n      var _bitBuffer = 0;\n\n      var _this = {};\n\n      _this.write = function(data, length) {\n\n        if ( (data >>> length) != 0) {\n          throw 'length over';\n        }\n\n        while (_bitLength + length >= 8) {\n          _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );\n          length -= (8 - _bitLength);\n          data >>>= (8 - _bitLength);\n          _bitBuffer = 0;\n          _bitLength = 0;\n        }\n\n        _bitBuffer = (data << _bitLength) | _bitBuffer;\n        _bitLength = _bitLength + length;\n      };\n\n      _this.flush = function() {\n        if (_bitLength > 0) {\n          _out.writeByte(_bitBuffer);\n        }\n      };\n\n      return _this;\n    };\n\n    var getLZWRaster = function(lzwMinCodeSize) {\n\n      var clearCode = 1 << lzwMinCodeSize;\n      var endCode = (1 << lzwMinCodeSize) + 1;\n      var bitLength = lzwMinCodeSize + 1;\n\n      \/\/ Setup LZWTable\n      var table = lzwTable();\n\n      for (var i = 0; i < clearCode; i += 1) {\n        table.add(String.fromCharCode(i) );\n      }\n      table.add(String.fromCharCode(clearCode) );\n      table.add(String.fromCharCode(endCode) );\n\n      var byteOut = byteArrayOutputStream();\n      var bitOut = bitOutputStream(byteOut);\n\n      \/\/ clear code\n      bitOut.write(clearCode, bitLength);\n\n      var dataIndex = 0;\n\n      var s = String.fromCharCode(_data[dataIndex]);\n      dataIndex += 1;\n\n      while (dataIndex < _data.length) {\n\n        var c = String.fromCharCode(_data[dataIndex]);\n        dataIndex += 1;\n\n        if (table.contains(s + c) ) {\n\n          s = s + c;\n\n        } else {\n\n          bitOut.write(table.indexOf(s), bitLength);\n\n          if (table.size() < 0xfff) {\n\n            if (table.size() == (1 << bitLength) ) {\n              bitLength += 1;\n            }\n\n            table.add(s + c);\n          }\n\n          s = c;\n        }\n      }\n\n      bitOut.write(table.indexOf(s), bitLength);\n\n      \/\/ end code\n      bitOut.write(endCode, bitLength);\n\n      bitOut.flush();\n\n      return byteOut.toByteArray();\n    };\n\n    var lzwTable = function() {\n\n      var _map = {};\n      var _size = 0;\n\n      var _this = {};\n\n      _this.add = function(key) {\n        if (_this.contains(key) ) {\n          throw 'dup key:' + key;\n        }\n        _map[key] = _size;\n        _size += 1;\n      };\n\n      _this.size = function() {\n        return _size;\n      };\n\n      _this.indexOf = function(key) {\n        return _map[key];\n      };\n\n      _this.contains = function(key) {\n        return typeof _map[key] != 'undefined';\n      };\n\n      return _this;\n    };\n\n    return _this;\n  };\n\n  var createDataURL = function(width, height, getPixel) {\n    var gif = gifImage(width, height);\n    for (var y = 0; y < height; y += 1) {\n      for (var x = 0; x < width; x += 1) {\n        gif.setPixel(x, y, getPixel(x, y) );\n      }\n    }\n\n    var b = byteArrayOutputStream();\n    gif.write(b);\n\n    var base64 = base64EncodeOutputStream();\n    var bytes = b.toByteArray();\n    for (var i = 0; i < bytes.length; i += 1) {\n      base64.writeByte(bytes[i]);\n    }\n    base64.flush();\n\n    return 'data:image\/gif;base64,' + base64;\n  };\n\n  \/\/---------------------------------------------------------------------\n  \/\/ returns qrcode function.\n\n  return qrcode;\n}();\n\n\/\/ multibyte support\n!function() {\n\n  qrcode.stringToBytesFuncs['UTF-8'] = function(s) {\n    \/\/ http:\/\/stackoverflow.com\/questions\/18729405\/how-to-convert-utf8-string-to-byte-array\n    function toUTF8Array(str) {\n      var utf8 = [];\n      for (var i=0; i < str.length; i++) {\n        var charcode = str.charCodeAt(i);\n        if (charcode < 0x80) utf8.push(charcode);\n        else if (charcode < 0x800) {\n          utf8.push(0xc0 | (charcode >> 6),\n              0x80 | (charcode & 0x3f));\n        }\n        else if (charcode < 0xd800 || charcode >= 0xe000) {\n          utf8.push(0xe0 | (charcode >> 12),\n              0x80 | ((charcode>>6) & 0x3f),\n              0x80 | (charcode & 0x3f));\n        }\n        \/\/ surrogate pair\n        else {\n          i++;\n          \/\/ UTF-16 encodes 0x10000-0x10FFFF by\n          \/\/ subtracting 0x10000 and splitting the\n          \/\/ 20 bits of 0x0-0xFFFFF into two halves\n          charcode = 0x10000 + (((charcode & 0x3ff)<<10)\n            | (str.charCodeAt(i) & 0x3ff));\n          utf8.push(0xf0 | (charcode >>18),\n              0x80 | ((charcode>>12) & 0x3f),\n              0x80 | ((charcode>>6) & 0x3f),\n              0x80 | (charcode & 0x3f));\n        }\n      }\n      return utf8;\n    }\n    return toUTF8Array(s);\n  };\n\n}();\n\n(function (factory) {\n  if (typeof define === 'function' && define.amd) {\n      define([], factory);\n  } else if (typeof exports === 'object') {\n      module.exports = factory();\n  }\n}(function () {\n    return qrcode;\n}));\n\n\/\/---------------------------------------------------------------------\n\/\/\n\/\/ QR Code Generator for JavaScript UTF8 Support (optional)\n\/\/\n\/\/ Copyright (c) 2011 Kazuhiko Arase\n\/\/\n\/\/ URL: http:\/\/www.d-project.com\/\n\/\/\n\/\/ Licensed under the MIT license:\n\/\/  http:\/\/www.opensource.org\/licenses\/mit-license.php\n\/\/\n\/\/ The word 'QR Code' is registered trademark of\n\/\/ DENSO WAVE INCORPORATED\n\/\/  http:\/\/www.denso-wave.com\/qrcode\/faqpatent-e.html\n\/\/\n\/\/---------------------------------------------------------------------\n\n!function(qrcode) {\n\n  \/\/---------------------------------------------------------------------\n  \/\/ overwrite qrcode.stringToBytes\n  \/\/---------------------------------------------------------------------\n\n  qrcode.stringToBytes = qrcode.stringToBytesFuncs['UTF-8'];\n\n}(qrcode);\n\nfunction youtubeId(input) {\n  const value = input.trim();\n  if (\/^[\\w-]{11}$\/.test(value)) return value;\n  let url; try { url = new URL(\/^https?:\\\/\\\/\/i.test(value) ? value : `https:\/\/${value}`); } catch { throw Error('Enter a YouTube video URL or an 11-character video ID.'); }\n  const host = url.hostname.toLowerCase();\n  let id;\n  if (host === 'youtu.be') id = url.pathname.split('\/')[1];\n  else if (['youtube.com','www.youtube.com','m.youtube.com','music.youtube.com','www.youtube-nocookie.com','youtube-nocookie.com'].includes(host)) {\n    id = url.pathname === '\/watch' ? url.searchParams.get('v') : \/^\\\/(shorts|embed|live)\\\/\/.test(url.pathname) ? url.pathname.split('\/')[2] : '';\n  }\n  if (!\/^[\\w-]{11}$\/.test(id || '')) throw Error('Use a valid YouTube watch, Shorts, embed, or youtu.be link.');\n  return id;\n}\nfunction randomIndex(n, cryptoSource = globalThis.crypto) {\n  if (!Number.isInteger(n) || n < 1) throw Error('Invalid character set.');\n  const ceiling = Math.floor(4294967296 \/ n) * n;\n  const values = new Uint32Array(1);\n  do { cryptoSource.getRandomValues(values); } while (values[0] >= ceiling);\n  return values[0] % n;\n}\nfunction makePassword(length, groups, excludeSimilar = false) {\n  const sets = groups.map(s => excludeSimilar ? s.replace(\/[Il1O0o]\/g, '') : s).filter(Boolean);\n  if (!sets.length) throw Error('Select at least one character type.');\n  if (!Number.isInteger(length) || length < 8 || length > 128) throw Error('Choose a length from 8 to 128.');\n  const alphabet = sets.join('');\n  \/\/ Rejection sampling gives equal probability to every string satisfying the selected types.\n  let password;\n  do { password = Array.from({length}, () => alphabet[randomIndex(alphabet.length)]).join(''); }\n  while (!sets.every(set => [...password].some(c => set.includes(c))));\n  return password;\n}\nfunction formatJSON(text, spaces = 2) {\n  if (text.length > 2_000_000) throw Error('Use JSON smaller than 2 MB.');\n  if (![0,2,4].includes(spaces)) throw Error('Choose 0, 2 or 4 spaces.');\n  const data = JSON.parse(text);\n  \/\/ Preserve numeric lexemes (including integers outside the safe JS range) with a lexical formatter.\n  let out = '', depth = 0, quoted = false, escaped = false, previous = '';\n  const indent = n => ' '.repeat(n * spaces);\n  for (let i = 0; i < text.length; i++) {\n    const c = text[i];\n    if (quoted) { out += c; if (escaped) escaped = false; else if (c === '\\\\') escaped = true; else if (c === '\"') quoted = false; continue; }\n    if (c === '\"') { quoted = true; out += c; previous = c; continue; }\n    if (\/\\s\/.test(c)) continue;\n    if (c === '{' || c === '[') { out += c; depth++; if (spaces && depth > 128) throw Error('This JSON is too deeply nested to format. Try Minify.'); let next=i+1; while (\/\\s\/.test(text[next] || '') && next<text.length) next++; if (spaces && text[next]!=='}' && text[next]!==']') out += '\\n' + indent(depth); }\n    else if (c === '}' || c === ']') { depth--; if (spaces && previous!=='{' && previous!=='[') out += '\\n' + indent(depth); out += c; }\n    else if (c === ',') out += ',' + (spaces ? '\\n' + indent(depth) : '');\n    else if (c === ':') out += ':' + (spaces ? ' ' : '');\n    else out += c;\n    previous = c;\n    if (out.length > 8_000_000) throw Error('Formatted output is too large. Try Minify.');\n  }\n  return {text:out, type:Array.isArray(data)?'array':data===null?'null':typeof data};\n}\nfunction icoFile(pngs) {\n  const header = new Uint8Array(6 + pngs.length * 16); const view = new DataView(header.buffer);\n  view.setUint16(2,1,true); view.setUint16(4,pngs.length,true);\n  let offset = header.length;\n  pngs.forEach(({size,bytes},i) => { const p=6+i*16; view.setUint8(p,size===256?0:size); view.setUint8(p+1,size===256?0:size); view.setUint16(p+4,1,true); view.setUint16(p+6,32,true); view.setUint32(p+8,bytes.length,true); view.setUint32(p+12,offset,true); offset+=bytes.length; });\n  return new Blob([header,...pngs.map(p=>p.bytes)],{type:'image\/x-icon'});\n}\n\n\/\/ Shared, page-local runtime. No analytics, storage or uploads.\nconst $=id=>root.querySelector('#'+id);\nconst status=(message='',error=false)=>{ $('status').textContent=message; $('status').dataset.error=String(error); };\nconst on=(id,event,fn)=>$(id).addEventListener(event,async e=>{try{await fn(e);}catch(error){status(error.message||'Something went wrong. Please try again.',true);}});\nconst enable=(ids,value=true)=>ids.forEach(id=>$(id).disabled=!value);\nconst number=(id,min,max)=>{const n=Number($(id).value);if(!Number.isInteger(n)||n<min||n>max)throw Error(`Choose ${id} between ${min} and ${max}.`);return n;};\nconst canvas=(width,height)=>{if(width*height>30_000_000)throw Error('The resulting image is too large. Use a smaller image.');const c=document.createElement('canvas');c.width=width;c.height=height;return c;};\nconst blob=c=>new Promise((resolve,reject)=>c.toBlob(b=>b?resolve(b):reject(Error('Unable to export this image.')),'image\/png'));\nconst urls=new Set();\nconst objectURL=b=>{const url=URL.createObjectURL(b);urls.add(url);return url;};\nconst release=url=>{if(url){URL.revokeObjectURL(url);urls.delete(url);}};\nconst download=(data,name)=>{const url=objectURL(data),a=document.createElement('a');a.href=url;a.download=name;a.click();setTimeout(()=>release(url),30000);};\nconst copy=async text=>{try{await navigator.clipboard.writeText(text);status('Copied to clipboard.');}catch{throw Error('Clipboard permission was blocked. Select and copy the output manually.');}};\nconst filesize=n=>n<1024?`${n} B`:`${(n\/1024\/1024).toFixed(2)} MB`;\nconst image=async(file,limit=20)=>{if(!file)throw Error('Choose an image first.');if(!\/^image\\\/(png|jpeg|webp)$\/.test(file.type))throw Error('Choose a PNG, JPG or WebP image.');if(file.size>limit*1024*1024)throw Error(`Choose an image smaller than ${limit} MB.`);let img;if('createImageBitmap'in globalThis){img=await createImageBitmap(file);}else{const url=URL.createObjectURL(file);try{img=await new Promise((resolve,reject)=>{const element=new Image;element.onload=()=>resolve(element);element.onerror=()=>reject(Error('Unable to decode this image.'));element.src=url;});img.close=()=>{};}finally{URL.revokeObjectURL(url);}}if(img.width*img.height>24_000_000){img.close();throw Error('Use an image with fewer than 24 million pixels.');}return img;};\nconst readData=file=>new Promise((resolve,reject)=>{const r=new FileReader();r.onload=()=>resolve(r.result);r.onerror=()=>reject(Error('Unable to read this file.'));r.readAsDataURL(file);});\nwindow.addEventListener('pagehide',()=>urls.forEach(url=>URL.revokeObjectURL(url)));\nroot.dataset.runtimeReady='true';\nstatus('Ready.');\n\nif(root.dataset.tool==='image-border'){\n let source,output,version=0;\n const render=()=>{enable(['download'],false);if(!source)return;const border=number('border',0,200),pad=number('padding',0,200),margin=border+pad;c: {output=canvas(source.width+margin*2,source.height+margin*2);const ctx=output.getContext('2d');ctx.fillStyle=$('borderColor').value;ctx.fillRect(0,0,output.width,output.height);ctx.clearRect(border,border,output.width-border*2,output.height-border*2);if(!$('transparent').checked){ctx.fillStyle=$('paddingColor').value;ctx.fillRect(border,border,output.width-border*2,output.height-border*2);}ctx.drawImage(source,margin,margin);$('stage').replaceChildren(output);}enable(['download']);status(`${output.width} \u00d7 ${output.height} px \u00b7 PNG export`);};\n on('file','change',async()=>{const token=++version;enable(['download'],false);source?.close();source=null;const next=await image($('file').files[0]);if(token!==version){next.close();return;}source=next;render();});\n ['border','padding','borderColor','paddingColor','transparent'].forEach(id=>on(id,'input',render));\n on('download','click',async()=>download(await blob(output),'aitoolsoft-bordered.png'));\n}\nif(root.dataset.tool==='favicon-generator'){\n let source,pack=[],ico,version=0,sourceVersion=0;\n const invalidate=()=>{version++;pack.forEach(p=>release(p.url));pack=[];$('icons').replaceChildren();$('markup').value='';enable(['zip','ico'],false);};\n on('file','change',async()=>{invalidate();const token=++sourceVersion;enable(['generate'],false);source?.close();source=null;const next=await image($('file').files[0]);if(token!==sourceVersion){next.close();return;}source=next;enable(['generate']);status('Image ready. Generate your icon pack.');});\n ['transparent','background'].forEach(id=>on(id,'input',()=>{invalidate();status('Settings changed. Generate icons again.');}));\n on('generate','click',async()=>{if(!source)throw Error('Choose an image first.');invalidate();const token=version;enable(['generate'],false);try{const next=[];for(const size of [16,32,48,64,180,192,512]){const c=canvas(size,size),ctx=c.getContext('2d');if(!$('transparent').checked){ctx.fillStyle=$('background').value;ctx.fillRect(0,0,size,size);}const ratio=Math.min(size\/source.width,size\/source.height);ctx.drawImage(source,(size-source.width*ratio)\/2,(size-source.height*ratio)\/2,source.width*ratio,source.height*ratio);const b=await blob(c);if(token!==version)return;next.push({size,blob:b,bytes:new Uint8Array(await b.arrayBuffer())});}if(token!==version)return;pack=next.map(p=>({...p,url:objectURL(p.blob)}));ico=icoFile(pack.filter(p=>p.size<=48));for(const p of pack){const card=document.createElement('div');card.className='at-card';const img=document.createElement('img');img.src=p.url;img.width=Math.min(64,p.size);img.height=Math.min(64,p.size);img.alt=`${p.size}-pixel favicon preview`;const a=document.createElement('a');a.textContent=`Download ${p.size} \u00d7 ${p.size}`;a.href=p.url;a.download=`favicon-${p.size}.png`;card.append(img,a);$('icons').append(card);}$('markup').value='<link rel=\"icon\" href=\"\/favicon.ico\" sizes=\"any\">\\n<link rel=\"icon\" type=\"image\/png\" sizes=\"32x32\" href=\"\/favicon-32.png\">\\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"\/favicon-180.png\">';enable(['zip','ico']);status('7 PNG icons and a multi-size ICO are ready.');}finally{enable(['generate'],!!source);}});\n on('ico','click',()=>download(ico,'favicon.ico'));\n on('zip','click',async()=>{const zip=new JSZip();pack.forEach(p=>zip.file(`favicon-${p.size}.png`,p.bytes));zip.file('favicon.ico',await ico.arrayBuffer());zip.file('installation.txt','Upload the icons to your website root, or adjust the paths below. Add these tags inside your document head.\\n\\n'+$('markup').value);download(await zip.generateAsync({type:'blob'}),'aitoolsoft-favicons.zip');});\n}\nif(root.dataset.tool==='youtube-thumbnail-generator'){\n on('generate','click',()=>{$('thumbnails').replaceChildren();const id=youtubeId($('url').value);for(const [name,file,size]of[['Maximum resolution','maxresdefault','1280 \u00d7 720'],['Standard definition','sddefault','640 \u00d7 480'],['High quality','hqdefault','480 \u00d7 360'],['Medium quality','mqdefault','320 \u00d7 180'],['Default','default','120 \u00d7 90']]){const url=`https:\/\/i.ytimg.com\/vi\/${id}\/${file}.jpg`;const card=document.createElement('div');card.className='at-card';const h=document.createElement('h3');h.textContent=name;const img=document.createElement('img');img.alt=name+' video thumbnail';img.referrerPolicy='no-referrer';const p=document.createElement('p');p.textContent=size+' \u00b7 checking availability';const a=document.createElement('a');a.href=url;a.target='_blank';a.rel='noopener noreferrer';a.textContent='Open image';a.hidden=true;const b=document.createElement('button');b.textContent='Copy image URL';b.disabled=true;b.onclick=()=>copy(url).catch(e=>status(e.message,true));const unavailable=()=>{img.hidden=true;p.textContent='This resolution is unavailable.';};img.onload=()=>{if(file!=='default'&&img.naturalWidth<=120){unavailable();return;}p.textContent=`${img.naturalWidth} \u00d7 ${img.naturalHeight} px`;a.hidden=false;b.disabled=false;};img.onerror=unavailable;img.src=url;card.append(h,img,p,a,b);$('thumbnails').append(card);}status('Open an available image, then use your browser\u2019s save-image command.');});\n}\nif(root.dataset.tool==='image-to-base64'){\n let data='',version=0;\n const render=()=>{if(!data)return;const raw=data.slice(data.indexOf(',')+1);$('result').value=({data,raw,html:`<img decoding=\"async\" src=\"${data}\" alt=\"\">`,css:`background-image: url(\"${data}\");`})[$('format').value];enable(['copy','download']);};\n on('file','change',async()=>{const token=++version;data='';$('result').value='';enable(['copy','download'],false);const f=$('file').files[0];if(!f||!\/^image\\\/(png|jpeg|webp|gif|x-icon|vnd.microsoft.icon)$\/.test(f.type))throw Error('Choose a PNG, JPG, WebP, GIF or ICO image.');if(f.size>10*1024*1024)throw Error('Choose an image smaller than 10 MB.');const next=await readData(f);if(token!==version)return;data=next;render();status(`Source: ${filesize(f.size)} \u00b7 Data URL: ${filesize(data.length)}`);});\n on('format','change',render);on('copy','click',()=>copy($('result').value));on('download','click',()=>download(new Blob([$('result').value],{type:'text\/plain'}),'image-base64.txt'));\n}\nif(root.dataset.tool==='json-formatter'){\n const invalidate=()=>{$('result').value='';enable(['copy','download'],false);status();};\n const run=spaces=>{invalidate();const result=formatJSON($('source').value,spaces);$('result').value=result.text;enable(['copy','download']);status(`Valid JSON \u00b7 ${result.type} \u00b7 ${result.text.length.toLocaleString()} characters`);};\n on('format','click',()=>run(Number($('indent').value)));on('minify','click',()=>run(0));on('source','input',invalidate);on('clear','click',()=>{$('source').value='';$('file').value='';invalidate();});\n on('file','change',async()=>{invalidate();const f=$('file').files[0];if(!f)return;if(f.size>2_000_000)throw Error('Choose a JSON file smaller than 2 MB.');$('source').value=await f.text();status('File loaded. Select Format JSON or Minify.');});\n on('copy','click',()=>copy($('result').value));on('download','click',()=>download(new Blob([$('result').value],{type:'application\/json'}),'formatted.json'));\n}\nif(root.dataset.tool==='password-generator'){\n let password='';\n on('generate','click',()=>{password='';enable(['copy'],false);$('password').textContent='';password=makePassword(number('length',8,128),[['upper','ABCDEFGHIJKLMNOPQRSTUVWXYZ'],['lower','abcdefghijklmnopqrstuvwxyz'],['numbers','0123456789'],['symbols','!@#$%^&*()-_=+[]{};:,.?\/~']].filter(([id])=>$(id).checked).map(([,set])=>set),$('similar').checked);$('password').textContent=password;enable(['copy']);status(`${password.length} characters \u00b7 generated locally`);});\n on('copy','click',()=>copy(password));\n}\nif(root.dataset.tool==='gif-maker'){\n let frames=[],result=null,resultURL='',busy=false;\n const invalidate=()=>{result=null;release(resultURL);resultURL='';enable(['download'],false);$('stage').replaceChildren(Object.assign(document.createElement('p'),{className:'at-empty',textContent:'Create your GIF to see the animated preview.'}));};\n const render=()=>{$('frames').replaceChildren();frames.forEach((frame,i)=>{const card=document.createElement('div');card.className='at-card at-frame';const img=document.createElement('img');img.src=frame.url;img.alt=`Frame ${i+1}`;const name=document.createElement('p');name.className='at-frame-name';name.textContent=`${i+1}. ${frame.name}`;const actions=document.createElement('div');actions.className='at-actions';for(const [label,offset]of[['Move earlier',-1],['Move later',1],['Remove',0]]){const b=document.createElement('button');b.type='button';b.textContent=offset===-1?'\u2190':offset===1?'\u2192':'Remove';b.setAttribute('aria-label',`${label}: frame ${i+1}`);b.disabled=busy||(offset&&(!frames[i+offset]));b.onclick=()=>{if(busy)return;invalidate();if(!offset){frames.splice(i,1);frame.bitmap.close();release(frame.url);}else [frames[i],frames[i+offset]]=[frames[i+offset],frames[i]];render();};actions.append(b);}card.append(img,name,actions);$('frames').append(card);});enable(['generate'],frames.length>=2&&!busy);};\n on('file','change',async()=>{if(busy)return;invalidate();const files=[...$('file').files];if(frames.length+files.length>30)throw Error('Use no more than 30 frames.');busy=true;enable(['generate'],false);$('file').disabled=true;try{for(const f of files){const original=await image(f,10),ratio=Math.min(1,800\/original.width,800\/original.height),c=canvas(Math.max(1,Math.round(original.width*ratio)),Math.max(1,Math.round(original.height*ratio)));c.getContext('2d').drawImage(original,0,0,c.width,c.height);original.close();const preview=await blob(c);frames.push({bitmap:await createImageBitmap(preview),name:f.name,url:objectURL(preview)});}status(`${frames.length} frames ready. Arrange them before creating your GIF.`);}finally{busy=false;$('file').disabled=false;$('file').value='';render();}});\n ['delay','width','colors','loop'].forEach(id=>on(id,'input',invalidate));\n on('generate','click',async()=>{if(busy||frames.length<2)return;const delay=number('delay',20,5000);busy=true;invalidate();const controls=[...root.querySelectorAll('input,select,button')];controls.forEach(el=>el.disabled=true);$('progress').hidden=false;try{const maxW=Math.max(...frames.map(f=>f.bitmap.width)),maxH=Math.max(...frames.map(f=>f.bitmap.height)),ratio=Math.min(1,Number($('width').value)\/maxW,800\/maxH),w=Math.max(1,Math.round(maxW*ratio)),h=Math.max(1,Math.round(maxH*ratio));const c=canvas(w,h),ctx=c.getContext('2d',{willReadFrequently:true}),gif=GIFEncoder();for(let i=0;i<frames.length;i++){status(`Creating frame ${i+1} of ${frames.length}\u2026`);$('progress').value=i\/frames.length*100;await new Promise(resolve=>setTimeout(resolve,15));ctx.fillStyle='#ffffff';ctx.fillRect(0,0,w,h);const img=frames[i].bitmap;ctx.drawImage(img,(w-img.width*ratio)\/2,(h-img.height*ratio)\/2,img.width*ratio,img.height*ratio);const rgba=ctx.getImageData(0,0,w,h).data;const palette=quantize(rgba,Number($('colors').value));gif.writeFrame(applyPalette(rgba,palette),w,h,{palette,delay,repeat:$('loop').checked?0:-1});}gif.finish();result=new Blob([gif.bytes()],{type:'image\/gif'});resultURL=objectURL(result);const preview=document.createElement('img');preview.src=resultURL;preview.alt='Your generated GIF animation';$('stage').replaceChildren(preview);$('progress').value=100;status(`${w} \u00d7 ${h} px \u00b7 ${frames.length} frames \u00b7 ${filesize(result.size)}`);}finally{busy=false;controls.forEach(el=>el.disabled=false);enable(['download'],!!result);render();$('progress').hidden=true;}});\n on('download','click',()=>download(result,'aitoolsoft-animation.gif'));\n}\nif(root.dataset.tool==='qr-generator'){\n let output,svg='';\n const invalidate=()=>{enable(['png','svg'],false);output=null;svg='';};\n ['text','size','level','foreground','background'].forEach(id=>on(id,'input',()=>{invalidate();status('Settings changed. Generate your QR code again.');}));\n on('generate','click',()=>{invalidate();const value=$('text').value;if(!value.trim())throw Error('Enter a link or text.');const fg=$('foreground').value,bg=$('background').value;if(fg===bg)throw Error('Choose different code and background colors.');const qr=qrcode(0,$('level').value);qr.addData(value,'Byte');try{qr.make();}catch{throw Error('This text is too long for the selected error correction. Shorten it or select a lower level.');}const count=qr.getModuleCount(),cell=Math.ceil(Number($('size').value)\/(count+8)),size=(count+8)*cell;output=canvas(size,size);const ctx=output.getContext('2d');ctx.fillStyle=bg;ctx.fillRect(0,0,size,size);ctx.fillStyle=fg;let path='';for(let y=0;y<count;y++)for(let x=0;x<count;x++)if(qr.isDark(y,x)){ctx.fillRect((x+4)*cell,(y+4)*cell,cell,cell);path+=`M${x+4} ${y+4}h1v1h-1z`; }svg=`<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${count+8} ${count+8}\" shape-rendering=\"crispEdges\"><rect width=\"100%\" height=\"100%\" fill=\"${bg}\"\/><path d=\"${path}\" fill=\"${fg}\"\/><\/svg>`;$('stage').replaceChildren(output);enable(['png','svg']);status(`${size} \u00d7 ${size} px \u00b7 Test with your phone before sharing. Use dark code colors on a light background.`);});\n on('png','click',async()=>download(await blob(output),'aitoolsoft-qr.png'));on('svg','click',()=>download(new Blob([svg],{type:'image\/svg+xml'}),'aitoolsoft-qr.svg'));\n}\n\n}catch(error){const status=root.querySelector('#status');if(status){status.textContent='The tool could not start: '+(error&&error.message?error.message:'unknown error');status.dataset.error='true';}console.error('[Aitoolsoft qr-generator]',error);}}if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot,{once:true});else boot();})();<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Online QR tool Make your next link easy to scan. Create a QR code for&hellip;<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1917","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.0 (Yoast SEO v28.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>QR code generator | Aitoolsoft<\/title>\n<meta name=\"description\" content=\"Create a QR code for a URL or plain text online. Customize the QR code size and colors, then download the finished code as a PNG or SVG file.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.aitoolsoft.com\/fr\/qr-generator.html\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"QR Code Generator\" \/>\n<meta property=\"og:description\" content=\"Create a QR code for a URL or plain text online. Customize the QR code size and colors, then download the finished code as a PNG or SVG file.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.aitoolsoft.com\/fr\/qr-generator.html\" \/>\n<meta property=\"og:site_name\" content=\"Aitoolsoft\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-10T00:52:57+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/qr-generator.html\",\"url\":\"https:\\\/\\\/www.aitoolsoft.com\\\/qr-generator.html\",\"name\":\"QR code generator | Aitoolsoft\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#website\"},\"datePublished\":\"2026-09-09T08:11:24+00:00\",\"dateModified\":\"2026-09-10T00:52:57+00:00\",\"description\":\"Create a QR code for a URL or plain text online. Customize the QR code size and colors, then download the finished code as a PNG or SVG file.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/qr-generator.html#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.aitoolsoft.com\\\/qr-generator.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/qr-generator.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\\\/\\\/www.aitoolsoft.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"QR Code Generator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#website\",\"url\":\"https:\\\/\\\/www.aitoolsoft.com\\\/\",\"name\":\"Aitoolsoft\",\"description\":\"Focused tools for images, documents, and everyday workflows\u2014online and across Apple devices.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.aitoolsoft.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#organization\",\"name\":\"Aitoolsoft\",\"url\":\"https:\\\/\\\/www.aitoolsoft.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\/\\/mlokfggnkpkq.i.optimole.com\\/cb:hL5J.22d\\/w:1583\\/h:504\\/q:mauto\\/f:best\\/https:\\/\\/www.aitoolsoft.com\\/wp-content\\/uploads\\/2025\\/07\\/aitoolsoft_logo.png\",\"contentUrl\":\"https:\\/\\/mlokfggnkpkq.i.optimole.com\\/cb:hL5J.22d\\/w:1583\\/h:504\\/q:mauto\\/f:best\\/https:\\/\\/www.aitoolsoft.com\\/wp-content\\/uploads\\/2025\\/07\\/aitoolsoft_logo.png\",\"width\":1583,\"height\":504,\"caption\":\"Aitoolsoft\"},\"image\":{\"@id\":\"https:\\\/\\\/www.aitoolsoft.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"G\u00e9n\u00e9rateur de codes QR | Aitoolsoft","description":"Cr\u00e9ez en ligne un code QR \u00e0 partir d'une URL ou d'un texte brut. Personnalisez la taille et les couleurs du code QR, puis t\u00e9l\u00e9chargez le code final au format PNG ou SVG.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.aitoolsoft.com\/fr\/qr-generator.html","og_locale":"fr_FR","og_type":"article","og_title":"QR Code Generator","og_description":"Create a QR code for a URL or plain text online. Customize the QR code size and colors, then download the finished code as a PNG or SVG file.","og_url":"https:\/\/www.aitoolsoft.com\/fr\/qr-generator.html","og_site_name":"Aitoolsoft","article_modified_time":"2026-09-10T00:52:57+00:00","twitter_card":"summary_large_image","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.aitoolsoft.com\/qr-generator.html","url":"https:\/\/www.aitoolsoft.com\/qr-generator.html","name":"G\u00e9n\u00e9rateur de codes QR | Aitoolsoft","isPartOf":{"@id":"https:\/\/www.aitoolsoft.com\/#website"},"datePublished":"2026-09-09T08:11:24+00:00","dateModified":"2026-09-10T00:52:57+00:00","description":"Cr\u00e9ez en ligne un code QR \u00e0 partir d'une URL ou d'un texte brut. Personnalisez la taille et les couleurs du code QR, puis t\u00e9l\u00e9chargez le code final au format PNG ou SVG.","breadcrumb":{"@id":"https:\/\/www.aitoolsoft.com\/qr-generator.html#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.aitoolsoft.com\/qr-generator.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.aitoolsoft.com\/qr-generator.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.aitoolsoft.com\/"},{"@type":"ListItem","position":2,"name":"QR Code Generator"}]},{"@type":"WebSite","@id":"https:\/\/www.aitoolsoft.com\/#website","url":"https:\/\/www.aitoolsoft.com\/","name":"Aitoolsoft","description":"Des outils sp\u00e9cialement con\u00e7us pour les images, les documents et les t\u00e2ches quotidiennes, en ligne et sur tous les appareils Apple.","publisher":{"@id":"https:\/\/www.aitoolsoft.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.aitoolsoft.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/www.aitoolsoft.com\/#organization","name":"Aitoolsoft","url":"https:\/\/www.aitoolsoft.com\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.aitoolsoft.com\/#\/schema\/logo\/image\/","url":"https:\/\/mlokfggnkpkq.i.optimole.com\/cb:hL5J.22d\/w:1583\/h:504\/q:mauto\/f:best\/https:\/\/www.aitoolsoft.com\/wp-content\/uploads\/2025\/07\/aitoolsoft_logo.png","contentUrl":"https:\/\/mlokfggnkpkq.i.optimole.com\/cb:hL5J.22d\/w:1583\/h:504\/q:mauto\/f:best\/https:\/\/www.aitoolsoft.com\/wp-content\/uploads\/2025\/07\/aitoolsoft_logo.png","width":1583,"height":504,"caption":"Aitoolsoft"},"image":{"@id":"https:\/\/www.aitoolsoft.com\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/pages\/1917","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/comments?post=1917"}],"version-history":[{"count":1,"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/pages\/1917\/revisions"}],"predecessor-version":[{"id":1918,"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/pages\/1917\/revisions\/1918"}],"wp:attachment":[{"href":"https:\/\/www.aitoolsoft.com\/fr\/wp-json\/wp\/v2\/media?parent=1917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}