From a760bbfbc28e14d4176847fd54235af56656e9c9 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 29 Mar 2023 08:22:35 +0200 Subject: [PATCH 01/15] MIB Uploader fix delete icon --- pandora_console/include/functions_filemanager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/include/functions_filemanager.php b/pandora_console/include/functions_filemanager.php index 66f60967c7..1e5297dbff 100644 --- a/pandora_console/include/functions_filemanager.php +++ b/pandora_console/include/functions_filemanager.php @@ -751,7 +751,7 @@ function filemanager_file_explorer( && ($readOnly === false) ) { $data[4] .= '
'; - $data[4] .= ''; + $data[4] .= ''; $data[4] .= html_print_input_hidden('filename', $fileinfo['realpath'], true); $data[4] .= html_print_input_hidden('hash', md5($fileinfo['realpath'].$config['server_unique_identifier']), true); $data[4] .= html_print_input_hidden('delete_file', 1, true); From 32bc7335ac846f96c93f62ba9161fb461211c183 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 29 Mar 2023 09:11:26 +0200 Subject: [PATCH 02/15] fixed styles --- pandora_console/include/styles/pandora.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 7d4ebc1e6c..1df4aaf488 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -5879,7 +5879,12 @@ div.switch_radio_button label:last-of-type { cursor: pointer; } -.switch_radio_button input:checked + label, +.switch_radio_button input:checked + label { + background-color: var(--primary-color); + box-shadow: none; + color: var(--secondary-color) !important; +} + .switch_radio_button input:checked:has(.custom_checkbox) { background-color: var(--primary-color); box-shadow: none; From 9a0dffbee36801cf0f721e2f97f055ad9a832e74 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 29 Mar 2023 11:02:57 +0200 Subject: [PATCH 03/15] Agents modules view fix filters --- pandora_console/extensions/agents_modules.php | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/pandora_console/extensions/agents_modules.php b/pandora_console/extensions/agents_modules.php index d3467b846c..5bf3d18ab5 100644 --- a/pandora_console/extensions/agents_modules.php +++ b/pandora_console/extensions/agents_modules.php @@ -729,16 +729,31 @@ function mainAgentsModules() if (isset($modules_selected[0]) === true && $modules_selected[0]) { $all_modules = []; foreach ($modules_selected as $key => $value) { - $name = modules_get_agentmodule_name($value); - $sql = "SELECT id_agente_modulo - FROM tagente_modulo - WHERE nombre = '".$name."';"; + if (is_int($value)) { + $name = modules_get_agentmodule_name($value); + $sql = "SELECT id_agente_modulo + FROM tagente_modulo + WHERE nombre = '".$name."';"; - $result_sql = db_get_all_rows_sql($sql); + $result_sql = db_get_all_rows_sql($sql); - if (is_array($result_sql)) { - foreach ($result_sql as $key => $value) { - $all_modules[$value['id_agente_modulo']] = io_safe_output($name); + if (is_array($result_sql)) { + foreach ($result_sql as $key => $value) { + $all_modules[$value['id_agente_modulo']] = io_safe_output($name); + } + } + } else { + $name = $value; + $sql = "SELECT id_agente_modulo + FROM tagente_modulo + WHERE nombre = '".$name."';"; + + $result_sql = db_get_all_rows_sql($sql); + + if (is_array($result_sql)) { + foreach ($result_sql as $key => $value) { + $all_modules[$value['id_agente_modulo']] = io_safe_output($name); + } } } } @@ -838,7 +853,7 @@ function mainAgentsModules() echo ''; - echo "".__('Agents').' / '.__('Modules').''; + echo "".__('Agents').' / '.__('Modules').''; if ($hor_offset > 0) { $new_hor_offset = ($hor_offset - $block); @@ -958,7 +973,7 @@ function mainAgentsModules() foreach ($module['id'] as $module_id) { if (!$match && array_key_exists($module_id, $agent_modules)) { - echo ""; + echo ""; $win_handle = dechex(crc32($module_id.$module['name'])); $graph_type = return_graphtype(modules_get_agentmodule_type($module_id)); $link = "winopeng_var('".'operation/agentes/stat_win.php?'."type=$graph_type&".'period='.SECONDS_1DAY.'&'.'id='.$module_id.'&'.'refresh='.SECONDS_10MINUTES."', 'day_".$win_handle."', 800, 480)"; From 7ada30c9b13b0b0624eecca668d1a43d8ce691d2 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Wed, 29 Mar 2023 12:12:56 +0200 Subject: [PATCH 04/15] 10718 & 10821 --- pandora_console/general/noaccess.php | 10 ++++------ pandora_console/include/styles/pandora.css | 6 ++++++ pandora_console/include/styles/tables.css | 5 +++++ pandora_console/operation/agentes/ver_agente.php | 15 +-------------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/pandora_console/general/noaccess.php b/pandora_console/general/noaccess.php index 39e343a0fc..b2fe4515a2 100644 --- a/pandora_console/general/noaccess.php +++ b/pandora_console/general/noaccess.php @@ -15,7 +15,7 @@ + + + + + + diff --git a/pandora_console/images/gm_log@svg.svg b/pandora_console/images/gm_log@svg.svg new file mode 100644 index 0000000000..dcae20e7db --- /dev/null +++ b/pandora_console/images/gm_log@svg.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/pandora_console/images/linux@os.svg b/pandora_console/images/linux@os.svg index 6de3c7ac76..22249e0cff 100644 --- a/pandora_console/images/linux@os.svg +++ b/pandora_console/images/linux@os.svg @@ -1,9 +1,38 @@ - - - - Dark / 20 / linux@svg - Created with Sketch. - - - - \ No newline at end of file + + + + +Dark / 20 / incremental-data@svg +Created with Sketch. + + diff --git a/pandora_console/images/networkmap/linux@os.svg b/pandora_console/images/networkmap/linux@os.svg index 6de3c7ac76..22249e0cff 100644 --- a/pandora_console/images/networkmap/linux@os.svg +++ b/pandora_console/images/networkmap/linux@os.svg @@ -1,9 +1,38 @@ - - - - Dark / 20 / linux@svg - Created with Sketch. - - - - \ No newline at end of file + + + + +Dark / 20 / incremental-data@svg +Created with Sketch. + + diff --git a/pandora_console/include/styles/pandora_black.css b/pandora_console/include/styles/pandora_black.css index be3a3d930d..f716688e75 100644 --- a/pandora_console/include/styles/pandora_black.css +++ b/pandora_console/include/styles/pandora_black.css @@ -1531,12 +1531,12 @@ a.autorefresh_txt, } .header-widget { - color: #222; + background-color: #222; } .grid-stack-item-content { box-shadow: 0px 0px 15px -10px #888; - border-radius: 5px 5px 0px 0px; + border-radius: 0px 0px 0px 0px; } /* xxx */ diff --git a/pandora_console/operation/agentes/group_view.php b/pandora_console/operation/agentes/group_view.php index 5e281e8b23..63fc0ab41c 100644 --- a/pandora_console/operation/agentes/group_view.php +++ b/pandora_console/operation/agentes/group_view.php @@ -295,7 +295,7 @@ if (empty($result_groups) === false) { echo ""; if (!isset($data['_is_tag_']) && check_acl($config['id_user'], $data['_id_'], 'AW')) { echo ''.html_print_image( - 'images/change-active.svg', + 'images/force@svg.svg', true, [ 'border' => '0', diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 6641fb5650..2946f2ea70 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -1579,7 +1579,7 @@ if (enterprise_installed() === true && (bool) $config['log_collector'] === true) $log_viewer_tab['text'] = html_print_menu_button( [ 'href' => 'index.php?sec=estado&sec2=operation/agentes/ver_agente&tab=log_viewer&id_agente='.$id_agente, - 'image' => 'images/gm_log.png', + 'image' => 'images/gm_log@svg.svg', 'title' => __('Log Viewer'), ], true diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index 0c8ad8c1fe..6f17e6301c 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -424,7 +424,7 @@ if ($pure === false) { echo html_print_label(__('Force'), 'force-mode', true); echo ''; echo html_print_image( - 'images/change-active.svg', + 'images/force@svg.svg', true, [ 'title' => __('Force remote checks'), diff --git a/pandora_console/views/dashboard/cell.php b/pandora_console/views/dashboard/cell.php index dea56fa485..56fcfca72b 100644 --- a/pandora_console/views/dashboard/cell.php +++ b/pandora_console/views/dashboard/cell.php @@ -54,6 +54,7 @@ if ($manageDashboards !== 0 || $writeDashboards !== 0) { [ 'width' => '16px', 'title' => __('Configure widget'), + 'class' => 'invert_filter', ] ); $output .= ' '; @@ -66,6 +67,7 @@ if ($manageDashboards !== 0 || $writeDashboards !== 0) { [ 'width' => '16px', 'title' => __('Delete widget'), + 'class' => 'invert_filter', ] ); $output .= ''; From 2b121a2fd204f9748d5b911f35653357d0d77bd9 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Wed, 29 Mar 2023 15:34:03 +0200 Subject: [PATCH 12/15] New qrcode.js version & vcard --- .../godmode/users/user_management.php | 49 +- pandora_console/include/javascript/pandora.js | 95 +- pandora_console/include/javascript/qrcode.js | 3305 ++++++++++++++--- pandora_console/include/styles/pandora.css | 8 + .../operation/agentes/alerts_status.php | 2 + pandora_console/operation/events/events.php | 2 +- 6 files changed, 2847 insertions(+), 614 deletions(-) mode change 100755 => 100644 pandora_console/include/javascript/qrcode.js diff --git a/pandora_console/godmode/users/user_management.php b/pandora_console/godmode/users/user_management.php index 91f69a909f..43e41745de 100644 --- a/pandora_console/godmode/users/user_management.php +++ b/pandora_console/godmode/users/user_management.php @@ -736,22 +736,18 @@ $userManagementTable->data['fields_addSettings'][1] .= html_print_div( true ); - -$contentQrCode = []; -$contentQrCode[] = html_print_image( - 'images/example_qr.png', - true, - [ - 'width' => '200px', - 'height' => '200px', - ] +$CodeQRContent .= html_print_div(['id' => 'qr_container_image', 'class' => 'scale-0-8'], true); +$CodeQRContent .= html_print_anchor( + ['id' => 'qr_code_agent_view'], + true ); -$contentQrCode[] = ''.__('Generated automatically with the information provided for the user').''; +$CodeQRContent .= '
'.$custom_id_div; -$qrCode = html_print_div( +// QR code div. +$CodeQRTable = html_print_div( [ - 'style' => 'display: flex;flex-direction: column;align-items: center;', - 'content' => implode('', $contentQrCode), + 'class' => 'agent_qr', + 'content' => $CodeQRContent, ], true ); @@ -760,8 +756,33 @@ $qrCode = html_print_div( html_print_div( [ 'id' => 'api_qrcode_display', - 'content' => $qrCode.$apiTokenContent, + 'content' => $CodeQRTable.$apiTokenContent, ] ); html_print_table($userManagementTable); + +$vcard_data = []; +$vcard_data['version'] = '3.0'; +$vcard_data['firstName'] = $user_info['firstname']; +$vcard_data['lastName'] = $user_info['lastname']; +$vcard_data['middleName'] = ($user_info['middlename'] === '1') ? '' : $user_info['middlename']; +$vcard_data['nickname'] = $user_info['fullname']; +$vcard_data['workPhone'] = $user_info['phone']; +$vcard_data['email'] = $user_info['email']; +$vcard_data['organization'] = io_safe_output(get_product_name()); +$vcard_data['url'] = ui_get_full_url('index.php'); + +$vcard_json = json_encode($vcard_data); +?> + + \ No newline at end of file diff --git a/pandora_console/include/javascript/pandora.js b/pandora_console/include/javascript/pandora.js index 9a58198227..4fa8511a60 100644 --- a/pandora_console/include/javascript/pandora.js +++ b/pandora_console/include/javascript/pandora.js @@ -1283,14 +1283,95 @@ function paint_qrcode(text, where, width, height) { $(where).empty(); - var qrcode = new QRCode(where, { - text: text, - width: width, - height: height, - colorDark: "#343434", - colorLight: "#ffffff", - correctLevel: QRCode.CorrectLevel.M + var qrcode = qrCode.createQr({ + typeElement: "createImg", + data: text, + typeNumber: 5, + cellSize: 5 }); + + $(where).append(qrcode); +} + +function paint_vcard(text, where) { + if (typeof text == "undefined") { + text = window.location.href; + } else { + //null value + if (isEmptyObject(text)) { + text = window.location.href; + } + } + + if (typeof where == "undefined") { + where = $("#qrcode_container_image").get(0); + } else if (typeof where == "string") { + where = $(where).get(0); + } + + if (typeof where == "undefined") { + where = $("#qrcode_container_image").get(0); + } else if (typeof where == "string") { + where = $(where).get(0); + } + + // version: "3.0", + // lastName: "Нижинский", + // middleName: "D", + // firstName: "Костя", + // nameSuffix: "JR", + // namePrefix: "MR", + // nickname: "Test User", + // gender: "M", + // organization: "ACME Corporation", + // workPhone: "312-555-1212444", + // homePhone: "312-555-1313333", + // cellPhone: "312-555-1414111", + // pagerPhone: "312-555-1515222", + // homeFax: "312-555-1616", + // workFax: "312-555-1717", + // birthday: "20140112", + // anniversary: "20140112", + // title: "Crash Test Dummy", + // role: "Crash Testing", + // email: "john.doe@testmail", + // workEmail: "john.doe@workmail", + // url: "http://johndoe", + // workUrl: "http://acemecompany/johndoe", + // homeAddress: { + // label: "Home Address", + // street: "123 Main Street", + // city: "Chicago", + // stateProvince: "IL", + // postalCode: "12345", + // countryRegion: "United States of America" + // }, + + // workAddress: { + // label: "Work Address", + // street: "123 Corporate Loop\nSuite 500", + // city: "Los Angeles", + // stateProvince: "CA", + // postalCode: "54321", + // countryRegion: "California Republic" + // }, + + // source: "http://sourceurl", + // note: "dddddd", + // socialUrls: { + // facebook: "johndoe", + // linkedIn: "johndoe", + // twitter: "johndoe", + // flickr: "johndoe", + // skype: "test_skype", + // custom: "johndoe" + // } + + $(where).empty(); + + var qrcode = qrCode.createVCardQr(text, { typeNumber: 30, cellSize: 2 }); + + $(where).append(qrcode); } function show_dialog_qrcode(dialog, text, where, width, height) { diff --git a/pandora_console/include/javascript/qrcode.js b/pandora_console/include/javascript/qrcode.js old mode 100755 new mode 100644 index cd8485aafb..4f664b4659 --- a/pandora_console/include/javascript/qrcode.js +++ b/pandora_console/include/javascript/qrcode.js @@ -1,609 +1,2730 @@ -/** - * @fileoverview - * - Using the 'QRCode for Javascript library' - * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. - * - this library has no dependencies. - * - * @author davidshimjs - * @see http://www.d-project.com/ - * @see http://jeromeetienne.github.com/jquery-qrcode/ - */ -var QRCode; +/* +name: qr-code-and-vcard +version: 0.9.2 +author: Konstantin Nizhinskiy +date: 2018-05-14 15:05:04 -(function () { - //--------------------------------------------------------------------- - // QRCode for JavaScript - // - // Copyright (c) 2009 Kazuhiko Arase - // - // URL: http://www.d-project.com/ - // - // Licensed under the MIT license: - // http://www.opensource.org/licenses/mit-license.php - // - // The word "QR Code" is registered trademark of - // DENSO WAVE INCORPORATED - // http://www.denso-wave.com/qrcode/faqpatent-e.html - // - //--------------------------------------------------------------------- - function QR8bitByte(data) { - this.mode = QRMode.MODE_8BIT_BYTE; - this.data = data; - this.parsedData = []; +*/ +(function(root, factory) { + if (typeof define === "function" && define.amd) { + // the AMD loader. + define([], function() { + return (root.qrCode = factory()); + }); + } else if (typeof module === "object" && module.exports) { + // the CommonJS loader. + module.exports = root.qrCode = factory(); + } else { + root.qrCode = factory(); + } +})(this, function() { + /** + * + * @constructor + */ + var QrCode = function() {}, + majorVersion = "3.0"; + // + /** + * Encode string + * @param {String} value to encode + * @return {String} encoded string + */ + var e = function(value) { + if (value) { + if (typeof value !== "string") { + value = "" + value; + } + return value + .replace(/\n/g, "\\n") + .replace(/,/g, "\\,") + .replace(/;/g, "\\;"); + } + return ""; + }; - // Added to support UTF-8 Characters - for (var i = 0, l = this.data.length; i < l; i++) { - var byteArray = []; - var code = this.data.charCodeAt(i); + /** + * Get formatted address + * @param address {object} address + * @param encodingPrefix {object} encoding prefix + * @param majorVersion {string} version vCard + * @return {String} Formatted address + */ + function getFormattedAddress(encodingPrefix, address, majorVersion) { + var formattedAddress = ""; - if (code > 0x10000) { - byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); - byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); - byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); - byteArray[3] = 0x80 | (code & 0x3F); - } else if (code > 0x800) { - byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); - byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); - byteArray[2] = 0x80 | (code & 0x3F); - } else if (code > 0x80) { - byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); - byteArray[1] = 0x80 | (code & 0x3F); - } else { - byteArray[0] = code; - } + if ( + address.details.label || + address.details.street || + address.details.city || + address.details.stateProvince || + address.details.postalCode || + address.details.countryRegion + ) { + if (majorVersion >= 4) { + formattedAddress = + "ADR" + + encodingPrefix + + ";TYPE=" + + address.type + + (address.details.label + ? ';LABEL="' + e(address.details.label) + '"' + : "") + + ":;;" + + e(address.details.street) + + ";" + + e(address.details.city) + + ";" + + e(address.details.stateProvince) + + ";" + + e(address.details.postalCode) + + ";" + + e(address.details.countryRegion) + + nl(); + } else { + if (address.details.label) { + formattedAddress = + "LABEL" + + encodingPrefix + + ";TYPE=" + + address.type + + ":" + + e(address.details.label) + + nl(); + } + formattedAddress += + "ADR" + + encodingPrefix + + ";TYPE=" + + address.type + + ":;;" + + e(address.details.street) + + ";" + + e(address.details.city) + + ";" + + e(address.details.stateProvince) + + ";" + + e(address.details.postalCode) + + ";" + + e(address.details.countryRegion) + + nl(); + } + } - this.parsedData.push(byteArray); - } + return formattedAddress; + } - this.parsedData = Array.prototype.concat.apply([], this.parsedData); + /** + * Get formatted photo + * @param {String} photoType Photo type (PHOTO, LOGO) + * @param {String} url URL to attach photo from + * @param {String} mediaType Media-type of photo (JPEG, PNG, GIF) + * @param {boolean} base64 base64 true/false + * @param {String} majorVersion version vCard + * @return {String} Formatted photo + */ + var getFormattedPhoto = function( + photoType, + url, + mediaType, + base64, + majorVersion + ) { + var params; - if (this.parsedData.length != this.data.length) { - this.parsedData.unshift(191); - this.parsedData.unshift(187); - this.parsedData.unshift(239); - } - } + if (majorVersion >= 4) { + params = base64 ? ";ENCODING=b;MEDIATYPE=image/" : ";MEDIATYPE=image/"; + } else if (majorVersion === 3) { + params = base64 ? ";ENCODING=b;TYPE=" : ";TYPE="; + } else { + params = base64 ? ";ENCODING=BASE64;" : ";"; + } - QR8bitByte.prototype = { - getLength: function (buffer) { - return this.parsedData.length; - }, - write: function (buffer) { - for (var i = 0, l = this.parsedData.length; i < l; i++) { - buffer.put(this.parsedData[i], 8); - } - } - }; + return photoType + params + mediaType + ":" + e(url) + nl(); + }; - function QRCodeModel(typeNumber, errorCorrectLevel) { - this.typeNumber = typeNumber; - this.errorCorrectLevel = errorCorrectLevel; - this.modules = null; - this.moduleCount = 0; - this.dataCache = null; - this.dataList = []; - } + var getMajorVersion = function(version) { + var majorVersionString = version ? version.split(".")[0] : "4"; + if (!isNaN(majorVersionString)) { + return parseInt(majorVersionString); + } + return 4; + }; + function getSocialUrls(type, user) { + switch (type.toLowerCase()) { + case "facebook": + return "https://facebook.com/" + user; + case "linkedin": + return "https://linkedin.com/" + user; + case "twitter": + return "https://twitter.com/" + user; + case "flickr": + return "https://flickr.com/" + user; + case "skype": + return "x-apple:" + user; + default: + return "https://www." + type + ".com/"; + } + } + /** + * Return new line characters + * @return {String} new line characters + */ + var nl = function() { + return "\r\n"; + }; - QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} - return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} - if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} - this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} - return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} - for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} - for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} - this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} - var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} - this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} - row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" - +buffer.getLengthInBits() - +">" - +totalDataCount*8 - +")");} - if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} - while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} - while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} - buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} - buffer.put(QRCodeModel.PAD1,8);} - return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} - var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} - return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} - return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} - return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} - for(var row=0;row=256){n-=255;} - return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} - if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} - this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; - - function _isSupportCanvas() { - return typeof CanvasRenderingContext2D != "undefined"; - } - - // android 2.x doesn't support Data-URI spec - function _getAndroid() { - var android = false; - var sAgent = navigator.userAgent; - - if (/android/i.test(sAgent)) { // android - android = true; - aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); - - if (aMat && aMat[1]) { - android = parseFloat(aMat[1]); - } - } - - return android; - } - - var svgDrawer = (function() { + //--------------------------------------------------------------------- + // + // QR Code Generator for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word 'QR Code' is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- - var Drawing = function (el, htOption) { - this._el = el; - this._htOption = htOption; - }; + var qrcode = (function() { + //--------------------------------------------------------------------- + // qrcode + //--------------------------------------------------------------------- - Drawing.prototype.draw = function (oQRCode) { - var _htOption = this._htOption; - var _el = this._el; - var nCount = oQRCode.getModuleCount(); - var nWidth = Math.floor(_htOption.width / nCount); - var nHeight = Math.floor(_htOption.height / nCount); + /** + * qrcode + * @param typeNumber 1 to 40 + * @param errorCorrectionLevel 'L','M','Q','H' + */ + var qrcode = function(typeNumber, errorCorrectionLevel) { + var PAD0 = 0xec; + var PAD1 = 0x11; - this.clear(); + var _typeNumber = typeNumber; + var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel]; + var _modules = null; + var _moduleCount = 0; + var _dataCache = null; + var _dataList = new Array(); - function makeSVG(tag, attrs) { - var el = document.createElementNS('http://www.w3.org/2000/svg', tag); - for (var k in attrs) - if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); - return el; - } + var _this = {}; - var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); - svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); - _el.appendChild(svg); - - svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); - - for (var row = 0; row < nCount; row++) { - for (var col = 0; col < nCount; col++) { - if (oQRCode.isDark(row, col)) { - var child = makeSVG("use", {"x": String(row), "y": String(col)}); - child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") - svg.appendChild(child); - } - } - } - }; - Drawing.prototype.clear = function () { - while (this._el.hasChildNodes()) - this._el.removeChild(this._el.lastChild); - }; - return Drawing; - })(); - - var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; - - // Drawing in DOM by using Table tag - var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { - var Drawing = function (el, htOption) { - this._el = el; - this._htOption = htOption; - }; - - /** - * Draw the QRCode - * - * @param {QRCode} oQRCode - */ - Drawing.prototype.draw = function (oQRCode) { - var _htOption = this._htOption; - var _el = this._el; - var nCount = oQRCode.getModuleCount(); - var nWidth = Math.floor(_htOption.width / nCount); - var nHeight = Math.floor(_htOption.height / nCount); - var aHTML = ['']; - - for (var row = 0; row < nCount; row++) { - aHTML.push(''); - - for (var col = 0; col < nCount; col++) { - aHTML.push(''); - } - - aHTML.push(''); - } - - aHTML.push('
'); - _el.innerHTML = aHTML.join(''); - - // Fix the margin values as real size. - var elTable = _el.childNodes[0]; - var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; - var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; - - if (nLeftMarginTable > 0 && nTopMarginTable > 0) { - elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; - } - }; - - /** - * Clear the QRCode - */ - Drawing.prototype.clear = function () { - this._el.innerHTML = ''; - }; - - return Drawing; - })() : (function () { // Drawing in Canvas - function _onMakeImage() { - this._elImage.src = this._elCanvas.toDataURL("image/png"); - this._elImage.style.display = "inline"; - this._elCanvas.style.display = "none"; - } - - // Android 2.1 bug workaround - // http://code.google.com/p/android/issues/detail?id=5141 - if (this._android && this._android <= 2.1) { - var factor = 1 / window.devicePixelRatio; - var drawImage = CanvasRenderingContext2D.prototype.drawImage; - CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { - if (("nodeName" in image) && /img/i.test(image.nodeName)) { - for (var i = arguments.length - 1; i >= 1; i--) { - arguments[i] = arguments[i] * factor; - } - } else if (typeof dw == "undefined") { - arguments[1] *= factor; - arguments[2] *= factor; - arguments[3] *= factor; - arguments[4] *= factor; - } - - drawImage.apply(this, arguments); - }; - } - - /** - * Check whether the user's browser supports Data URI or not - * - * @private - * @param {Function} fSuccess Occurs if it supports Data URI - * @param {Function} fFail Occurs if it doesn't support Data URI - */ - function _safeSetDataURI(fSuccess, fFail) { - var self = this; - self._fFail = fFail; - self._fSuccess = fSuccess; - - // Check it just once - if (self._bSupportDataURI === null) { - var el = document.createElement("img"); - var fOnError = function() { - self._bSupportDataURI = false; - - if (self._fFail) { - _fFail.call(self); - } - }; - var fOnSuccess = function() { - self._bSupportDataURI = true; - - if (self._fSuccess) { - self._fSuccess.call(self); - } - }; - - el.onabort = fOnError; - el.onerror = fOnError; - el.onload = fOnSuccess; - el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. - return; - } else if (self._bSupportDataURI === true && self._fSuccess) { - self._fSuccess.call(self); - } else if (self._bSupportDataURI === false && self._fFail) { - self._fFail.call(self); + var makeImpl = function(test, maskPattern) { + _moduleCount = _typeNumber * 4 + 17; + _modules = (function(moduleCount) { + var modules = new Array(moduleCount); + for (var row = 0; row < moduleCount; row += 1) { + modules[row] = new Array(moduleCount); + for (var col = 0; col < moduleCount; col += 1) { + modules[row][col] = null; } - }; - - /** - * Drawing QRCode by using canvas - * - * @constructor - * @param {HTMLElement} el - * @param {Object} htOption QRCode Options - */ - var Drawing = function (el, htOption) { - this._bIsPainted = false; - this._android = _getAndroid(); - - this._htOption = htOption; - this._elCanvas = document.createElement("canvas"); - this._elCanvas.width = htOption.width; - this._elCanvas.height = htOption.height; - el.appendChild(this._elCanvas); - this._el = el; - this._oContext = this._elCanvas.getContext("2d"); - this._bIsPainted = false; - this._elImage = document.createElement("img"); - this._elImage.alt = "Scan me!"; - this._elImage.style.display = "none"; - this._el.appendChild(this._elImage); - this._bSupportDataURI = null; - }; - - /** - * Draw the QRCode - * - * @param {QRCode} oQRCode - */ - Drawing.prototype.draw = function (oQRCode) { - var _elImage = this._elImage; - var _oContext = this._oContext; - var _htOption = this._htOption; - - var nCount = oQRCode.getModuleCount(); - var nWidth = _htOption.width / nCount; - var nHeight = _htOption.height / nCount; - var nRoundedWidth = Math.round(nWidth); - var nRoundedHeight = Math.round(nHeight); + } + return modules; + })(_moduleCount); - _elImage.style.display = "none"; - this.clear(); - - for (var row = 0; row < nCount; row++) { - for (var col = 0; col < nCount; col++) { - var bIsDark = oQRCode.isDark(row, col); - var nLeft = col * nWidth; - var nTop = row * nHeight; - _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; - _oContext.lineWidth = 1; - _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; - _oContext.fillRect(nLeft, nTop, nWidth, nHeight); - - // 안티 앨리어싱 방지 처리 - _oContext.strokeRect( - Math.floor(nLeft) + 0.5, - Math.floor(nTop) + 0.5, - nRoundedWidth, - nRoundedHeight - ); - - _oContext.strokeRect( - Math.ceil(nLeft) - 0.5, - Math.ceil(nTop) - 0.5, - nRoundedWidth, - nRoundedHeight - ); - } - } - - this._bIsPainted = true; - }; - - /** - * Make the image from Canvas if the browser supports Data URI. - */ - Drawing.prototype.makeImage = function () { - if (this._bIsPainted) { - _safeSetDataURI.call(this, _onMakeImage); - } - }; - - /** - * Return whether the QRCode is painted or not - * - * @return {Boolean} - */ - Drawing.prototype.isPainted = function () { - return this._bIsPainted; - }; - - /** - * Clear the QRCode - */ - Drawing.prototype.clear = function () { - this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); - this._bIsPainted = false; - }; - - /** - * @private - * @param {Number} nNumber - */ - Drawing.prototype.round = function (nNumber) { - if (!nNumber) { - return nNumber; - } - - return Math.floor(nNumber * 1000) / 1000; - }; - - return Drawing; - })(); - - /** - * Get the type by string length - * - * @private - * @param {String} sText - * @param {Number} nCorrectLevel - * @return {Number} type - */ - function _getTypeNumber(sText, nCorrectLevel) { - var nType = 1; - var length = _getUTF8Length(sText); - - for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { - var nLimit = 0; - - switch (nCorrectLevel) { - case QRErrorCorrectLevel.L : - nLimit = QRCodeLimitLength[i][0]; - break; - case QRErrorCorrectLevel.M : - nLimit = QRCodeLimitLength[i][1]; - break; - case QRErrorCorrectLevel.Q : - nLimit = QRCodeLimitLength[i][2]; - break; - case QRErrorCorrectLevel.H : - nLimit = QRCodeLimitLength[i][3]; - break; - } - - if (length <= nLimit) { - break; - } else { - nType++; - } - } - - if (nType > QRCodeLimitLength.length) { - throw new Error("Too long data"); - } - - return nType; - } + setupPositionProbePattern(0, 0); + setupPositionProbePattern(_moduleCount - 7, 0); + setupPositionProbePattern(0, _moduleCount - 7); + setupPositionAdjustPattern(); + setupTimingPattern(); + setupTypeInfo(test, maskPattern); - function _getUTF8Length(sText) { - var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); - return replacedText.length + (replacedText.length != sText ? 3 : 0); - } - - /** - * @class QRCode - * @constructor - * @example - * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); - * - * @example - * var oQRCode = new QRCode("test", { - * text : "http://naver.com", - * width : 128, - * height : 128 - * }); - * - * oQRCode.clear(); // Clear the QRCode. - * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. - * - * @param {HTMLElement|String} el target element or 'id' attribute of element. - * @param {Object|String} vOption - * @param {String} vOption.text QRCode link data - * @param {Number} [vOption.width=256] - * @param {Number} [vOption.height=256] - * @param {String} [vOption.colorDark="#000000"] - * @param {String} [vOption.colorLight="#ffffff"] - * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] - */ - QRCode = function (el, vOption) { - this._htOption = { - width : 256, - height : 256, - typeNumber : 4, - colorDark : "#000000", - colorLight : "#ffffff", - correctLevel : QRErrorCorrectLevel.H - }; - - if (typeof vOption === 'string') { - vOption = { - text : vOption - }; - } - - // Overwrites options - if (vOption) { - for (var i in vOption) { - this._htOption[i] = vOption[i]; - } - } - - if (typeof el == "string") { - el = document.getElementById(el); - } - - this._android = _getAndroid(); - this._el = el; - this._oQRCode = null; - this._oDrawing = new Drawing(this._el, this._htOption); - - if (this._htOption.text) { - this.makeCode(this._htOption.text); - } - }; - - /** - * Make the QRCode - * - * @param {String} sText link data - */ - QRCode.prototype.makeCode = function (sText) { - this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); - this._oQRCode.addData(sText); - this._oQRCode.make(); - this._el.title = sText; - this._oDrawing.draw(this._oQRCode); - this.makeImage(); - }; - - /** - * Make the Image from Canvas element - * - It occurs automatically - * - Android below 3 doesn't support Data-URI spec. - * - * @private - */ - QRCode.prototype.makeImage = function () { - if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { - this._oDrawing.makeImage(); - } - }; - - /** - * Clear the QRCode - */ - QRCode.prototype.clear = function () { - this._oDrawing.clear(); - }; - - /** - * @name QRCode.CorrectLevel - */ - QRCode.CorrectLevel = QRErrorCorrectLevel; -})(); + if (_typeNumber >= 7) { + setupTypeNumber(test); + } + + if (_dataCache == null) { + _dataCache = createData( + _typeNumber, + _errorCorrectionLevel, + _dataList + ); + } + + mapData(_dataCache, maskPattern); + }; + + var setupPositionProbePattern = function(row, col) { + for (var r = -1; r <= 7; r += 1) { + if (row + r <= -1 || _moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c += 1) { + if (col + c <= -1 || _moduleCount <= col + c) continue; + + if ( + (0 <= r && r <= 6 && (c == 0 || c == 6)) || + (0 <= c && c <= 6 && (r == 0 || r == 6)) || + (2 <= r && r <= 4 && 2 <= c && c <= 4) + ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + }; + + var getBestMaskPattern = function() { + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i += 1) { + makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(_this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }; + + var setupTimingPattern = function() { + for (var r = 8; r < _moduleCount - 8; r += 1) { + if (_modules[r][6] != null) { + continue; + } + _modules[r][6] = r % 2 == 0; + } + + for (var c = 8; c < _moduleCount - 8; c += 1) { + if (_modules[6][c] != null) { + continue; + } + _modules[6][c] = c % 2 == 0; + } + }; + + var setupPositionAdjustPattern = function() { + var pos = QRUtil.getPatternPosition(_typeNumber); + + for (var i = 0; i < pos.length; i += 1) { + for (var j = 0; j < pos.length; j += 1) { + var row = pos[i]; + var col = pos[j]; + + if (_modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r += 1) { + for (var c = -2; c <= 2; c += 1) { + if ( + r == -2 || + r == 2 || + c == -2 || + c == 2 || + (r == 0 && c == 0) + ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + } + } + }; + + var setupTypeNumber = function(test) { + var bits = QRUtil.getBCHTypeNumber(_typeNumber); + + for (var i = 0; i < 18; i += 1) { + var mod = !test && ((bits >> i) & 1) == 1; + _modules[Math.floor(i / 3)][(i % 3) + _moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i += 1) { + var mod = !test && ((bits >> i) & 1) == 1; + _modules[(i % 3) + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }; + + var setupTypeInfo = function(test, maskPattern) { + var data = (_errorCorrectionLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i += 1) { + var mod = !test && ((bits >> i) & 1) == 1; + + if (i < 6) { + _modules[i][8] = mod; + } else if (i < 8) { + _modules[i + 1][8] = mod; + } else { + _modules[_moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i += 1) { + var mod = !test && ((bits >> i) & 1) == 1; + + if (i < 8) { + _modules[8][_moduleCount - i - 1] = mod; + } else if (i < 9) { + _modules[8][15 - i - 1 + 1] = mod; + } else { + _modules[8][15 - i - 1] = mod; + } + } + + // fixed module + _modules[_moduleCount - 8][8] = !test; + }; + + var mapData = function(data, maskPattern) { + var inc = -1; + var row = _moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + var maskFunc = QRUtil.getMaskFunction(maskPattern); + + for (var col = _moduleCount - 1; col > 0; col -= 2) { + if (col == 6) col -= 1; + + while (true) { + for (var c = 0; c < 2; c += 1) { + if (_modules[row][col - c] == null) { + var dark = false; + + if (byteIndex < data.length) { + dark = ((data[byteIndex] >>> bitIndex) & 1) == 1; + } + + var mask = maskFunc(row, col - c); + + if (mask) { + dark = !dark; + } + + _modules[row][col - c] = dark; + bitIndex -= 1; + + if (bitIndex == -1) { + byteIndex += 1; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || _moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + }; + + var createBytes = function(buffer, rsBlocks) { + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r += 1) { + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i += 1) { + dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i += 1) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = modIndex >= 0 ? modPoly.getAt(modIndex) : 0; + } + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < dcdata[r].length) { + data[index] = dcdata[r][i]; + index += 1; + } + } + } + + for (var i = 0; i < maxEcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < ecdata[r].length) { + data[index] = ecdata[r][i]; + index += 1; + } + } + } + + return data; + }; + + var createData = function(typeNumber, errorCorrectionLevel, dataList) { + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel); + + var buffer = qrBitBuffer(); + + for (var i = 0; i < dataList.length; i += 1) { + var data = dataList[i]; + buffer.put(data.getMode(), 4); + buffer.put( + data.getLength(), + QRUtil.getLengthInBits(data.getMode(), typeNumber) + ); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error( + "code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + + ")" + ); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD1, 8); + } + + return createBytes(buffer, rsBlocks); + }; + + _this.addData = function(data, mode) { + mode = mode || "Byte"; + + var newData = null; + + switch (mode) { + case "Numeric": + newData = qrNumber(data); + break; + case "Alphanumeric": + newData = qrAlphaNum(data); + break; + case "Byte": + newData = qr8BitByte(data); + break; + case "Kanji": + newData = qrKanji(data); + break; + default: + throw "mode:" + mode; + } + + _dataList.push(newData); + _dataCache = null; + }; + + _this.isDark = function(row, col) { + if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { + throw new Error(row + "," + col); + } + return _modules[row][col]; + }; + + _this.getModuleCount = function() { + return _moduleCount; + }; + + _this.make = function() { + makeImpl(false, getBestMaskPattern()); + }; + + _this.createTableTag = function(cellSize, margin) { + cellSize = cellSize || 2; + margin = typeof margin == "undefined" ? cellSize * 4 : margin; + + var qrHtml = ""; + + qrHtml += '> 6), 0x80 | (charcode & 0x3f)); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push( + 0xe0 | (charcode >> 12), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f) + ); + } + // surrogate pair + else { + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = + 0x10000 + + (((charcode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff)); + utf8.push( + 0xf0 | (charcode >> 18), + 0x80 | ((charcode >> 12) & 0x3f), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f) + ); + } + } + return utf8; + } + return toUTF8Array(s); + }; + //--------------------------------------------------------------------- + // qrcode.createStringToBytes + //--------------------------------------------------------------------- + + /** + * @param unicodeData base64 string of byte array. + * [16bit Unicode],[16bit Bytes], ... + * @param numChars + */ + qrcode.createStringToBytes = function(unicodeData, numChars) { + // create conversion map. + + var unicodeMap = (function() { + var bin = base64DecodeInputStream(unicodeData); + var read = function() { + var b = bin.read(); + if (b == -1) throw new Error(); + return b; + }; + + var count = 0; + var unicodeMap = {}; + while (true) { + var b0 = bin.read(); + if (b0 == -1) break; + var b1 = read(); + var b2 = read(); + var b3 = read(); + var k = String.fromCharCode((b0 << 8) | b1); + var v = (b2 << 8) | b3; + unicodeMap[k] = v; + count += 1; + } + if (count != numChars) { + throw new Error(count + " != " + numChars); + } + + return unicodeMap; + })(); + + var unknownChar = "?".charCodeAt(0); + + return function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + if (c < 128) { + bytes.push(c); + } else { + var b = unicodeMap[s.charAt(i)]; + if (typeof b == "number") { + if ((b & 0xff) == b) { + // 1byte + bytes.push(b); + } else { + // 2bytes + bytes.push(b >>> 8); + bytes.push(b & 0xff); + } + } else { + bytes.push(unknownChar); + } + } + } + return bytes; + }; + }; + + //--------------------------------------------------------------------- + // QRMode + //--------------------------------------------------------------------- + + var QRMode = { + MODE_NUMBER: 1 << 0, + MODE_ALPHA_NUM: 1 << 1, + MODE_8BIT_BYTE: 1 << 2, + MODE_KANJI: 1 << 3 + }; + + //--------------------------------------------------------------------- + // QRErrorCorrectionLevel + //--------------------------------------------------------------------- + + var QRErrorCorrectionLevel = { + L: 1, + M: 0, + Q: 3, + H: 2 + }; + + //--------------------------------------------------------------------- + // QRMaskPattern + //--------------------------------------------------------------------- + + var QRMaskPattern = { + PATTERN000: 0, + PATTERN001: 1, + PATTERN010: 2, + PATTERN011: 3, + PATTERN100: 4, + PATTERN101: 5, + PATTERN110: 6, + PATTERN111: 7 + }; + + //--------------------------------------------------------------------- + // QRUtil + //--------------------------------------------------------------------- + + var QRUtil = (function() { + var PATTERN_POSITION_TABLE = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + var G15 = + (1 << 10) | + (1 << 8) | + (1 << 5) | + (1 << 4) | + (1 << 2) | + (1 << 1) | + (1 << 0); + var G18 = + (1 << 12) | + (1 << 11) | + (1 << 10) | + (1 << 9) | + (1 << 8) | + (1 << 5) | + (1 << 2) | + (1 << 0); + var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); + + var _this = {}; + + var getBCHDigit = function(data) { + var digit = 0; + while (data != 0) { + digit += 1; + data >>>= 1; + } + return digit; + }; + + _this.getBCHTypeInfo = function(data) { + var d = data << 10; + while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { + d ^= G15 << (getBCHDigit(d) - getBCHDigit(G15)); + } + return ((data << 10) | d) ^ G15_MASK; + }; + + _this.getBCHTypeNumber = function(data) { + var d = data << 12; + while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { + d ^= G18 << (getBCHDigit(d) - getBCHDigit(G18)); + } + return (data << 12) | d; + }; + + _this.getPatternPosition = function(typeNumber) { + return PATTERN_POSITION_TABLE[typeNumber - 1]; + }; + + _this.getMaskFunction = function(maskPattern) { + switch (maskPattern) { + case QRMaskPattern.PATTERN000: + return function(i, j) { + return (i + j) % 2 == 0; + }; + case QRMaskPattern.PATTERN001: + return function(i, j) { + return i % 2 == 0; + }; + case QRMaskPattern.PATTERN010: + return function(i, j) { + return j % 3 == 0; + }; + case QRMaskPattern.PATTERN011: + return function(i, j) { + return (i + j) % 3 == 0; + }; + case QRMaskPattern.PATTERN100: + return function(i, j) { + return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; + }; + case QRMaskPattern.PATTERN101: + return function(i, j) { + return ((i * j) % 2) + ((i * j) % 3) == 0; + }; + case QRMaskPattern.PATTERN110: + return function(i, j) { + return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0; + }; + case QRMaskPattern.PATTERN111: + return function(i, j) { + return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0; + }; + + default: + throw new Error("bad maskPattern:" + maskPattern); + } + }; + + _this.getErrorCorrectPolynomial = function(errorCorrectLength) { + var a = qrPolynomial([1], 0); + for (var i = 0; i < errorCorrectLength; i += 1) { + a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0)); + } + return a; + }; + + _this.getLengthInBits = function(mode, type) { + if (1 <= type && type < 10) { + // 1 - 9 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 10; + case QRMode.MODE_ALPHA_NUM: + return 9; + case QRMode.MODE_8BIT_BYTE: + return 8; + case QRMode.MODE_KANJI: + return 8; + default: + throw new Error("mode:" + mode); + } + } else if (type < 27) { + // 10 - 26 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 12; + case QRMode.MODE_ALPHA_NUM: + return 11; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 10; + default: + throw new Error("mode:" + mode); + } + } else if (type < 41) { + // 27 - 40 + + switch (mode) { + case QRMode.MODE_NUMBER: + return 14; + case QRMode.MODE_ALPHA_NUM: + return 13; + case QRMode.MODE_8BIT_BYTE: + return 16; + case QRMode.MODE_KANJI: + return 12; + default: + throw new Error("mode:" + mode); + } + } else { + throw new Error("type:" + type); + } + }; + + _this.getLostPoint = function(qrcode) { + var moduleCount = qrcode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount; col += 1) { + var sameCount = 0; + var dark = qrcode.isDark(row, col); + + for (var r = -1; r <= 1; r += 1) { + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c += 1) { + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrcode.isDark(row + r, col + c)) { + sameCount += 1; + } + } + } + + if (sameCount > 5) { + lostPoint += 3 + sameCount - 5; + } + } + } + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row += 1) { + for (var col = 0; col < moduleCount - 1; col += 1) { + var count = 0; + if (qrcode.isDark(row, col)) count += 1; + if (qrcode.isDark(row + 1, col)) count += 1; + if (qrcode.isDark(row, col + 1)) count += 1; + if (qrcode.isDark(row + 1, col + 1)) count += 1; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount - 6; col += 1) { + if ( + qrcode.isDark(row, col) && + !qrcode.isDark(row, col + 1) && + qrcode.isDark(row, col + 2) && + qrcode.isDark(row, col + 3) && + qrcode.isDark(row, col + 4) && + !qrcode.isDark(row, col + 5) && + qrcode.isDark(row, col + 6) + ) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount - 6; row += 1) { + if ( + qrcode.isDark(row, col) && + !qrcode.isDark(row + 1, col) && + qrcode.isDark(row + 2, col) && + qrcode.isDark(row + 3, col) && + qrcode.isDark(row + 4, col) && + !qrcode.isDark(row + 5, col) && + qrcode.isDark(row + 6, col) + ) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount; row += 1) { + if (qrcode.isDark(row, col)) { + darkCount += 1; + } + } + } + + var ratio = + Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + }; + + return _this; + })(); + + //--------------------------------------------------------------------- + // QRMath + //--------------------------------------------------------------------- + + var QRMath = (function() { + var EXP_TABLE = new Array(256); + var LOG_TABLE = new Array(256); + + // initialize tables + for (var i = 0; i < 8; i += 1) { + EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i += 1) { + EXP_TABLE[i] = + EXP_TABLE[i - 4] ^ + EXP_TABLE[i - 5] ^ + EXP_TABLE[i - 6] ^ + EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i += 1) { + LOG_TABLE[EXP_TABLE[i]] = i; + } + + var _this = {}; + + _this.glog = function(n) { + if (n < 1) { + throw new Error("glog(" + n + ")"); + } + + return LOG_TABLE[n]; + }; + + _this.gexp = function(n) { + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return EXP_TABLE[n]; + }; + + return _this; + })(); + + //--------------------------------------------------------------------- + // qrPolynomial + //--------------------------------------------------------------------- + + function qrPolynomial(num, shift) { + if (typeof num.length == "undefined") { + throw new Error(num.length + "/" + shift); + } + + var _num = (function() { + var offset = 0; + while (offset < num.length && num[offset] == 0) { + offset += 1; + } + var _num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i += 1) { + _num[i] = num[i + offset]; + } + return _num; + })(); + + var _this = {}; + + _this.getAt = function(index) { + return _num[index]; + }; + + _this.getLength = function() { + return _num.length; + }; + + _this.multiply = function(e) { + var num = new Array(_this.getLength() + e.getLength() - 1); + + for (var i = 0; i < _this.getLength(); i += 1) { + for (var j = 0; j < e.getLength(); j += 1) { + num[i + j] ^= QRMath.gexp( + QRMath.glog(_this.getAt(i)) + QRMath.glog(e.getAt(j)) + ); + } + } + + return qrPolynomial(num, 0); + }; + + _this.mod = function(e) { + if (_this.getLength() - e.getLength() < 0) { + return _this; + } + + var ratio = QRMath.glog(_this.getAt(0)) - QRMath.glog(e.getAt(0)); + + var num = new Array(_this.getLength()); + for (var i = 0; i < _this.getLength(); i += 1) { + num[i] = _this.getAt(i); + } + + for (var i = 0; i < e.getLength(); i += 1) { + num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i)) + ratio); + } + + // recursive call + return qrPolynomial(num, 0).mod(e); + }; + + return _this; + } + + //--------------------------------------------------------------------- + // QRRSBlock + //--------------------------------------------------------------------- + + var QRRSBlock = (function() { + var RS_BLOCK_TABLE = [ + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12, 7, 37, 13], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ]; + + var qrRSBlock = function(totalCount, dataCount) { + var _this = {}; + _this.totalCount = totalCount; + _this.dataCount = dataCount; + return _this; + }; + + var _this = {}; + + var getRsBlockTable = function(typeNumber, errorCorrectionLevel) { + switch (errorCorrectionLevel) { + case QRErrorCorrectionLevel.L: + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectionLevel.M: + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectionLevel.Q: + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectionLevel.H: + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default: + return undefined; + } + }; + + _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) { + var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel); + + if (typeof rsBlock == "undefined") { + throw new Error( + "bad rs block @ typeNumber:" + + typeNumber + + "/errorCorrectionLevel:" + + errorCorrectionLevel + ); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i += 1) { + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j += 1) { + list.push(qrRSBlock(totalCount, dataCount)); + } + } + + return list; + }; + + return _this; + })(); + + //--------------------------------------------------------------------- + // qrBitBuffer + //--------------------------------------------------------------------- + + var qrBitBuffer = function() { + var _buffer = new Array(); + var _length = 0; + + var _this = {}; + + _this.getBuffer = function() { + return _buffer; + }; + + _this.getAt = function(index) { + var bufIndex = Math.floor(index / 8); + return ((_buffer[bufIndex] >>> (7 - (index % 8))) & 1) == 1; + }; + + _this.put = function(num, length) { + for (var i = 0; i < length; i += 1) { + _this.putBit(((num >>> (length - i - 1)) & 1) == 1); + } + }; + + _this.getLengthInBits = function() { + return _length; + }; + + _this.putBit = function(bit) { + var bufIndex = Math.floor(_length / 8); + if (_buffer.length <= bufIndex) { + _buffer.push(0); + } + + if (bit) { + _buffer[bufIndex] |= 0x80 >>> _length % 8; + } + + _length += 1; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qrNumber + //--------------------------------------------------------------------- + + var qrNumber = function(data) { + var _mode = QRMode.MODE_NUMBER; + var _data = data; + + var _this = {}; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _data.length; + }; + + _this.write = function(buffer) { + var data = _data; + + var i = 0; + + while (i + 2 < data.length) { + buffer.put(strToNum(data.substring(i, i + 3)), 10); + i += 3; + } + + if (i < data.length) { + if (data.length - i == 1) { + buffer.put(strToNum(data.substring(i, i + 1)), 4); + } else if (data.length - i == 2) { + buffer.put(strToNum(data.substring(i, i + 2)), 7); + } + } + }; + + var strToNum = function(s) { + var num = 0; + for (var i = 0; i < s.length; i += 1) { + num = num * 10 + chatToNum(s.charAt(i)); + } + return num; + }; + + var chatToNum = function(c) { + if ("0" <= c && c <= "9") { + return c.charCodeAt(0) - "0".charCodeAt(0); + } + throw "illegal char :" + c; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qrAlphaNum + //--------------------------------------------------------------------- + + var qrAlphaNum = function(data) { + var _mode = QRMode.MODE_ALPHA_NUM; + var _data = data; + + var _this = {}; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _data.length; + }; + + _this.write = function(buffer) { + var s = _data; + + var i = 0; + + while (i + 1 < s.length) { + buffer.put(getCode(s.charAt(i)) * 45 + getCode(s.charAt(i + 1)), 11); + i += 2; + } + + if (i < s.length) { + buffer.put(getCode(s.charAt(i)), 6); + } + }; + + var getCode = function(c) { + if ("0" <= c && c <= "9") { + return c.charCodeAt(0) - "0".charCodeAt(0); + } else if ("A" <= c && c <= "Z") { + return c.charCodeAt(0) - "A".charCodeAt(0) + 10; + } else { + switch (c) { + case " ": + return 36; + case "$": + return 37; + case "%": + return 38; + case "*": + return 39; + case "+": + return 40; + case "-": + return 41; + case ".": + return 42; + case "/": + return 43; + case ":": + return 44; + default: + throw "illegal char :" + c; + } + } + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qr8BitByte + //--------------------------------------------------------------------- + + var qr8BitByte = function(data) { + var _mode = QRMode.MODE_8BIT_BYTE; + var _data = data; + var _bytes = qrcode.stringToBytes(data); + + var _this = {}; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _bytes.length; + }; + + _this.write = function(buffer) { + for (var i = 0; i < _bytes.length; i += 1) { + buffer.put(_bytes[i], 8); + } + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // qrKanji + //--------------------------------------------------------------------- + + var qrKanji = function(data) { + var _mode = QRMode.MODE_KANJI; + var _data = data; + var _bytes = qrcode.stringToBytes(data); + + !(function(c, code) { + // self test for sjis support. + var test = qrcode.stringToBytes(c); + if (test.length != 2 || ((test[0] << 8) | test[1]) != code) { + throw "sjis not supported."; + } + })("\u53cb", 0x9746); + + var _this = {}; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return ~~(_bytes.length / 2); + }; + + _this.write = function(buffer) { + var data = _bytes; + + var i = 0; + + while (i + 1 < data.length) { + var c = ((0xff & data[i]) << 8) | (0xff & data[i + 1]); + + if (0x8140 <= c && c <= 0x9ffc) { + c -= 0x8140; + } else if (0xe040 <= c && c <= 0xebbf) { + c -= 0xc140; + } else { + throw "illegal char at " + (i + 1) + "/" + c; + } + + c = ((c >>> 8) & 0xff) * 0xc0 + (c & 0xff); + + buffer.put(c, 13); + + i += 2; + } + + if (i < data.length) { + throw "illegal char at " + (i + 1); + } + }; + + return _this; + }; + + //===================================================================== + // GIF Support etc. + // + + //--------------------------------------------------------------------- + // byteArrayOutputStream + //--------------------------------------------------------------------- + + var byteArrayOutputStream = function() { + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i)); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ""; + s += "["; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ","; + } + s += _bytes[i]; + } + s += "]"; + return s; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // base64EncodeOutputStream + //--------------------------------------------------------------------- + + var base64EncodeOutputStream = function() { + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ""; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f)); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error("n:" + n); + }; + + _this.writeByte = function(n) { + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6)); + _buflen -= 6; + } + }; + + _this.flush = function() { + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen)); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - (_length % 3); + for (var i = 0; i < padlen; i += 1) { + _base64 += "="; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // base64DecodeInputStream + //--------------------------------------------------------------------- + + var base64DecodeInputStream = function(str) { + var _str = str; + var _pos = 0; + var _buffer = 0; + var _buflen = 0; + + var _this = {}; + + _this.read = function() { + while (_buflen < 8) { + if (_pos >= _str.length) { + if (_buflen == 0) { + return -1; + } + throw new Error("unexpected end of file./" + _buflen); + } + + var c = _str.charAt(_pos); + _pos += 1; + + if (c == "=") { + _buflen = 0; + return -1; + } else if (c.match(/^\s$/)) { + // ignore if whitespace. + continue; + } + + _buffer = (_buffer << 6) | decode(c.charCodeAt(0)); + _buflen += 6; + } + + var n = (_buffer >>> (_buflen - 8)) & 0xff; + _buflen -= 8; + return n; + }; + + var decode = function(c) { + if (0x41 <= c && c <= 0x5a) { + return c - 0x41; + } else if (0x61 <= c && c <= 0x7a) { + return c - 0x61 + 26; + } else if (0x30 <= c && c <= 0x39) { + return c - 0x30 + 52; + } else if (c == 0x2b) { + return 62; + } else if (c == 0x2f) { + return 63; + } else { + throw new Error("c:" + c); + } + }; + + return _this; + }; + + //--------------------------------------------------------------------- + // gifImage (B/W) + //--------------------------------------------------------------------- + + var gifImage = function(width, height) { + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + //--------------------------------- + // GIF Signature + + out.writeString("GIF87a"); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(","); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(";"); + }; + + var bitOutputStream = function(out) { + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + if (data >>> length != 0) { + throw new Error("length over"); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ((data << _bitLength) | _bitBuffer)); + length -= 8 - _bitLength; + data >>>= 8 - _bitLength; + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i)); + } + table.add(String.fromCharCode(clearCode)); + table.add(String.fromCharCode(endCode)); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c)) { + s = s + c; + } else { + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + if (table.size() == 1 << bitLength) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key)) { + throw new Error("dup key:" + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != "undefined"; + }; + + return _this; + }; + + return _this; + }; + + var createImgTag = function(width, height, getPixel, alt) { + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y)); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ""; + img += "= 4 ? "" : ";CHARSET=UTF-8"; + encodingPrefix = ""; + if (!vCard.version) { + vCard.version = "4.0"; + } + formattedVCardString += "BEGIN:VCARD" + nl(); + formattedVCardString += "VERSION:" + vCard.version + nl(); + + var formattedName = vCard.formattedName; + + if (!formattedName) { + formattedName = ""; + + [vCard.firstName, vCard.middleName, vCard.lastName].forEach(function( + name + ) { + if (name) { + if (formattedName) { + formattedName += " "; + } + } + formattedName += name; + }); + } + + formattedVCardString += + "FN" + encodingPrefix + ":" + e(formattedName) + nl(); + formattedVCardString += + "N" + + encodingPrefix + + ":" + + e(vCard.lastName) + + ";" + + e(vCard.firstName) + + ";" + + e(vCard.middleName) + + ";" + + e(vCard.namePrefix) + + ";" + + e(vCard.nameSuffix) + + nl(); + + if (vCard.nickname && majorVersion >= 3) { + formattedVCardString += + "NICKNAME" + encodingPrefix + ":" + e(vCard.nickname) + nl(); + } + + if (vCard.gender) { + formattedVCardString += "GENDER:" + e(vCard.gender) + nl(); + } + + if (vCard.birthday) { + formattedVCardString += "BDAY:" + vCard.birthday + nl(); + } + + if (vCard.anniversary) { + formattedVCardString += "ANNIVERSARY:" + vCard.anniversary + nl(); + } + + if (vCard.email) { + if (!Array.isArray(vCard.email)) { + vCard.email = new Array(vCard.email); + } + vCard.email.forEach(function(address) { + if (majorVersion >= 4) { + formattedVCardString += + "EMAIL" + encodingPrefix + ";type=HOME:" + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += + "EMAIL" + + encodingPrefix + + ";type=HOME,INTERNET:" + + e(address) + + nl(); + } else { + formattedVCardString += + "EMAIL" + encodingPrefix + ";HOME;INTERNET:" + e(address) + nl(); + } + }); + } + + if (vCard.workEmail) { + if (!Array.isArray(vCard.workEmail)) { + vCard.workEmail = new Array(vCard.workEmail); + } + vCard.workEmail.forEach(function(address) { + if (majorVersion >= 4) { + formattedVCardString += + "EMAIL" + encodingPrefix + ";type=WORK:" + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += + "EMAIL" + + encodingPrefix + + ";type=WORK,INTERNET:" + + e(address) + + nl(); + } else { + formattedVCardString += + "EMAIL" + encodingPrefix + ";WORK;INTERNET:" + e(address) + nl(); + } + }); + } + + if (vCard.otherEmail) { + if (!Array.isArray(vCard.otherEmail)) { + vCard.otherEmail = new Array(vCard.otherEmail); + } + vCard.otherEmail.forEach(function(address) { + if (majorVersion >= 4) { + formattedVCardString += + "EMAIL" + encodingPrefix + ";type=OTHER:" + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += + "EMAIL" + + encodingPrefix + + ";type=OTHER,INTERNET:" + + e(address) + + nl(); + } else { + formattedVCardString += + "EMAIL" + encodingPrefix + ";OTHER;INTERNET:" + e(address) + nl(); + } + }); + } + + if (vCard.logo && vCard.logo.url) { + formattedVCardString += getFormattedPhoto( + "LOGO", + vCard.logo.url, + vCard.logo.mediaType, + vCard.logo.base64, + majorVersion + ); + } + + if (vCard.photo && vCard.photo.url) { + formattedVCardString += getFormattedPhoto( + "PHOTO", + vCard.photo.url, + vCard.photo.mediaType, + vCard.photo.base64, + majorVersion + ); + } + + if (vCard.cellPhone) { + if (!Array.isArray(vCard.cellPhone)) { + vCard.cellPhone = new Array(vCard.cellPhone); + } + vCard.cellPhone.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="voice,cell":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=CELL:" + e(number) + nl(); + } + }); + } + + if (vCard.pagerPhone) { + if (!Array.isArray(vCard.pagerPhone)) { + vCard.pagerPhone = new Array(vCard.pagerPhone); + } + vCard.pagerPhone.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="pager,cell":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=PAGER:" + e(number) + nl(); + } + }); + } + + if (vCard.homePhone) { + if (!Array.isArray(vCard.homePhone)) { + vCard.homePhone = new Array(vCard.homePhone); + } + vCard.homePhone.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="voice,home":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=HOME,VOICE:" + e(number) + nl(); + } + }); + } + + if (vCard.workPhone) { + if (!Array.isArray(vCard.workPhone)) { + vCard.workPhone = new Array(vCard.workPhone); + } + vCard.workPhone.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="voice,work":tel:' + e(vCard.workPhone) + nl(); + } else { + formattedVCardString += + "TEL;TYPE=WORK,VOICE:" + e(vCard.workPhone) + nl(); + } + }); + } + + if (vCard.homeFax) { + if (!Array.isArray(vCard.homeFax)) { + vCard.homeFax = new Array(vCard.homeFax); + } + vCard.homeFax.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="fax,home":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=HOME,FAX:" + e(number) + nl(); + } + }); + } + + if (vCard.workFax) { + if (!Array.isArray(vCard.workFax)) { + vCard.workFax = new Array(vCard.workFax); + } + vCard.workFax.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="fax,work":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=WORK,FAX:" + e(number) + nl(); + } + }); + } + + if (vCard.otherPhone) { + if (!Array.isArray(vCard.otherPhone)) { + vCard.otherPhone = new Array(vCard.otherPhone); + } + vCard.otherPhone.forEach(function(number) { + if (majorVersion >= 4) { + formattedVCardString += + 'TEL;VALUE=uri;TYPE="voice,other":tel:' + e(number) + nl(); + } else { + formattedVCardString += "TEL;TYPE=OTHER:" + e(number) + nl(); + } + }); + } + + [ + { + details: vCard.homeAddress || {}, + type: "HOME" + }, + { + details: vCard.workAddress || {}, + type: "WORK" + } + ].forEach(function(address) { + formattedVCardString += getFormattedAddress( + encodingPrefix, + address, + majorVersion + ); + }); + + if (vCard.title) { + formattedVCardString += + "TITLE" + encodingPrefix + ":" + e(vCard.title) + nl(); + } + + if (vCard.role) { + formattedVCardString += + "ROLE" + encodingPrefix + ":" + e(vCard.role) + nl(); + } + + if (vCard.organization) { + formattedVCardString += + "ORG" + encodingPrefix + ":" + e(vCard.organization) + nl(); + } + + if (vCard.url) { + formattedVCardString += + "URL" + encodingPrefix + ":" + e(vCard.url) + nl(); + } + + if (vCard.workUrl) { + formattedVCardString += + "URL;type=WORK" + encodingPrefix + ":" + e(vCard.workUrl) + nl(); + } + + if (vCard.note) { + formattedVCardString += + "NOTE" + encodingPrefix + ":" + e(vCard.note) + nl(); + } + + if (vCard.socialUrls) { + for (var key in vCard.socialUrls) { + if (vCard.socialUrls.hasOwnProperty(key) && vCard.socialUrls[key]) { + formattedVCardString += + "X-SOCIALPROFILE" + + encodingPrefix + + ";TYPE=" + + key + + ";x-user=" + + e(vCard.socialUrls[key]) + + ":" + + getSocialUrls(key, vCard.socialUrls[key]) + + nl(); + } + } + } + if (vCard.source) { + formattedVCardString += + "SOURCE" + encodingPrefix + ":" + e(vCard.source) + nl(); + } + if (vCard.rev) { + formattedVCardString += "REV:" + e(vCard.REV) + nl(); + } + formattedVCardString += "END:VCARD" + nl(); + return formattedVCardString; + }; + + /** + * Create QR code from vCard + * + * + * @param vCard {object} - object vCard + * @param options {string|object} + * @param options.typeNumber {number} - Type number (1 ~ 40) + * @param options.typeElement {number} - Type element create QR ('createImg','createSvg','createTable') + * @param options.errorCorrectionLevel {string} - Error correction level ('L', 'M', 'Q', 'H') + * @param options.data {string} - Error correction level ('L', 'M', 'Q', 'H') + * @param options.mode {string} - Mode ('Numeric', 'Alphanumeric', 'Byte'(default), 'Kanji') + * @param options.cellSize {number} - Size qr default: 2 + * @param options.margin {number} - Margin qr default: cellSize * 4 + * @return {string} + */ + QrCode.prototype.createVCardQr = function(vCard, options) { + options.data = this.createVCard(vCard); + return this.createQr(options); + }; + + return new QrCode(); +}); diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 805a758100..6a18af8faf 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -6888,6 +6888,10 @@ div.graph div.legend table { margin-left: 15px; } +.mrgn_lft_17px { + margin-left: 17px; +} + .mrgn_lft_20px { margin-left: 20px; } @@ -11821,3 +11825,7 @@ span.help_icon_15px > img { transform: rotate(360deg); } } + +.scale-0-8 { + transform: scale(0.8); +} diff --git a/pandora_console/operation/agentes/alerts_status.php b/pandora_console/operation/agentes/alerts_status.php index fda858cbc6..d970c5aa65 100755 --- a/pandora_console/operation/agentes/alerts_status.php +++ b/pandora_console/operation/agentes/alerts_status.php @@ -326,6 +326,7 @@ if (is_metaconsole() === true) { 1, 2, 3, + -3, -1, ]; } else { @@ -333,6 +334,7 @@ if (is_metaconsole() === true) { 0, 1, 2, + -3, -1, ]; } diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index ed7bd20ea0..62a8850b80 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -820,7 +820,7 @@ if (is_ajax() === true) { break; } - $draw_state = '
'; + $draw_state = '
'; $draw_state .= ''; From 6a6c99dcab1bcf0fe6b681308b508fc08e8aebb6 Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 29 Mar 2023 16:31:25 +0200 Subject: [PATCH 13/15] fixed styles --- pandora_console/include/class/CustomNetScan.class.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/class/CustomNetScan.class.php b/pandora_console/include/class/CustomNetScan.class.php index d2d8cd4700..e0fd3708ac 100644 --- a/pandora_console/include/class/CustomNetScan.class.php +++ b/pandora_console/include/class/CustomNetScan.class.php @@ -523,11 +523,13 @@ class CustomNetScan extends Wizard // Schedule. $form['inputs'][] = [ - 'label' => __('Interval').ui_print_help_tip( + 'label' => __('Interval').ui_print_help_tip( __('Manual interval means that it will be executed only On-demand'), true ), - 'arguments' => [ + 'class' => 'input-interval', + 'extra-container' => true, + 'arguments' => [ 'type' => 'select', 'selected' => $interv_manual, 'fields' => [ @@ -537,7 +539,7 @@ class CustomNetScan extends Wizard 'name' => 'interval_manual_defined', 'return' => true, ], - 'extra' => ''.html_print_extended_select_for_time( + 'extra' => ''.html_print_extended_select_for_time( 'interval', $this->task['interval_sweep'], '', From 8c3b5d650debec3919701bede6de36a068c4fcf0 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 29 Mar 2023 16:50:17 +0200 Subject: [PATCH 14/15] tree view dashboard metaconsole --- .../include/javascript/tree/TreeController.js | 12 +++++-- .../lib/Dashboard/Widgets/tree_view.php | 31 +++++-------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/pandora_console/include/javascript/tree/TreeController.js b/pandora_console/include/javascript/tree/TreeController.js index 368ebd69a9..841e48dbe1 100644 --- a/pandora_console/include/javascript/tree/TreeController.js +++ b/pandora_console/include/javascript/tree/TreeController.js @@ -655,7 +655,7 @@ var TreeController = { $content.append( '
0 ? controller.baseURL : "") + - 'images/module-graph.svg" /> ' + (controller.baseURL.indexOf("meta") !== -1 + ? "../../images/" + : "images/") + + 'module-graph.svg" /> ' ); } @@ -1123,7 +1126,10 @@ var TreeController = { (controller.baseURL.length > 0 ? controller.baseURL : "") + - 'images/simple-value.svg" /> ' + (controller.baseURL.indexOf("meta") !== -1 + ? "../../images/" + : "images/") + + 'simple-value.svg" /> ' ); $dataImage .addClass("module-data") diff --git a/pandora_console/include/lib/Dashboard/Widgets/tree_view.php b/pandora_console/include/lib/Dashboard/Widgets/tree_view.php index e832f1293f..a351f8b156 100644 --- a/pandora_console/include/lib/Dashboard/Widgets/tree_view.php +++ b/pandora_console/include/lib/Dashboard/Widgets/tree_view.php @@ -134,12 +134,7 @@ class TreeViewWidget extends Widget ) { global $config; - if (is_metaconsole() === true) { - ui_require_css_file('tree_meta'); - } else { - ui_require_css_file('tree'); - } - + ui_require_css_file('tree'); ui_require_css_file('fixed-bottom-box'); // WARNING: Do not edit. This chunk must be in the constructor. @@ -559,11 +554,7 @@ class TreeViewWidget extends Widget $height = $size['height']; // Css Files. - if (is_metaconsole() === true) { - \ui_require_css_file('tree_meta', 'include/styles/', true); - } else { - \ui_require_css_file('tree', 'include/styles/', true); - } + \ui_require_css_file('tree', 'include/styles/', true); if ($config['style'] == 'pandora_black' && !is_metaconsole()) { \ui_require_css_file('pandora_black', 'include/styles/', true); @@ -576,19 +567,11 @@ class TreeViewWidget extends Widget 'include/javascript/i18n/' ); - if (is_metaconsole() === true) { - \ui_require_javascript_file( - 'TreeControllerMeta', - 'include/javascript/tree/', - true - ); - } else { - \ui_require_javascript_file( - 'TreeController', - 'include/javascript/tree/', - true - ); - } + \ui_require_javascript_file( + 'TreeController', + 'include/javascript/tree/', + true + ); \ui_require_javascript_file( 'fixed-bottom-box', From f26e70630af7405696ee59af7c3686083e1994ac Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Wed, 29 Mar 2023 17:09:41 +0200 Subject: [PATCH 15/15] Blue background & Datatable fix --- pandora_console/include/functions_ui.php | 5 +++-- pandora_console/operation/agentes/group_view.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 2f88d2d86f..e04067551f 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -4070,15 +4070,16 @@ function ui_print_datatable(array $parameters) }"; } - $js .= '});'; + $js .= '$("table#'.$table_id.'").removeClass("invisible"); + });'; $js .= ' $(function() { $(document).on("preInit.dt", function (ev, settings) { - // $("table#'.$table_id.'").hide(); $("div.dataTables_length").hide(); $("div.dt-buttons").hide(); }); }); + '; $js .= ''; diff --git a/pandora_console/operation/agentes/group_view.php b/pandora_console/operation/agentes/group_view.php index 63fc0ab41c..a1db772a47 100644 --- a/pandora_console/operation/agentes/group_view.php +++ b/pandora_console/operation/agentes/group_view.php @@ -192,7 +192,7 @@ echo '
'; echo "".$total_agent_warning.'%'; echo "".$total_agent_ok.'%'; echo "".$total_agent_unknown.'%'; - echo "".$total_not_init.'%'; + echo "".$total_not_init.'%'; echo ''; echo "
"; echo "".$total_critical.'%';