Added Japaneese machine translation.

This commit is contained in:
Ylian Saint-Hilaire 2019-12-09 16:34:37 -08:00
parent 990214ed19
commit 9ddde5d450
37 changed files with 29746 additions and 6711 deletions

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.4.5-m",
"version": "0.4.5-o",
"keywords": [
"Remote Management",
"Intel AMT",

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,537 @@
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
<script type="text/javascript" src="scripts/amt-terminal-0.0.2.js"></script>
<script type="text/javascript" src="scripts/zlib.js"></script>
<script type="text/javascript" src="scripts/zlib-inflate.js"></script>
<script type="text/javascript" src="scripts/zlib-adler32.js"></script>
<script type="text/javascript" src="scripts/zlib-crc32.js"></script>
</head>
<body style="overflow:hidden;background-color:black">
<div id="p11" class="noselect" style="overflow:hidden">
<div id="deskarea0">
<div id="deskarea1" class="areaHead">
<div class="toright2">
<div class="deskareaicon" title="表示モードの切り替え" onclick="toggleAspectRatio(1)"></div>
</div>
<div>
<input id="OpenFileButton" type="button" value="ファイルを開く..." onclick="openfile()">
<span id="deskstatus"></span>
</div>
</div>
<div id="deskarea2" style="">
<div class="areaProgress"><div id="progressbar" style=""></div></div>
</div>
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b></b></div>
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b></b></div>
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
<div id="DeskParent">
<canvas id="Desk" width="640" height="480"></canvas>
</div>
<div id="TermParent" style="display:none">
<pre id="Term"></pre>
</div>
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
</div>
<div id="deskarea4" class="areaFoot">
<div class="toright2">
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
</div>
<div>
&nbsp;
<input id="PlayButton" type="button" value="遊びます" disabled="disabled" onclick="play()">
<input id="PauseButton" type="button" value="一時停止" disabled="disabled" onclick="pause()">
<input id="RestartButton" type="button" value="再起動" disabled="disabled" onclick="restart()">
<select id="PlaySpeed" onchange="this.blur();">
<option value="4">1/4スピード</option>
<option value="2">1/2速度</option>
<option value="1" selected="">通常速度</option>
<option value="0.5">2倍速</option>
<option value="0.25">4倍速</option>
<option value="0.1">10倍速</option>
</select>
</div>
</div>
</div>
<div id="dialog" class="noselect" style="display:none">
<div id="dialogHeader">
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()"></div>
<div id="id_dialogtitle"></div>
</div>
<div id="dialogBody">
<div id="dialog1">
<div id="id_dialogMessage" style=""></div>
</div>
<div id="dialog2" style="">
<div id="id_dialogOptions"></div>
</div>
</div>
<div id="idx_dlgButtonBar">
<input id="idx_dlgCancelButton" type="button" value="キャンセル" style="" onclick="dialogclose(0)">
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
<div><input id="idx_dlgDeleteButton" type="button" value="削除する" style="display:none" onclick="dialogclose(2)"></div>
</div>
</div>
</div>
<script>
var recFile = null;
var recFilePtr = 0;
var recFileStartTime = 0;
var recFileLastTime = 0;
var recFileEndTime = 0;
var recFileMetadata = null;
var recFileProtocol = 0;
var agentDesktop = null;
var amtDesktop = null;
var playing = false;
var readState = 0;
var waitTimer = null;
var waitTimerArgs = null;
var deskAspectRatio = 0;
var currentDeltaTimeTotalSec = 0;
function start() {
window.onresize = deskAdjust;
document.ondrop = ondrop;
document.ondragover = ondragover;
document.ondragleave = ondragleave;
document.onkeypress = onkeypress;
Q('PlaySpeed').value = 1;
cleanup();
}
function readNextBlock(func) {
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
var fr = new FileReader();
fr.onload = function () {
var type = ReadShort(this.result, 0);
var flags = ReadShort(this.result, 2);
var size = ReadInt(this.result, 4);
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
var fr2 = new FileReader();
fr2.onload = function () {
recFilePtr += (16 + size);
if (recFileEndTime == 0) {
// File pointer progress bar
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
} else {
// Time progress bar
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
}
func(type, flags, time, this.result);
};
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
}
};
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
}
}
function readLastBlock(func) {
if (recFile.size < 32) { func(-1); } else {
var fr = new FileReader();
fr.onload = function () {
var type = ReadShort(this.result, 0);
var flags = ReadShort(this.result, 2);
var size = ReadInt(this.result, 4);
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
};
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
}
}
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
function addInfoNoEsc(name, value) {
if (value == null) return '';
return '<span style=color:gray>' + EscapeHtml(name) + '</span>:&nbsp;<span style=font-size:20px>' + value + '</span><br/>';
}
function processFirstBlock(type, flags, time, data) {
recFileProtocol = 0;
if ((type != 1) || (flags != 0)) { cleanup(); return; }
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
var x = '';
x += addInfo("時間", recFileMetadata.time);
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("期間", format("{0}秒{1}", secs, (secs > 1) ? 's' : '')); }
x += addInfo("ユーザー名", recFileMetadata.username);
x += addInfo("ユーザーID", recFileMetadata.userid);
x += addInfo("セッションID", recFileMetadata.sessionid);
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("住所", format("{0}から{1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
if (recFileMetadata.devicename) { x += addInfo("装置名", recFileMetadata.devicename); }
x += addInfo("NodeID", recFileMetadata.nodeid);
if (recFileMetadata.protocol) {
var p = recFileMetadata.protocol;
if (p == 1) { p = "MeshCentralターミナル"; }
else if (p == 2) { p = "MeshCentralデスクトップ"; }
else if (p == 100) { p = "Intelreg; AMT WSMAN"; }
else if (p == 101) { p = "Intelreg; AMTリダイレクト"; }
x += addInfoNoEsc("プロトコル", p);
}
QV('DeskParent', true);
QV('TermParent', false);
if (recFileMetadata.protocol == 1) {
// MeshCentral remote terminal
recFileProtocol = 1;
x += '<br /><br /><span style=color:gray>' + "[スペース]を押して再生/一時停止します。" + '</span>';
QE('PlayButton', true);
QE('PauseButton', false);
QE('RestartButton', false);
recFileStartTime = recFileLastTime = time;
}
else if (recFileMetadata.protocol == 2) {
// MeshCentral remote desktop
recFileProtocol = 2;
x += '<br /><br /><span style=color:gray>' + "[スペース]を押して再生/一時停止します。" + '</span>';
QE('PlayButton', true);
QE('PauseButton', false);
QE('RestartButton', false);
recFileStartTime = recFileLastTime = time;
agentDesktop = CreateAgentRemoteDesktop('Desk');
agentDesktop.onScreenSizeChange = deskAdjust;
agentDesktop.State = 3;
deskAdjust();
}
else if (recFileMetadata.protocol == 101) {
// Intel AMT Redirection
recFileProtocol = 101;
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
QE('PlayButton', true);
QE('PauseButton', false);
QE('RestartButton', false);
recFileStartTime = recFileLastTime = time;
amtDesktop = CreateAmtRemoteDesktop('Desk');
amtDesktop.onScreenSizeChange = deskAdjust;
amtDesktop.State = 3;
amtDesktop.Start();
deskAdjust();
}
QV('metadatadiv', true);
QH('metadatadiv', x);
QH('deskstatus', recFile.name);
}
function processBlock(type, flags, time, data) {
if (type < 0) { pause(); return; }
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
if (waitTime < 5) {
processBlockEx(type, flags, time, data);
} else {
waitTimerArgs = [type, flags, time, data]
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
}
}
function processBlockEx(type, flags, time, data) {
if (playing == false) return;
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
// Update the clock
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
currentDeltaTimeTotalSec = deltaTimeTotalSec;
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
deltaTimeTotalSec -= (deltaTimeHours * 3600)
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
deltaTimeTotalSec -= (deltaTimeHours * 60)
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
}
if ((type == 2) && flagBinary && !flagUser) {
// Device --> User data
if (recFileProtocol == 1) {
// MeshCentral Terminal
agentTerminal.ProcessData(data);
} else if (recFileProtocol == 2) {
// MeshCentral Remote Desktop
agentDesktop.ProcessData(data);
} else if (recFileProtocol == 101) {
// Intel AMT KVM
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
// We are not authenticated, KVM data starts here.
readState = 1;
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
} else if (readState == 1) {
amtDesktop.ProcessData(data);
}
}
} else if ((type == 2) && flagBinary && flagUser) {
// User --> Device data
if (recFileProtocol == 101) {
// Intel AMT KVM
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
}
}
recFileLastTime = time;
if (playing) { readNextBlock(processBlock); }
}
function cleanup() {
recFile = null;
recFilePtr = 0;
recFileMetadata = null;
playing = false;
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
readState = 0;
waitTimerArgs = null;
currentDeltaTimeTotalSec = 0;
recFileEndTime = 0;
agentTerminal = null;
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
QH('deskstatus', '');
QE('PlayButton', false);
QE('PauseButton', false);
QE('RestartButton', false);
QS('progressbar').width = '0px';
QH('timespan', '00:00:00');
QV('metadatadiv', true);
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + ".mcrecファイルをドラッグアンドドロップするか、[ファイルを開く...]をクリックします" + '</span>');
QV('DeskParent', true);
QV('TermParent', false);
}
function ondrop(e) {
haltEvent(e);
QV('bigfail', false);
QV('bigok', false);
// Check if these are files we can upload, remove all folders.
if (e.dataTransfer == null) return;
var files = [];
for (var i in e.dataTransfer.files) {
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
files.push(e.dataTransfer.files[i]);
}
}
if (files.length == 0) return;
cleanup();
recFile = files[0];
recFilePtr = 0;
readNextBlock(processFirstBlock);
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
}
var dragtimer = null;
function ondragover(e) {
haltEvent(e);
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
var ac = true;
QV('bigok', ac);
QV('bigfail', !ac);
}
function ondragleave(e) {
haltEvent(e);
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
}
function onkeypress(e) {
if (xxdialogMode) return;
if (e.key == ' ') { togglePause(); haltEvent(e); }
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
if (e.key == '0') { pause(); restart(); haltEvent(e); }
}
function openfile() {
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
setDialogMode(2, "ファイルを開く...", 3, openfileEx, x);
QE('idx_dlgOkButton', false);
}
function openfileEx() {
var xfiles = Q('p2fileinput').files;
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
if (files.length == 0) return;
cleanup();
recFile = files[0];
recFilePtr = 0;
readNextBlock(processFirstBlock);
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
Q('OpenFileButton').blur();
}
function openfileChanged() {
var xfiles = Q('p2fileinput').files;
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
QE('idx_dlgOkButton', files.length == 1);
}
function togglePause() {
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
}
function play() {
Q('PlayButton').blur();
if ((playing == true) || (recFileProtocol == 0)) return;
playing = true;
QV('metadatadiv', false);
QE('PlayButton', false);
QE('PauseButton', true);
QE('RestartButton', false);
if ((recFileProtocol == 1) && (agentTerminal == null)) {
QV('DeskParent', false);
QV('TermParent', true);
agentTerminal = CreateAmtRemoteTerminal('Term', {});
agentTerminal.State = 3;
}
readNextBlock(processBlock);
}
function pause() {
Q('PauseButton').blur();
if (playing == false) return;
playing = false;
QE('PlayButton', recFilePtr != recFile.size);
QE('PauseButton', false);
QE('RestartButton', recFilePtr != 0);
if (waitTimer != null) {
clearTimeout(waitTimer);
waitTimer = null;
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
waitTimerArgs = null;
}
}
function restart() {
Q('RestartButton').blur();
if (playing == true) return;
recFilePtr = 0;
readState = 0;
currentDeltaTimeTotalSec = 0;
QV('metadatadiv', true);
QE('PlayButton', true);
QE('PauseButton', false);
QE('RestartButton', false);
QS('progressbar').width = '0px';
QH('timespan', '00:00:00');
QV('DeskParent', true);
QV('TermParent', false);
if (agentDesktop) {
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
} else if (amtDesktop) {
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
amtDesktop = CreateAmtRemoteDesktop('Desk');
amtDesktop.onScreenSizeChange = deskAdjust;
amtDesktop.State = 3;
amtDesktop.Start();
} else if (agentTerminal) {
agentTerminal = null;
}
}
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
// Toggle the web page to full screen
function toggleAspectRatio(toggle) {
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
deskAdjust();
}
function deskAdjust() {
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
var deskH = Q('Desk').height, deskW = Q('Desk').width;
if (deskAspectRatio == 2) {
// Scale mode
QS('Desk')['margin-top'] = null;
QS('Desk').height = '100%';
QS('Desk').width = '100%';
QS('DeskParent').overflow = 'hidden';
} else if (deskAspectRatio == 1) {
// Zoomed mode
QS('Desk')['margin-top'] = '0px';
//QS('Desk')['margin-left'] = '0px';
QS('Desk').height = deskH + 'px';
QS('Desk').width = deskW + 'px';
QS('DeskParent').overflow = 'scroll';
} else {
// Fixed aspect ratio
if ((parentH / parentW) > (deskH / deskW)) {
var hNew = ((deskH * parentW) / deskW) + 'px';
//if (webPageFullScreen || fullscreen) {
//QS('deskarea3x').height = null;
//} else {
// QS('deskarea3x').height = hNew;
//QS('deskarea3x').height = null;
//}
QS('Desk').height = hNew;
QS('Desk').width = '100%';
} else {
var wNew = ((deskW * parentH) / deskH) + 'px';
//if (webPageFullScreen || fullscreen) {
//QS('Desk').height = null;
//} else {
QS('Desk').height = '100%';
//}
QS('Desk').width = wNew;
}
QS('Desk')['margin-top'] = null;
QS('DeskParent').overflow = 'hidden';
}
}
//
// POPUP DIALOG
//
// null = Hidden, 1 = Generic Message
var xxdialogMode;
var xxdialogFunc;
var xxdialogButtons;
var xxdialogTag;
var xxcurrentView = -1;
// Display a dialog box
// Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
function setDialogMode(x, y, b, f, c, tag) {
xxdialogMode = x;
xxdialogFunc = f;
xxdialogButtons = b;
xxdialogTag = tag;
QE('idx_dlgOkButton', true);
QV('idx_dlgOkButton', b & 1);
QV('idx_dlgCancelButton', b & 2);
QV('id_dialogclose', (b & 2) || (b & 8));
QV('idx_dlgDeleteButton', b & 4);
QV('idx_dlgButtonBar', b & 7);
if (y) QH('id_dialogtitle', y);
for (var i = 1; i < 3; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
QV('dialog', x);
if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
}
function dialogclose(x) {
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
setDialogMode();
if (((b & 8) || x) && f) f(x, t);
}
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
start();
</script>
</body></html>

View File

@ -53,7 +53,7 @@ function start() {
var command = null;
if (process.argv.length > 2) { command = process.argv[2].toLowerCase(); }
if (['check', 'extract', 'extractall', 'translate', 'translateall', 'minifyall', 'merge'].indexOf(command) == -1) { command = null; }
if (['check', 'extract', 'extractall', 'translate', 'translateall', 'minifyall', 'merge', 'totext', 'fromtext'].indexOf(command) == -1) { command = null; }
console.log('MeshCentral web site translator');
if (command == null) {
@ -80,6 +80,12 @@ function start() {
console.log('');
console.log(' MERGE [sourcefile] [tartgetfile] [language code]');
console.log(' Merge a language from a translation file into another translation file.');
console.log('');
console.log(' TOTEXT [translationfile] [textfile] [language code]');
console.log(' Save a text for with all strings of a given language.');
console.log('');
console.log(' FROMTEXT [translationfile] [textfile] [language code]');
console.log(' Import raw text string as translations for a language code.');
process.exit();
return;
}
@ -108,6 +114,29 @@ function start() {
extract(process.argv[3], sources);
}
// Save a text file with all the strings for a given language
if (command == 'totext') {
if ((process.argv.length == 6)) {
if (fs.existsSync(process.argv[3]) == false) { console.log('Unable to find: ' + process.argv[3]); return; }
totext(process.argv[3], process.argv[4], process.argv[5]);
} else {
console.log('Usage: TOTEXT [translationfile] [textfile] [language code]');
}
return;
}
// Read a text file and use it as translation for a given language
if (command == 'fromtext') {
if ((process.argv.length == 6)) {
if (fs.existsSync(process.argv[3]) == false) { console.log('Unable to find: ' + process.argv[3]); return; }
if (fs.existsSync(process.argv[4]) == false) { console.log('Unable to find: ' + process.argv[4]); return; }
fromtext(process.argv[3], process.argv[4], process.argv[5]);
} else {
console.log('Usage: FROMTEXT [translationfile] [textfile] [language code]');
}
return;
}
// Merge one language from a language file into another language file.
if (command == 'merge') {
if ((process.argv.length == 6)) {
@ -195,6 +224,75 @@ function start() {
}
}
function totext(source, target, lang) {
// Load the source language file
var sourceLangFileData = null;
try { sourceLangFileData = JSON.parse(fs.readFileSync(source)); } catch (ex) { }
if ((sourceLangFileData == null) || (sourceLangFileData.strings == null)) { console.log("Invalid source language file."); process.exit(); return; }
console.log('Writing ' + lang + '...');
// Generate raw text
var output = [];
var splitOutput = [];
var count = 0;
for (var i in sourceLangFileData.strings) {
if ((sourceLangFileData.strings[i][lang] != null) && (sourceLangFileData.strings[i][lang].indexOf('\r') == -1) && (sourceLangFileData.strings[i][lang].indexOf('\n') == -1)) {
output.push(sourceLangFileData.strings[i][lang]);
if (splitOutput[Math.floor(count / 1000) + 1] == null) { splitOutput[Math.floor(count / 1000) + 1] = []; }
splitOutput[Math.floor(count / 1000) + 1].push(sourceLangFileData.strings[i][lang]);
} else {
output.push('');
if (splitOutput[Math.floor(count / 1000) + 1] == null) { splitOutput[Math.floor(count / 1000) + 1] = []; }
splitOutput[Math.floor(count / 1000) + 1].push('');
}
count++;
}
if (output.length <= 1000) {
// Save the target back
fs.writeFileSync(target + '-' + lang + '.txt', output.join('\r\n'), { flag: 'w+' });
console.log('Done.');
} else {
// Save the text in 1000 string bunches
for (var i in splitOutput) {
console.log('Writing ' + target + '-' + lang + '-' + i + '.txt...');
fs.writeFileSync(target + '-' + lang + '-' + i + '.txt', splitOutput[i].join('\r\n'), { flag: 'w+' });
}
console.log('Done.');
}
}
function fromtext(source, target, lang) {
// Load the source language file
var sourceLangFileData = null;
try { sourceLangFileData = JSON.parse(fs.readFileSync(source)); } catch (ex) { }
if ((sourceLangFileData == null) || (sourceLangFileData.strings == null)) { console.log("Invalid source language file."); process.exit(); return; }
console.log('Updating ' + lang + '...');
// Read raw text
var rawText = fs.readFileSync(target).toString('utf8');
var rawTextArray = rawText.split('\r\n');
var rawTextPtr = 0;
console.log('Translation file: ' + sourceLangFileData.strings.length + ' string(s)');
console.log('Text file: ' + rawTextArray.length + ' string(s)');
if (sourceLangFileData.strings.length != rawTextArray.length) { console.log('String count mismatch, unable to import.'); process.exit(1); return; }
var output = [];
var splitOutput = [];
for (var i in sourceLangFileData.strings) {
if ((sourceLangFileData.strings[i]['en'] != null) && (sourceLangFileData.strings[i]['en'].indexOf('\r') == -1) && (sourceLangFileData.strings[i]['en'].indexOf('\n') == -1)) {
sourceLangFileData.strings[i][lang] = rawTextArray[i];
}
}
fs.writeFileSync(source + '-new', JSON.stringify(sourceLangFileData), { flag: 'w+' });
console.log('Done.');
}
function merge(source, target, lang) {
// Load the source language file
var sourceLangFileData = null;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,294 @@
<!DOCTYPE html><html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<title>MeshCentral - Agent Installation</title>
<style>
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
}
.tab button:hover {
background-color: #ddd;
}
.tab button.active {
background-color: #8f8;
}
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
</style>
</head>
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
<div id="container">
<!-- Begin Masthead -->
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:20px; padding-top:8px">
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title}}}</font></strong>
</div>
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
</div>
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
</div>
<div id="page_leftbar">
<div style="height:16px"></div>
</div>
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
<div id="uiMenu" style="display:none">
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
</div>
</div>
</div>
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
<h1>リモートエージェントのインストール<span id="groupname"></span></h1>
<p>
You have been invited to install a software that will allow a remote operator to fully access your computer remotely including the desktop and files.
Only follow the instructions below if this invitation was expected and you know who will be accessing your computer.
Selecting your operation system and follow the instructions below.
</p>
<div>
<div class="tab">
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64ビット</button>
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32ビット</button>
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">マックOS</button>
</div>
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
<h3>Microsoft™Windows 64ビット</h3>
<p><a id="win64url">ここからソフトウェアをダウンロードしてください</a>、実行して「インストール」または「接続」を押します。</p>
<div style="text-align:center">
<img class="winagent-img" src="images/winagent.png">
</div>
</div>
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
<h3>Microsoft™Windows 32ビット</h3>
<p><a id="win32url">ここからソフトウェアをダウンロードしてください</a>、実行して「インストール」または「接続」を押します。</p>
<div style="text-align:center">
<img class="winagent-img" src="images/winagent.png">
</div>
</div>
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
<h3>Linux</h3>
<p>インストールするには、ルートターミナルで次のコマンドをカットアンドペーストします。</p>
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
<input type="button" value="クリップボードにコピー" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
<p>アンインストールするには、次のコマンドをルートとしてカットアンドペーストします。</p>
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
<input type="button" value="クリップボードにコピー" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
<br><br>
</div>
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
<h3>Apple™MacOS</h3>
<p><a id="macosurl">ここからインストーラーをダウンロードしてください</a>、それを右クリックするか、「control」を押してファイルをクリックします。次に、「開く」を選択し、指示に従います。</p>
<div style="text-align:center">
<img src="images/macosagent.png">
</div>
</div>
</div>
</div>
<div id="footer">
<table cellpadding="0" cellspacing="10" style="width: 100%">
<tbody><tr>
<td style="text-align:left"></td>
<td style="text-align:right"></td>
</tr>
</tbody></table>
</div>
</div>
<script>
'use strict';
var uiMode = parseInt(getstore('uiMode', 1));
var webPageStackMenu = false;
var webPageFullScreen = true;
var nightMode = (getstore('_nightMode', '0') == '1');
var domain = '{{{domain}}}';
var domainUrl = '{{{domainurl}}}';
var meshid = '{{{meshid}}}';
var serverPort = '{{{serverport}}}';
var serverHttps = '{{{serverhttps}}}';
var serverNoProxy = '{{{servernoproxy}}}';
var installFlags = '{{{installflags}}}';
var groupName = decodeURIComponent('{{{meshname}}}');
if (groupName != '') { QH('groupname', ' for ' + groupName); }
userInterfaceSelectMenu();
setup();
// Toggle user interface menu
function showUserInterfaceSelectMenu() {
Q('uiViewButton1').classList.remove('uiSelectorSel');
Q('uiViewButton2').classList.remove('uiSelectorSel');
Q('uiViewButton3').classList.remove('uiSelectorSel');
Q('uiViewButton4').classList.remove('uiSelectorSel');
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
QV('uiMenu', (QS('uiMenu').display == 'none'));
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
}
function userInterfaceSelectMenu(s) {
if (s) { uiMode = s; putstore('uiMode', uiMode); }
webPageFullScreen = (uiMode < 3);
webPageStackMenu = true;//(uiMode > 1);
toggleFullScreen(0);
toggleStackMenu(0);
QC('column_l').add('room4submenu');
}
function toggleNightMode() {
nightMode = !nightMode;
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
putstore('_nightMode', nightMode ? '1' : '0');
}
// Toggle the web page to full screen
function toggleFullScreen(toggle) {
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
var hide = 0;
//if (args.hide) { hide = parseInt(args.hide); }
if (webPageFullScreen == false) {
QC('body').remove('menu_stack');
QC('body').remove('fullscreen');
QC('body').remove('arg_hide');
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
//QV('UserDummyMenuSpan', false);
//QV('page_leftbar', false);
} else {
QC('body').add('fullscreen');
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
//QV('page_leftbar', true);
}
QV('body', true);
}
// If FullScreen, toggle menu to be horisontal or vertical
function toggleStackMenu(toggle) {
if (webPageFullScreen == true) {
if (toggle === 1) {
webPageStackMenu = !webPageStackMenu;
putstore('webPageStackMenu', webPageStackMenu);
}
if (webPageStackMenu == false) {
QC('body').remove('menu_stack');
} else {
QC('body').add('menu_stack');
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
}
}
}
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
function openTab(evt, tabname) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName('tabcontent');
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none';
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName('tablinks');
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(' active', '');
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(tabname).style.display = 'block';
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
}
var linuxInstall, linuxUnInstall;
function setup() {
var servername = window.location.hostname;
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
// Windows 64bit Setup
var url = 'meshagents?id=4&meshid=' + meshid;
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
Q('win64url').href = url;
// Windows 32bit Setup
url = 'meshagents?id=3&meshid=' + meshid;
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
Q('win32url').href = url;
// MacOS Setup
url = 'meshosxagent?id=16&meshid=' + meshid;
Q('macosurl').href = url;
// Linux Setup
if (serverHttps == 1) {
var portStr = (serverPort == 443) ? '' : ("" + serverPort);
if (serverNoProxy == 0) {
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
} else {
// Server asked that agent be installed to preferably not use a HTTP proxy.
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
}
} else {
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
if (serverNoProxy == 0) {
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
} else {
// Server asked that agent be installed to preferably not use a HTTP proxy.
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
}
}
QH('linuxinstall', linuxInstall);
QH('unlinuxinstall', linuxUnInstall);
// Attempt to detect the most likely operating system for this browser
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
else { openTab(null, 'wintab64'); }
}
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
</script>
</body></html>

View File

@ -447,13 +447,13 @@
QV('getStarted2', !newGroupsAllowed);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation en {0} minute {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -1284,7 +1284,7 @@
var r = message.event.results[i], shortname = r.hostname;
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
if (r.state == 2) { if (r.tls == 1) { str += "avec TLS."; } else { str += "sans TLS."; } } else { str += ' not activated.'; }
if (r.state == 2) { if (r.tls == 1) { str += " avec TLS."; } else { str += " sans TLS."; } } else { str += ' not activated.'; }
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
}
// If no results where found, display a nice message
@ -2154,7 +2154,7 @@
// Setup CIRA with user/pass authentication (Somewhat difficult)
x += '<div id=dlgAddCira1 style=display:none>' + format("To add a new Intel&reg; AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel AMT", EscapeHtml(mesh.name));
if (serverinfo.mpspass) { x += ("et authentifiez-vous sur le serveur en utilisant ce nom d'utilisateur et mot de passe." + '<br /><br />'); } else { x += ("et vous authentifier sur le serveur en utilisant ce nom d'utilisateur et n'importe quel mot de passe." + '<br /><br />'); }
if (serverinfo.mpspass) { x += (" et authentifiez-vous sur le serveur en utilisant ce nom d'utilisateur et mot de passe." + '<br /><br />'); } else { x += (" et vous authentifier sur le serveur en utilisant ce nom d'utilisateur et n'importe quel mot de passe." + '<br /><br />'); }
x += addHtmlValue("Certificat Racine", '<a href=\"' + "MeshServerRootCert.cer" + '\" download>' + "Fichier de Certificate Racine" + '</a>');
x += addHtmlValue("Nom d'utilisateur", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
if (serverinfo.mpspass) { x += addHtmlValue("Mot de passe", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
@ -6063,7 +6063,7 @@
function account_showChangePassword() {
if (xxdialogMode) return false;
var x = "Change your account password by entering the old password and new password twice in the boxes below.";
if (features & 0x00010000) { "Un indice de mot de passe peut être utilisé mais n'est pas recommandé."; }
if (features & 0x00010000) { " Un indice de mot de passe peut être utilisé mais n'est pas recommandé."; }
x += '<br /><br />';
//x += "<form action='" + domainUrl + "changepassword' method=post>";
x += '<table style=margin-left:60px>';
@ -6315,10 +6315,10 @@
if (currentMesh.amt.type == 1) { intelAmtPolicy = 'Deactivate Client Control Mode (CCM)'; }
else if (currentMesh.amt.type == 2) {
intelAmtPolicy = "Simple Client Control Mode (CCM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
} else if (currentMesh.amt.type == 3) {
intelAmtPolicy = "Simple Admin Control Mode (ACM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
}
}
x += addHtmlValue("Intel&reg; AMT", addLinkConditional(intelAmtPolicy, 'p20editMeshAmt()', meshrights & 1));
@ -6549,7 +6549,7 @@
var x = '';
if (userid == null) {
x += "Autoriser les utilisateurs à gérer ce groupe et les périphériques de ce groupe.";
if (features & 0x00080000) { x += "Les utilisateurs doivent se connecter une fois sur ce serveur avant de pouvoir être ajoutés à un groupe de périphériques.." }
if (features & 0x00080000) { x += " Les utilisateurs doivent se connecter une fois sur ce serveur avant de pouvoir être ajoutés à un groupe de périphériques.." }
x += '<br /><br /><div style=\'position:relative\'>';
x += addHtmlValue("Noms", '<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() placeholder="user1, user2, user3" />');
x += '<div id=dp20usersuggest class=suggestionBox style=\'top:30px;left:130px;display:none\'></div>';

File diff suppressed because one or more lines are too long

View File

@ -447,13 +447,13 @@
QV('getStarted2', !newGroupsAllowed);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} minuto {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -1284,7 +1284,7 @@
var r = message.event.results[i], shortname = r.hostname;
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
if (r.state == 2) { if (r.tls == 1) { str += "com TLS."; } else { str += "sem TLS."; } } else { str += ' not activated.'; }
if (r.state == 2) { if (r.tls == 1) { str += " com TLS."; } else { str += " sem TLS."; } } else { str += ' not activated.'; }
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
}
// If no results where found, display a nice message
@ -2154,7 +2154,7 @@
// Setup CIRA with user/pass authentication (Somewhat difficult)
x += '<div id=dlgAddCira1 style=display:none>' + format("Para adicionar um novo Intel&reg; Dispositivo AMT para grupo de dispositivos \"{0}\" com CIRA, carregue o seguinte certificado como raiz confiável no Intel AMT", EscapeHtml(mesh.name));
if (serverinfo.mpspass) { x += ("e autenticar no servidor usando esse nome de usuário e senha." + '<br /><br />'); } else { x += ("e autenticar no servidor usando esse nome de usuário e qualquer senha." + '<br /><br />'); }
if (serverinfo.mpspass) { x += (" e autenticar no servidor usando esse nome de usuário e senha." + '<br /><br />'); } else { x += (" e autenticar no servidor usando esse nome de usuário e qualquer senha." + '<br /><br />'); }
x += addHtmlValue("Certificado raiz", '<a href=\"' + "MeshServerRootCert.cer" + '\" download>' + "Arquivo de certificado raiz" + '</a>');
x += addHtmlValue("Nome de usuário", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
if (serverinfo.mpspass) { x += addHtmlValue("Senha", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
@ -6063,7 +6063,7 @@
function account_showChangePassword() {
if (xxdialogMode) return false;
var x = "Altere a senha da sua conta digitando a senha antiga e a nova senha duas vezes nas caixas abaixo.";
if (features & 0x00010000) { "Dica de senha pode ser usada, mas não é recomendada."; }
if (features & 0x00010000) { " Dica de senha pode ser usada, mas não é recomendada."; }
x += '<br /><br />';
//x += "<form action='" + domainUrl + "changepassword' method=post>";
x += '<table style=margin-left:60px>';
@ -6315,10 +6315,10 @@
if (currentMesh.amt.type == 1) { intelAmtPolicy = 'Deactivate Client Control Mode (CCM)'; }
else if (currentMesh.amt.type == 2) {
intelAmtPolicy = "Modo de Controle de Cliente Simples (CCM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
} else if (currentMesh.amt.type == 3) {
intelAmtPolicy = "Modo de controle de administrador simples (ACM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
}
}
x += addHtmlValue("Intel&reg; AMT", addLinkConditional(intelAmtPolicy, 'p20editMeshAmt()', meshrights & 1));
@ -6549,7 +6549,7 @@
var x = '';
if (userid == null) {
x += "Permitir que os usuários gerenciem esse grupo de dispositivos e dispositivos neste grupo.";
if (features & 0x00080000) { x += "Os usuários precisam fazer login neste servidor uma vez antes de poderem ser adicionados a um grupo de dispositivos." }
if (features & 0x00080000) { x += " Os usuários precisam fazer login neste servidor uma vez antes de poderem ser adicionados a um grupo de dispositivos." }
x += '<br /><br /><div style=\'position:relative\'>';
x += addHtmlValue("Nomes de usuário", '<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() placeholder="user1, user2, user3" />');
x += '<div id=dp20usersuggest class=suggestionBox style=\'top:30px;left:130px;display:none\'></div>';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -692,13 +692,13 @@
QV('p3createMeshLink2', false);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation en {0} minute {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -1788,7 +1788,7 @@
function deviceHeaderSet() {
if (deviceHeaderId == 0) { deviceHeaderId = 1; return; }
deviceHeaders['DevxHeader' + deviceHeaderId] = ', ' + deviceHeaderTotal + ((deviceHeaderTotal == 1) ? "nœud" : "noeuds");
deviceHeaders['DevxHeader' + deviceHeaderId] = ', ' + deviceHeaderTotal + ((deviceHeaderTotal == 1) ? " nœud" : " noeuds");
var title = '';
for (var x in deviceHeaderCount) { if (title.length > 0) title += ', '; title += deviceHeaderCount[x] + ' ' + PowerStateStr2(x); }
deviceHeadersTitles['DevxHeader' + deviceHeaderId] = title;
@ -3108,7 +3108,7 @@
x += '<br style=clear:both><br>';
var currentMeshLinks = currentMesh.links[userinfo._id];
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<div style=margin-bottom:6px><a onclick=p20showAddMeshUserDialog() style=cursor:pointer><img src=images/icon-addnew.png border=0 height=12 width=12>' + "Ajouter un utilisateur" + '</a></div>'; }
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<div style=margin-bottom:6px><a onclick=p20showAddMeshUserDialog() style=cursor:pointer><img src=images/icon-addnew.png border=0 height=12 width=12>' + " Ajouter un utilisateur" + '</a></div>'; }
/*
if ((meshrights & 4) != 0) {

File diff suppressed because it is too large Load Diff

View File

@ -692,13 +692,13 @@
QV('p3createMeshLink2', false);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} minuto {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -1788,7 +1788,7 @@
function deviceHeaderSet() {
if (deviceHeaderId == 0) { deviceHeaderId = 1; return; }
deviceHeaders['DevxHeader' + deviceHeaderId] = ', ' + deviceHeaderTotal + ((deviceHeaderTotal == 1) ? "nó" : "nós");
deviceHeaders['DevxHeader' + deviceHeaderId] = ', ' + deviceHeaderTotal + ((deviceHeaderTotal == 1) ? " nó" : " nós");
var title = '';
for (var x in deviceHeaderCount) { if (title.length > 0) title += ', '; title += deviceHeaderCount[x] + ' ' + PowerStateStr2(x); }
deviceHeadersTitles['DevxHeader' + deviceHeaderId] = title;
@ -3108,7 +3108,7 @@
x += '<br style=clear:both><br>';
var currentMeshLinks = currentMesh.links[userinfo._id];
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<div style=margin-bottom:6px><a onclick=p20showAddMeshUserDialog() style=cursor:pointer><img src=images/icon-addnew.png border=0 height=12 width=12>' + "Adicionar usuário" + '</a></div>'; }
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<div style=margin-bottom:6px><a onclick=p20showAddMeshUserDialog() style=cursor:pointer><img src=images/icon-addnew.png border=0 height=12 width=12>' + " Adicionar usuário" + '</a></div>'; }
/*
if ((meshrights & 4) != 0) {

View File

@ -1456,13 +1456,13 @@
QV('getStarted2', !newGroupsAllowed);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Réinitialiser à la prochaine connexion."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Réinitialiser à la prochaine connexion."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation en {0} minute {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Réinitialisation dans {0} heure {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Réinitialiser dans le {0} jour {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -2293,7 +2293,7 @@
var r = message.event.results[i], shortname = r.hostname;
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
if (r.state == 2) { if (r.tls == 1) { str += "avec TLS."; } else { str += "sans TLS."; } } else { str += ' not activated.'; }
if (r.state == 2) { if (r.tls == 1) { str += " avec TLS."; } else { str += " sans TLS."; } } else { str += ' not activated.'; }
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
}
// If no results where found, display a nice message
@ -3163,7 +3163,7 @@
// Setup CIRA with user/pass authentication (Somewhat difficult)
x += '<div id=dlgAddCira1 style=display:none>' + format("To add a new Intel&reg; AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel AMT", EscapeHtml(mesh.name));
if (serverinfo.mpspass) { x += ("et authentifiez-vous sur le serveur en utilisant ce nom d'utilisateur et mot de passe." + '<br /><br />'); } else { x += ("et vous authentifier sur le serveur en utilisant ce nom d'utilisateur et n'importe quel mot de passe." + '<br /><br />'); }
if (serverinfo.mpspass) { x += (" et authentifiez-vous sur le serveur en utilisant ce nom d'utilisateur et mot de passe." + '<br /><br />'); } else { x += (" et vous authentifier sur le serveur en utilisant ce nom d'utilisateur et n'importe quel mot de passe." + '<br /><br />'); }
x += addHtmlValue("Certificat Racine", '<a href=\"' + "MeshServerRootCert.cer" + '\" download>' + "Fichier de Certificate Racine" + '</a>');
x += addHtmlValue("Nom d'utilisateur", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
if (serverinfo.mpspass) { x += addHtmlValue("Mot de passe", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
@ -7072,7 +7072,7 @@
function account_showChangePassword() {
if (xxdialogMode) return false;
var x = "Change your account password by entering the old password and new password twice in the boxes below.";
if (features & 0x00010000) { "Un indice de mot de passe peut être utilisé mais n'est pas recommandé."; }
if (features & 0x00010000) { " Un indice de mot de passe peut être utilisé mais n'est pas recommandé."; }
x += '<br /><br />';
//x += "<form action='" + domainUrl + "changepassword' method=post>";
x += '<table style=margin-left:60px>';
@ -7324,10 +7324,10 @@
if (currentMesh.amt.type == 1) { intelAmtPolicy = 'Deactivate Client Control Mode (CCM)'; }
else if (currentMesh.amt.type == 2) {
intelAmtPolicy = "Simple Client Control Mode (CCM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
} else if (currentMesh.amt.type == 3) {
intelAmtPolicy = "Simple Admin Control Mode (ACM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
}
}
x += addHtmlValue("Intel&reg; AMT", addLinkConditional(intelAmtPolicy, 'p20editMeshAmt()', meshrights & 1));
@ -7558,7 +7558,7 @@
var x = '';
if (userid == null) {
x += "Autoriser les utilisateurs à gérer ce groupe et les périphériques de ce groupe.";
if (features & 0x00080000) { x += "Les utilisateurs doivent se connecter une fois sur ce serveur avant de pouvoir être ajoutés à un groupe de périphériques.." }
if (features & 0x00080000) { x += " Les utilisateurs doivent se connecter une fois sur ce serveur avant de pouvoir être ajoutés à un groupe de périphériques.." }
x += '<br /><br /><div style=\'position:relative\'>';
x += addHtmlValue("Noms", '<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() placeholder="user1, user2, user3" />');
x += '<div id=dp20usersuggest class=suggestionBox style=\'top:30px;left:130px;display:none\'></div>';

File diff suppressed because one or more lines are too long

View File

@ -1456,13 +1456,13 @@
QV('getStarted2', !newGroupsAllowed);
if (typeof userinfo.passchange == 'number') {
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
if (seconds < 0) { QH('p2nextPasswordUpdateTime', "- Redefinir no próximo login."); }
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Redefinir no próximo login."); }
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} minuto {1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format("- Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} hora {1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
else { QH('p2nextPasswordUpdateTime', format(" - Redefinir em {0} dia {1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
}
}
}
@ -2293,7 +2293,7 @@
var r = message.event.results[i], shortname = r.hostname;
if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
if (r.state == 2) { if (r.tls == 1) { str += "com TLS."; } else { str += "sem TLS."; } } else { str += ' not activated.'; }
if (r.state == 2) { if (r.tls == 1) { str += " com TLS."; } else { str += " sem TLS."; } } else { str += ' not activated.'; }
x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
}
// If no results where found, display a nice message
@ -3163,7 +3163,7 @@
// Setup CIRA with user/pass authentication (Somewhat difficult)
x += '<div id=dlgAddCira1 style=display:none>' + format("Para adicionar um novo Intel&reg; Dispositivo AMT para grupo de dispositivos \"{0}\" com CIRA, carregue o seguinte certificado como raiz confiável no Intel AMT", EscapeHtml(mesh.name));
if (serverinfo.mpspass) { x += ("e autenticar no servidor usando esse nome de usuário e senha." + '<br /><br />'); } else { x += ("e autenticar no servidor usando esse nome de usuário e qualquer senha." + '<br /><br />'); }
if (serverinfo.mpspass) { x += (" e autenticar no servidor usando esse nome de usuário e senha." + '<br /><br />'); } else { x += (" e autenticar no servidor usando esse nome de usuário e qualquer senha." + '<br /><br />'); }
x += addHtmlValue("Certificado raiz", '<a href=\"' + "MeshServerRootCert.cer" + '\" download>' + "Arquivo de certificado raiz" + '</a>');
x += addHtmlValue("Nome de usuário", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
if (serverinfo.mpspass) { x += addHtmlValue("Senha", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
@ -7072,7 +7072,7 @@
function account_showChangePassword() {
if (xxdialogMode) return false;
var x = "Altere a senha da sua conta digitando a senha antiga e a nova senha duas vezes nas caixas abaixo.";
if (features & 0x00010000) { "Dica de senha pode ser usada, mas não é recomendada."; }
if (features & 0x00010000) { " Dica de senha pode ser usada, mas não é recomendada."; }
x += '<br /><br />';
//x += "<form action='" + domainUrl + "changepassword' method=post>";
x += '<table style=margin-left:60px>';
@ -7324,10 +7324,10 @@
if (currentMesh.amt.type == 1) { intelAmtPolicy = 'Deactivate Client Control Mode (CCM)'; }
else if (currentMesh.amt.type == 2) {
intelAmtPolicy = "Modo de Controle de Cliente Simples (CCM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
} else if (currentMesh.amt.type == 3) {
intelAmtPolicy = "Modo de controle de administrador simples (ACM)";
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += "+ CIRA"; }
if (currentMesh.amt.cirasetup == 2) { intelAmtPolicy += " + CIRA"; }
}
}
x += addHtmlValue("Intel&reg; AMT", addLinkConditional(intelAmtPolicy, 'p20editMeshAmt()', meshrights & 1));
@ -7558,7 +7558,7 @@
var x = '';
if (userid == null) {
x += "Permitir que os usuários gerenciem esse grupo de dispositivos e dispositivos neste grupo.";
if (features & 0x00080000) { x += "Os usuários precisam fazer login neste servidor uma vez antes de poderem ser adicionados a um grupo de dispositivos." }
if (features & 0x00080000) { x += " Os usuários precisam fazer login neste servidor uma vez antes de poderem ser adicionados a um grupo de dispositivos." }
x += '<br /><br /><div style=\'position:relative\'>';
x += addHtmlValue("Nomes de usuário", '<input id=dp20username style=width:230px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() placeholder="user1, user2, user3" />');
x += '<div id=dp20usersuggest class=suggestionBox style=\'top:30px;left:130px;display:none\'></div>';

View File

@ -0,0 +1 @@
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><meta http-equiv=X-UA-Compatible content="IE=edge"><meta content="text/html;charset=utf-8"http-equiv=Content-Type><meta name=viewport content="user-scalable=1,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>MeshCentral - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>ダウンロード</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} &nbsp;<a href=terms>利用規約とプライバシー</a></table></div></div></div>

View File

@ -0,0 +1,41 @@
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
<title>MeshCentral - Download</title>
</head>
<body>
<div id="container" style="max-height:100vh">
<div id="mastheadx"></div>
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px">
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div>
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_content" style="max-height:calc(100vh-138px)">
<div id="column_l">
<h1>ダウンロード</h1>
<p style="margin-left:20px">{{{message}}}</p>
<br>
</div>
<div id="footer">
<table cellpadding="0" cellspacing="10" style="width:100%">
<tbody><tr>
<td style="text-align:left"></td>
<td style="text-align:right">
{{{rootCertLink}}}
&nbsp;<a href="terms">利用規約とプライバシー</a>
</td>
</tr>
</tbody></table>
</div>
</div>
</div>
</body></html>

View File

@ -0,0 +1 @@
<!doctypehtml><meta http-equiv=X-UA-Compatible content="IE=edge"><meta content="text/html; charset=utf-8"http-equiv=Content-Type><meta name=viewport content="user-scalable=1,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>MeshCentral</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title=ユーザーインターフェイスの選択 onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title=左バーインターフェイス><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title=トップバーインターフェース><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title=固定幅インターフェイス><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title=ナイトモードを切り替える><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>このページは存在しません</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>メインサイトに行く</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >バック</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>

View File

@ -0,0 +1 @@
<!doctypehtml><meta http-equiv=X-UA-Compatible content="IE=edge"><meta content="text/html; charset=utf-8"http-equiv=Content-Type><meta name=viewport content="user-scalable=1,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>MeshCentral</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><strong><font style=font-size:36px;font-family:Arial,Helvetica,sans-serif>{{{title}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>このページは存在しません</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>メインサイトに行く</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}}&nbsp;<a href=/ >バック</a></table></div></div>

View File

@ -0,0 +1,54 @@
<!DOCTYPE html><html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<title>MeshCentral</title>
<style type="text/css">
a {
color: #036;
text-decoration: underline;
}
#footer a {
color: #fff;
text-decoration: underline;
}
#footer a:hover {
color: #fff;
text-decoration: none;
}
</style>
</head>
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
<div id="container">
<!-- Begin Masthead -->
<div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div>
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:7px">
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
<div id="column_l" style="padding-left:10px;padding-right:10px">
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">このページは存在しません</div>
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>メインサイトに行く</b></a></div>
</div>
</div>
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
<table cellpadding="0" cellspacing="6" style="width:100%">
<tbody><tr>
<td style="text-align:left;color:white">{{{footer}}}</td>
<td style="text-align:right">{{{rootCertLink}}}&nbsp;<a href="/">バック</a></td>
</tr>
</tbody></table>
</div>
</div>
</body></html>

View File

@ -0,0 +1,131 @@
<!DOCTYPE html><html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<title>MeshCentral</title>
</head>
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
<div id="container">
<!-- Begin Masthead -->
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:20px; padding-top:8px">
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title}}}</font></strong>
</div>
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_leftbar">
<div style="height:16px"></div>
</div>
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
<div id="uiMenu" style="display:none">
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
</div>
</div>
</div>
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">このページは存在しません</div>
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>メインサイトに行く</b></a></div>
</div>
<div id="footer">
<table cellpadding="0" cellspacing="10" style="width: 100%">
<tbody><tr>
<td style="text-align:left"></td>
<td style="text-align:right"><a href="/">バック</a></td>
</tr>
</tbody></table>
</div>
</div>
<script>
'use strict';
var uiMode = parseInt(getstore('uiMode', 1));
var webPageStackMenu = false;
var webPageFullScreen = true;
var nightMode = (getstore('_nightMode', '0') == '1');
var terms = '{{{terms}}}';
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
QV('column_l', true);
userInterfaceSelectMenu();
// Toggle user interface menu
function showUserInterfaceSelectMenu() {
Q('uiViewButton1').classList.remove('uiSelectorSel');
Q('uiViewButton2').classList.remove('uiSelectorSel');
Q('uiViewButton3').classList.remove('uiSelectorSel');
Q('uiViewButton4').classList.remove('uiSelectorSel');
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
QV('uiMenu', (QS('uiMenu').display == 'none'));
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
}
function userInterfaceSelectMenu(s) {
if (s) { uiMode = s; putstore('uiMode', uiMode); }
webPageFullScreen = (uiMode < 3);
webPageStackMenu = true;//(uiMode > 1);
toggleFullScreen(0);
toggleStackMenu(0);
QC('column_l').add('room4submenu');
}
function toggleNightMode() {
nightMode = !nightMode;
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
putstore('_nightMode', nightMode ? '1' : '0');
}
// Toggle the web page to full screen
function toggleFullScreen(toggle) {
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
var hide = 0;
//if (args.hide) { hide = parseInt(args.hide); }
if (webPageFullScreen == false) {
QC('body').remove('menu_stack');
QC('body').remove('fullscreen');
QC('body').remove('arg_hide');
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
//QV('UserDummyMenuSpan', false);
//QV('page_leftbar', false);
} else {
QC('body').add('fullscreen');
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
//QV('page_leftbar', true);
}
QV('body', true);
}
// If FullScreen, toggle menu to be horisontal or vertical
function toggleStackMenu(toggle) {
if (webPageFullScreen == true) {
if (toggle === 1) {
webPageStackMenu = !webPageStackMenu;
putstore('webPageStackMenu', webPageStackMenu);
}
if (webPageStackMenu == false) {
QC('body').remove('menu_stack');
} else {
QC('body').add('menu_stack');
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
}
}
}
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
</script>
</body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,647 @@
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="shortcut icon" type="image/x-icon" href="{{{domainurl}}}favicon.ico">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<script type="text/javascript" src="scripts/u2f-api.js"></script>
<title>MeshCentral - Login</title>
<style>
a {
color: #036;
text-decoration: underline;
}
#footer a {
color: #fff;
text-decoration: underline;
}
#footer a:hover {
color: #fff;
text-decoration: none;
}
</style>
</head>
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
<div id="container">
<div id="mastheadx"></div>
<div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px">
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div>
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:10px">
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
<div id="column_l" style="padding:10px;width:100%">
<table style="width:100%">
<tbody><tr>
<td align="center">
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
<form method="post">
<input type="hidden" name="action" value="login">
<div id="message1"></div>
<div>
<b>ログイン</b>
</div>
<table>
<tbody><tr>
<td id="loginusername" align="right" width="100">ユーザー名:</td>
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
</tr>
<tr>
<td align="right">パスワード:</td>
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
</tr>
<tr>
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">ヒントを見せて</a></div></td>
<td align="right"><input id="loginButton" type="submit" value="ログイン" disabled="disabled"></td>
</tr>
</tbody></table>
<div id="hrAccountDiv" style="display:none"><hr></div>
<div id="resetAccountDiv" style="display:none;padding:2px">
<span id="resetAccountSpan">ユーザー/パスワードを忘れましたか?</span> <a onclick="xgo(3)" style="cursor:pointer">アカウントをリセット</a>。
</div>
<div id="newAccountDiv" style="display:none;padding:2px">
アカウントを持っていないのですか? <a onclick="xgo(2)" style="cursor:pointer">一つ作る</a>。
</div>
<input id="loginformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="createpanel" style="display:none">
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
<form method="post">
<input type="hidden" name="action" value="createaccount">
<div id="message2"></div>
<div>
<b>アカウント作成</b>
</div>
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
<table>
<tbody><tr id="nuUserRow">
<td align="right" width="100">ユーザー名:</td>
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
</tr>
<tr>
<td align="right" width="100">Eメール</td>
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
</tr>
<tr>
<td align="right">パスワード:</td>
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
</tr>
<tr>
<td align="right">パスワード:</td>
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
</tr>
<tr id="createPanelHint" style="display:none">
<td align="right">ヒントを渡す:</td>
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
</tr>
<tr id="newAccountPass" title="アカウント作成トークンを入力してください">
<td align="right">作成トークン:</td>
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="createButton" type="submit" value="アカウントを作成する" disabled="disabled"></div>
<div id="passWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
<input id="createformargs" name="urlargs" type="hidden" value="">
</form>
</div>
</div>
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
<form method="post">
<input type="hidden" name="action" value="resetaccount">
<div id="message3"></div>
<div>
<b>アカウントのリセット</b>
</div>
<table>
<tbody><tr>
<td align="right" width="100">Eメール</td>
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="eresetButton" type="submit" value="アカウントをリセット" disabled="disabled"></div>
<div id="passWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
<input id="resetformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
<form method="post" autocomplete="off">
<input type="hidden" name="action" value="tokenlogin">
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
<div id="message4"></div>
<table>
<tbody><tr>
<td align="right" width="100">ログイントークン:</td>
<td>
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
</td>
</tr>
<tr>
<td colspan="2" style="align-content:center">
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">このデバイスを30日間記憶します。</label>
</td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="tokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="セキュリティキーを使用" onclick="useSecurityKey()"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
<input id="tokenformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
<form method="post" autocomplete="off">
<input type="hidden" name="action" value="resetaccount">
<div id="message5"></div>
<table>
<tbody><tr>
<td align="right" width="100">ログイントークン:</td>
<td>
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
</td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
<form method="post">
<input type="hidden" name="action" value="resetpassword">
<div id="message6"></div>
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
<table>
<tbody><tr>
<td id="rnuPass1" width="100" align="right">パスワード:</td>
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
</tr>
<tr>
<td id="rnuPass2" align="right">パスワード:</td>
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
</tr>
<tr id="resetpasswordpanelHint" style="display:none">
<td id="rnuHint" align="right">パスワードのヒント:</td>
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="resetPassButton" type="submit" value="パスワードを再設定する" disabled="disabled"></div>
<div id="rpassWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
</form>
</div>
</td>
</tr>
</tbody></table>
</div>
</div>
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
<table cellpadding="0" cellspacing="6" style="width:100%">
<tbody><tr>
<td style="text-align:left;color:white">{{{footer}}}</td>
<td style="text-align:right">{{{rootCertLink}}}&nbsp;<a href="terms">利用規約とプライバシー</a></td>
</tr>
</tbody></table>
</div>
</div>
<div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:180px;width:400px;display:none">
<div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0">
<div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>バツ</b></div>
<div id="id_dialogtitle" style="padding:5px"></div>
<div style="width:100%;margin:6px"></div>
</div>
<div style="margin-right:16px;margin-left:8px">
<div id="dialog1" style="margin:auto;text-align:center;margin:3px">
<div id="id_dialogMessage" style="padding:10px"></div>
</div>
<div id="dialog2" style="margin:auto;margin:3px">
<div id="id_dialogOptions"></div>
</div>
</div>
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
<input id="idx_dlgCancelButton" type="button" value="キャンセル" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">
<input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)">
</div>
</div>
<script>
'use strict';
var loginMode = '{{{loginmode}}}';
var newAccount = '{{{newAccount}}}';
var passhint = '{{{passhint}}}';
var newAccountPass = parseInt('{{{newAccountPass}}}');
var emailCheck = ('{{{emailcheck}}}' == 'true');
var features = parseInt('{{{features}}}');
var passRequirements = '{{{passRequirements}}}';
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
var publicKeyCredentialRequestOptions = null;
var currentpanel = 0;
// Display the right server message
var messageid = parseInt('{{{messageid}}}');
var okmessages = ['', "お待ちください、送信されたメールをリセットします。"];
var failmessages = ["アカウントを作成できません。", "アカウントの上限に達しました。", "このメールアドレスを持つ既存のアカウント。", "アカウント作成トークンが無効です。", "ユーザー名は既に存在します。", "パスワードが拒否されました。別のパスワードを使用してください。", "無効なメール。", "アカウントが見つかりませんでした。", "トークンが無効です。もう一度お試しください。", "メールを送信できません。", "アカウントがロックされました。", "アクセスが拒否されました。", "ログインに失敗しました。ユーザー名とパスワードを確認してください。", "パスワードの変更が要求されました。", "IPアドレスがブロックされています。しばらくしてからもう一度お試しください。"];
if (messageid > 0) {
var msg = '';
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
if (msg != '') {
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
}
}
// If URL arguments are provided, add them to form posts
if (window.location.href.indexOf('?') > 0) {
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
Q('loginformargs').value = urlargs;
Q('createformargs').value = urlargs;
Q('resetformargs').value = urlargs;
Q('tokenformargs').value = urlargs;
Q('resettokenformargs').value = urlargs;
Q('resetpasswordformargs').value = urlargs;
}
function startup() {
if ((features & 32) == 0) {
// Guard against other site's top frames (web bugs).
var loc = null;
try { loc = top.location.toString().toLowerCase(); } catch (e) { }
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
}
if (features & 0x200000) { // Email is username
QH('loginusername', "Eメール");
QH('resetAccountSpan', "パスワードをお忘れですか?");
QV('nuUserRow', false);
}
QV('createPanelHint', passRequirements.hint === true);
QV('resetpasswordpanelHint', passRequirements.hint === true);
window.onresize = center;
center();
validateLogin();
validateCreate();
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
QV('newAccountPass', (newAccountPass == 1));
QV('resetAccountDiv', (emailCheck == true));
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
if (loginMode == '4') {
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
}
if (loginMode == '5') {
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
publicKeyCredentialRequestOptions.allowCredentials.push(
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
);
}
// New WebAuthn hardware keys
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
function (rawAssertion) {
var assertion = {
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
};
Q('resetHwtokenInput').value = JSON.stringify(assertion);
QE('resetTokenOkButton', true);
Q('resetTokenOkButton').click();
},
function (error) { console.log('credentials-get error', error); }
);
}
}
}
// Use a hardware security key
function useSecurityKey() {
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
publicKeyCredentialRequestOptions.allowCredentials.push(
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
);
}
// New WebAuthn hardware keys
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
function (rawAssertion) {
var assertion = {
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
};
Q('hwtokenInput').value = JSON.stringify(assertion);
QE('tokenOkButton', true);
Q('tokenOkButton').click();
},
function (error) { console.log('credentials-get error', error); }
);
}
}
function showPassHint() {
if (passRequirements.hint === true) { messagebox("パスワードのヒント", passhint); }
}
function xgo(x) {
QV('message1', false);
QV('message2', false);
QV('message3', false);
QV('message4', false);
QV('message5', false);
QV('message6', false);
go(x);
}
function go(x) {
currentpanel = x;
setDialogMode(0);
QV('showPassHintLink', false);
QV('loginpanel', x == 1);
QV('createpanel', x == 2);
QV('resetpanel', x == 3);
QV('tokenpanel', x == 4);
QV('resettokenpanel', x == 5);
QV('resetpasswordpanel', x == 6);
if (x == 1) { Q('username').focus(); }
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
if (x == 3) { Q('remail').focus(); }
if (x == 4) { Q('tokenInput').focus(); }
if (x == 5) { Q('resetTokenInput').focus(); }
if (x == 6) { Q('rapassword1').focus(); }
}
function validateLogin(box, e) {
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
QE('loginButton', ok);
setDialogMode(0);
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
if (e != null) { haltEvent(e); }
}
function validateCreate(box,e) {
setDialogMode(0);
var ok = false;
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
if (Q('apassword1').value == '') {
QH('passWarning', '');
QV('passwordPolicyCallout', false);
} else {
if (!passRequirementsEx) {
// No password requirements, display password strength
var passStrength = checkPasswordStrength(Q('apassword1').value);
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
else { QH('passWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
} else {
// Password requirements provided, use that
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
if (passReq == false) {
ok = false;
//QS('nuPass1').color = '#7b241c';
//QS('nuPass2').color = '#7b241c';
QH('passWarning', '<span style=color:red><b>' + "パスワードポリシー" + '</b><span>'); // TODO: Display problem hint
QV('passwordPolicyCallout', true);
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
} else {
QH('passWarning', '');
QV('passwordPolicyCallout', false);
}
}
}
QE('createButton', ok);
if ((e != null) && (e.keyCode == 13)) {
if (box == 1) { Q('aemail').focus(); }
if (box == 2) { Q('apassword1').focus(); }
if (box == 3) { Q('apassword2').focus(); }
if (box == 4) { Q('apasswordhint').focus(); }
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
if (box == 6) { Q('createButton').click(); }
}
if (e != null) { haltEvent(e); }
}
function validatePassReset(box, e) {
setDialogMode(0);
var pass1ok = (Q('rapassword1').value.length > 0);
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
var ok = (pass1ok && pass2ok);
// Color the fields
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
if (Q('rapassword1').value == '') {
QH('rpassWarning', '');
QV('rpasswordPolicyCallout', false);
} else {
if (!passRequirementsEx) {
// No password requirements, display password strength
var passStrength = checkPasswordStrength(Q('rapassword1').value);
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
else { QH('rpassWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
} else {
// Password requirements provided, use that
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
if (passReq == false) {
ok = false;
QS('rnuPass1').color = '#7b241c';
QS('rnuPass2').color = '#7b241c';
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
QV('rpasswordPolicyCallout', true);
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
} else {
QH('rpassWarning', '');
QV('rpasswordPolicyCallout', false);
}
}
}
if ((e != null) && (e.keyCode == 13)) {
if (box == 2) { Q('rapassword1').focus(); }
if (box == 3) { Q('rapassword2').focus(); }
if (box == 4) { Q('rapasswordhint').focus(); }
if (box == 6) { Q('resetPassButton').click(); }
}
if (e != null) { haltEvent(e); }
QE('resetPassButton', ok);
}
function validateReset(e) {
setDialogMode(0);
var x = validateEmail(Q('remail').value);
QE('eresetButton', x);
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
if (e != null) { haltEvent(e); }
}
function passwordPolicyText(pass) {
var policy = '<div style=text-align:left>';
var counts = strCount(pass);
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("最小長{0}", passRequirements.min) + '<br />'; }
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("{0}の最大長", passRequirements.max) + '<br />'; }
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0}大文字", passRequirements.upper) + '<br />'; }
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0}小文字", passRequirements.lower) + '<br />'; }
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0}数値", passRequirements.numeric) + '<br />'; }
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0}英数字以外", passRequirements.nonalpha) + '<br />'; }
policy += '</div>';
return policy;
}
// Return a password strength score
function checkPasswordStrength(password) {
var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
if (!password) return 0;
for (var i = 0; i< password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
return parseInt(r + (varCount - 1) * 10);
}
// Check password requirements
function checkPasswordRequirements(password, requirements) {
if ((requirements == null) || (requirements == '') || (typeof requirements != 'object')) return true;
if (requirements.min) { if (password.length < requirements.min) return false; }
if (requirements.max) { if (password.length > requirements.max) return false; }
var counts = strCount(password);
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
if (requirements.lower && (counts.lower < requirements.lower)) return false;
if (requirements.upper && (counts.upper < requirements.upper)) return false;
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
return true;
}
function strCount(password) {
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
if (typeof password != 'string') return counts;
for (var i = 0; i < password.length; i++) {
if (/\d/.test(password[i])) { counts.numeric++; }
if (/[a-z]/.test(password[i])) { counts.lower++; }
if (/[A-Z]/.test(password[i])) { counts.upper++; }
if (/\W/.test(password[i])) { counts.nonalpha++; }
}
return counts;
}
var xcheckTokenTimer = null;
function checkTokenTimer(enter) {
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
}
function checkToken() {
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
if (t1 != t2) { Q('tokenInput').value = t2; }
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
}
function resetCheckToken() {
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
if (t1 != t2) { Q('resetTokenInput').value = t2; }
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
}
//
// POPUP DIALOG
//
// undefined = Hidden, 1 = Generic Message
var xxdialogMode;
var xxdialogFunc;
var xxdialogButtons;
var xxdialogTag;
var xxcurrentView = 0;
// Display a dialog box
// Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
function setDialogMode(x, y, b, f, c, tag) {
xxdialogMode = x;
xxdialogFunc = f;
xxdialogButtons = b;
xxdialogTag = tag;
QE('idx_dlgOkButton', true);
QV('idx_dlgOkButton', b & 1);
QV('idx_dlgCancelButton', b & 2);
QV('id_dialogclose', (b & 2) || (b & 8));
QV('idx_dlgButtonBar', b & 7);
if (y) QH('id_dialogtitle', y);
for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
QV('dialog', x);
if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
}
function dialogclose(x) {
var f = xxdialogFunc;
var b = xxdialogButtons;
var t = xxdialogTag;
setDialogMode();
if (((b & 8) || x) && f) f(x, t);
}
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
function messagebox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
function statusbox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t); }
function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
</script>
</body></html>

View File

@ -0,0 +1,727 @@
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="shortcut icon" type="image/x-icon" href="{{{domainurl}}}favicon.ico">
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
<title>{{{title}}} - Login</title>
</head>
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
<div id="container">
<div id="masthead">
<div class="title">{{{title}}}</div>
<div class="title2">{{{title2}}}</div>
</div>
<div id="topbar" class="noselect style3" style="height:24px">
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
<div id="uiMenu" style="display:none">
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
</div>
</div>
</div>
<div id="column_l">
<h1>ようこそ</h1>
<div id="welcomeText" style="display:none">リアルタイムのオープンソースのリモート監視および管理WebサイトであるMeshCentralを使用して、世界中のどこからでも自宅またはオフィスのデバイスに接続します。コンピューターに管理エージェントをダウンロードしてインストールする必要があります。インストールすると、コンピューターはこのWebサイトの[デバイス]セクションに表示され、コンピューターを監視して制御できるようになります。</div>
<table id="centralTable" style="">
<tbody><tr>
<td id="welcomeimage">
<picture>
<img alt="" src="welcome.jpg" style="border-radius:20px">
</picture>
</td>
<td id="logincell">
<div id="loginpanel" style="display:none">
<form method="post">
<input type="hidden" name="action" value="login">
<div id="message1"></div>
<div>
<b>ログイン</b>
</div>
<table>
<tbody><tr>
<td id="loginusername" align="right" width="100">ユーザー名:</td>
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
</tr>
<tr>
<td align="right">パスワード:</td>
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
</tr>
<tr>
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">ヒントを見せて</a></div></td>
<td align="right"><input id="loginButton" type="submit" value="ログイン" disabled="disabled"></td>
</tr>
</tbody></table>
<div id="hrAccountDiv" style="display:none"><hr></div>
<div id="resetAccountDiv" style="display:none;padding:2px">
<span id="resetAccountSpan">ユーザー名/パスワードを忘れましたか?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">アカウントをリセット</a>。
</div>
<div id="newAccountDiv" style="display:none;padding:2px">
アカウントを持っていないのですか? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">一つ作る</a>。
</div>
<input id="loginformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="createpanel" style="display:none;position:relative">
<form method="post">
<input type="hidden" name="action" value="createaccount">
<div id="message2"></div>
<div>
<b>アカウント作成</b>
</div>
<div id="passwordPolicyCallout" style="display:none"></div>
<table>
<tbody><tr id="nuUserRow">
<td id="nuUser" align="right" width="100">ユーザー名:</td>
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
</tr>
<tr>
<td id="nuEmail" align="right" width="100">Eメール</td>
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
</tr>
<tr>
<td id="nuPass1" align="right">パスワード:</td>
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
</tr>
<tr>
<td id="nuPass2" align="right">パスワード:</td>
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
</tr>
<tr id="createPanelHint" style="display:none">
<td id="nuHint" align="right">パスワードのヒント:</td>
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
</tr>
<tr id="newAccountPass" title="アカウント作成トークンを入力してください">
<td id="nuToken" align="right">作成トークン:</td>
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="createButton" type="submit" value="アカウントを作成する" disabled="disabled"></div>
<div id="passWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
<input id="createformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="resetpanel" style="display:none">
<form method="post">
<input type="hidden" name="action" value="resetaccount">
<div id="message3"></div>
<div>
<b>アカウントのリセット</b>
</div>
<table>
<tbody><tr>
<td align="right" width="100">Eメール</td>
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="eresetButton" type="submit" value="アカウントをリセット" disabled="disabled"></div>
<div id="passWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
<input id="resetformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="tokenpanel" style="display:none">
<form method="post" autocomplete="off">
<input type="hidden" name="action" value="tokenlogin">
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
<div id="message4"></div>
<table>
<tbody><tr>
<td align="right" width="100">ログイントークン:</td>
<td>
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
</td>
</tr>
<tr>
<td colspan="2" style="align-content:center">
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">このデバイスを30日間記憶します。</label>
</td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="tokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="セキュリティキーを使用" onclick="useSecurityKey()"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
<input id="tokenformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="resettokenpanel" style="display:none">
<form method="post">
<input type="hidden" name="action" value="resetaccount">
<div id="message5"></div>
<table>
<tbody><tr>
<td align="right" width="100">ログイントークン:</td>
<td>
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
</td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
</form>
</div>
<div id="resetpasswordpanel" style="display:none;position:relative">
<form method="post">
<input type="hidden" name="action" value="resetpassword">
<div id="message6"></div>
<div id="rpasswordPolicyCallout" style="display:none"></div>
<table>
<tbody><tr>
<td id="rnuPass1" width="100" align="right">パスワード:</td>
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
</tr>
<tr>
<td id="rnuPass2" align="right">パスワード:</td>
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
</tr>
<tr id="resetpasswordpanelHint" style="display:none">
<td id="rnuHint" align="right">パスワードのヒント:</td>
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
</tr>
<tr>
<td colspan="2">
<div style="float:right"><input id="resetPassButton" type="submit" value="パスワードを再設定する" disabled="disabled"></div>
<div id="rpassWarning" style="padding-top:6px"></div>
</td>
</tr>
</tbody></table>
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
</form>
</div>
</td>
</tr>
</tbody></table>
<br>
</div>
<div id="footer">
<div class="footer1">{{{footer}}}</div>
<div class="footer2">
{{{rootCertLink}}}
&nbsp;<a href="terms">利用規約とプライバシー</a>
</div>
</div>
</div>
<div id="dialog" style="display:none">
<div id="dialogHeader">
<div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>バツ</b></div>
<div id="id_dialogtitle" style="padding:5px"></div>
<div style="width:100%;margin:6px"></div>
</div>
<div id="dialogBody">
<div id="dialog1">
<div id="id_dialogMessage" style=""></div>
</div>
<div id="dialog2" style="">
<div id="id_dialogOptions"></div>
</div>
</div>
<div id="idx_dlgButtonBar" style="">
<input id="idx_dlgCancelButton" type="button" value="キャンセル" style="" onclick="dialogclose(0)">
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
</div>
</div>
<script>
'use strict';
var passhint = '{{{passhint}}}';
var loginMode = '{{{loginmode}}}';
var newAccount = '{{{newAccount}}}';
var newAccountPass = parseInt('{{{newAccountPass}}}');
var emailCheck = ('{{{emailcheck}}}' == 'true');
var passRequirements = '{{{passRequirements}}}';
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
var features = parseInt('{{{features}}}');
var welcomeText = decodeURIComponent('{{{welcometext}}}');
var currentpanel = 0;
var uiMode = parseInt(getstore('uiMode', '1'));
var webPageFullScreen = true;
var nightMode = (getstore('_nightMode', '0') == '1');
var publicKeyCredentialRequestOptions = null;
// Display the right server message
var messageid = parseInt('{{{messageid}}}');
var okmessages = ['', "お待ちください、送信されたメールをリセットします。"];
var failmessages = ["アカウントを作成できません。", "アカウントの上限に達しました。", "このメールアドレスを持つ既存のアカウント。", "アカウント作成トークンが無効です。", "ユーザー名は既に存在します。", "パスワードが拒否されました。別のパスワードを使用してください。", "無効なメール。", "アカウントが見つかりませんでした。", "トークンが無効です。もう一度お試しください。", "メールを送信できません。", "アカウントがロックされました。", "アクセスが拒否されました。", "ログインに失敗しました。ユーザー名とパスワードを確認してください。", "パスワードの変更が要求されました。", "IPアドレスがブロックされています。しばらくしてからもう一度お試しください。"];
if (messageid > 0) {
var msg = '';
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
if (msg != '') {
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
}
}
// If URL arguments are provided, add them to form posts
if (window.location.href.indexOf('?') > 0) {
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
Q('loginformargs').value = urlargs;
Q('createformargs').value = urlargs;
Q('resetformargs').value = urlargs;
Q('tokenformargs').value = urlargs;
Q('resettokenformargs').value = urlargs;
Q('resetpasswordformargs').value = urlargs;
}
//var webPageFullScreen = getstore('webPageFullScreen', true);
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
//toggleFullScreen();
function startup() {
if ((features & 32) == 0) {
// Guard against other site's top frames (web bugs).
var loc = null;
try { loc = top.location.toString().toLowerCase(); } catch (e) { }
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
}
if (features & 0x200000) { // Email is username
QH('loginusername', "Eメール");
QH('resetAccountSpan', "パスワードをお忘れですか?");
QV('nuUserRow', false);
}
if (nightMode) { QC('body').add('night'); }
QV('createPanelHint', passRequirements.hint === true);
QV('resetpasswordpanelHint', passRequirements.hint === true);
// Display the welcome text
if (welcomeText) { QH('welcomeText', welcomeText); }
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
QV('welcomeText', true);
window.onresize = center;
center();
validateLogin();
validateCreate();
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
QV('newAccountPass', (newAccountPass == 1));
QV('resetAccountDiv', (emailCheck == true));
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
if (loginMode == '4') {
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
}
if (loginMode == '5') {
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
publicKeyCredentialRequestOptions.allowCredentials.push(
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
);
}
// New WebAuthn hardware keys
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
function (rawAssertion) {
var assertion = {
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
};
Q('resetHwtokenInput').value = JSON.stringify(assertion);
QE('resetTokenOkButton', true);
Q('resetTokenOkButton').click();
},
function (error) { console.log('credentials-get error', error); }
);
}
}
// Setup the user interface in the right mode
userInterfaceSelectMenu();
}
// Use a hardware security key
function useSecurityKey() {
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
publicKeyCredentialRequestOptions.allowCredentials.push(
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
);
}
// New WebAuthn hardware keys
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
function (rawAssertion) {
var assertion = {
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
};
Q('hwtokenInput').value = JSON.stringify(assertion);
QE('tokenOkButton', true);
Q('tokenOkButton').click();
},
function (error) { console.log('credentials-get error', error); }
);
}
}
function showPassHint(e) {
messagebox("パスワードのヒント", passhint);
haltEvent(e);
return false;
}
function xgo(x, e) {
QV('message1', false);
QV('message2', false);
QV('message3', false);
QV('message4', false);
QV('message5', false);
QV('message6', false);
go(x);
haltEvent(e);
return false;
}
function go(x) {
currentpanel = x;
setDialogMode(0);
QV('showPassHintLink', false);
QV('loginpanel', x == 1);
QV('createpanel', x == 2);
QV('resetpanel', x == 3);
QV('tokenpanel', x == 4);
QV('resettokenpanel', x == 5);
QV('resetpasswordpanel', x == 6);
if (x == 1) { Q('username').focus(); }
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
if (x == 3) { Q('remail').focus(); }
if (x == 4) { Q('tokenInput').focus(); }
if (x == 5) { Q('resetTokenInput').focus(); }
if (x == 6) { Q('rapassword1').focus(); }
}
function validateLogin(box, e) {
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
QE('loginButton', ok);
setDialogMode(0);
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
if (e != null) { haltEvent(e); }
}
function validateCreate(box, e) {
setDialogMode(0);
var userok = false;
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
var emailok = (validateEmail(Q('aemail').value) == true);
var pass1ok = (Q('apassword1').value.length > 0);
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
// Color the fields
QS('nuUser').color = userok?'black':'#7b241c';
QS('nuEmail').color = emailok?'black':'#7b241c';
QS('nuPass1').color = pass1ok?'black':'#7b241c';
QS('nuPass2').color = pass2ok?'black':'#7b241c';
QS('nuToken').color = newAccOk?'black':'#7b241c';
if (Q('apassword1').value == '') {
QH('passWarning', '');
QV('passwordPolicyCallout', false);
} else {
if (!passRequirementsEx) {
// No password requirements, display password strength
var passStrength = checkPasswordStrength(Q('apassword1').value);
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
else { QH('passWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
} else {
// Password requirements provided, use that
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
if (passReq == false) {
ok = false;
QS('nuPass1').color = '#7b241c';
QS('nuPass2').color = '#7b241c';
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
QV('passwordPolicyCallout', true);
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
} else {
QH('passWarning', '');
QV('passwordPolicyCallout', false);
}
}
}
if ((e != null) && (e.keyCode == 13)) {
if ((box == 1) && userok) { Q('aemail').focus(); }
if ((box == 2) && emailok) { Q('apassword1').focus(); }
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
if (box == 6) { Q('createButton').click(); }
}
if (e != null) { haltEvent(e); }
QE('createButton', ok);
}
function validatePassReset(box, e) {
setDialogMode(0);
var pass1ok = (Q('rapassword1').value.length > 0);
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
var ok = (pass1ok && pass2ok);
// Color the fields
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
if (Q('rapassword1').value == '') {
QH('rpassWarning', '');
QV('rpasswordPolicyCallout', false);
} else {
if (!passRequirementsEx) {
// No password requirements, display password strength
var passStrength = checkPasswordStrength(Q('rapassword1').value);
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
else { QH('rpassWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
} else {
// Password requirements provided, use that
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
if (passReq == false) {
ok = false;
QS('rnuPass1').color = '#7b241c';
QS('rnuPass2').color = '#7b241c';
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
QV('rpasswordPolicyCallout', true);
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
} else {
QH('rpassWarning', '');
QV('rpasswordPolicyCallout', false);
}
}
}
if ((e != null) && (e.keyCode == 13)) {
if (box == 2) { Q('rapassword1').focus(); }
if (box == 3) { Q('rapassword2').focus(); }
if (box == 4) { Q('rapasswordhint').focus(); }
if (box == 6) { Q('resetPassButton').click(); }
}
if (e != null) { haltEvent(e); }
QE('resetPassButton', ok);
}
function passwordPolicyText(pass) {
var policy = '<div style=text-align:left>';
var counts = strCount(pass);
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("最小長{0}", passRequirements.min) + '<br />'; }
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("{0}の最大長", passRequirements.max) + '<br />'; }
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0}大文字", passRequirements.upper) + '<br />'; }
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0}小文字", passRequirements.lower) + '<br />'; }
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0}数値", passRequirements.numeric) + '<br />'; }
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0}英数字以外", passRequirements.nonalpha) + '<br />'; }
policy += '</div>';
return policy;
}
function showPasswordPolicy() {
messagebox("パスワードポリシー", passwordPolicyText());
}
function validateReset(e) {
setDialogMode(0);
var x = validateEmail(Q('remail').value);
QE('eresetButton', x);
if ((e != null) && (e.keyCode == 13) && (x == true)) {
Q('eresetButton').click();
}
if (e != null) { haltEvent(e); }
}
// Return a password strength score
function checkPasswordStrength(password) {
var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
if (!password) return 0;
for (var i = 0; i< password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
return parseInt(r + (varCount - 1) * 10);
}
// Check password requirements
function checkPasswordRequirements(password, requirements) {
if ((requirements == null) || (requirements == '') || (typeof requirements != 'object')) return true;
if (requirements.min) { if (password.length < requirements.min) return false; }
if (requirements.max) { if (password.length > requirements.max) return false; }
var counts = strCount(password);
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
if (requirements.lower && (counts.lower < requirements.lower)) return false;
if (requirements.upper && (counts.upper < requirements.upper)) return false;
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
return true;
}
function strCount(password) {
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
if (typeof password != 'string') return counts;
for (var i = 0; i < password.length; i++) {
if (/\d/.test(password[i])) { counts.numeric++; }
if (/[a-z]/.test(password[i])) { counts.lower++; }
if (/[A-Z]/.test(password[i])) { counts.upper++; }
if (/\W/.test(password[i])) { counts.nonalpha++; }
}
return counts;
}
function checkToken() {
var t1 = Q('tokenInput').value;
var t2 = t1.split(' ').join('');
if (t1 != t2) { Q('tokenInput').value = t2; }
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
}
function resetCheckToken() {
var t1 = Q('resetTokenInput').value;
var t2 = t1.split(' ').join('');
if (t1 != t2) { Q('resetTokenInput').value = t2; }
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
}
//
// POPUP DIALOG
//
// undefined = Hidden, 1 = Generic Message
var xxdialogMode;
var xxdialogFunc;
var xxdialogButtons;
var xxdialogTag;
var xxcurrentView = 0;
// Display a dialog box
// Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
function setDialogMode(x, y, b, f, c, tag) {
xxdialogMode = x;
xxdialogFunc = f;
xxdialogButtons = b;
xxdialogTag = tag;
QE('idx_dlgOkButton', true);
QV('idx_dlgOkButton', b & 1);
QV('idx_dlgCancelButton', b & 2);
QV('id_dialogclose', (b & 2) || (b & 8));
QV('idx_dlgButtonBar', b & 7);
if (y) QH('id_dialogtitle', y);
for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
QV('dialog', x);
if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
}
function dialogclose(x) {
var f = xxdialogFunc;
var b = xxdialogButtons;
var t = xxdialogTag;
setDialogMode();
if (((b & 8) || x) && f) f(x, t);
}
// Toggle the web page to full screen
function toggleFullScreen(toggle) {
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
if (webPageFullScreen == false) {
// By adding body class, it will change a style of all ellements using CSS selector
// No need for JS anymore and it will be consistent style for all the templates.
QC('body').remove('fullscreen');
} else {
QC('body').add('fullscreen');
}
QV('body', true);
center();
}
// Toggle user interface menu
function showUserInterfaceSelectMenu() {
Q('uiViewButton1').classList.remove('uiSelectorSel');
Q('uiViewButton2').classList.remove('uiSelectorSel');
Q('uiViewButton3').classList.remove('uiSelectorSel');
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
QV('uiMenu', (QS('uiMenu').display == 'none'));
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
}
function userInterfaceSelectMenu(s) {
if (s) { uiMode = s; putstore('uiMode', uiMode); }
webPageFullScreen = (uiMode < 3);
//webPageStackMenu = (uiMode > 1);
toggleFullScreen(0);
//toggleStackMenu(0);
}
function toggleNightMode() {
nightMode = !nightMode;
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
putstore('_nightMode', (nightMode ? '1' : '0'));
}
function center() {
/* Now we use CSS media to achive the same effect as deleted JS */
if (webPageFullScreen == false) {
QS('centralTable')['margin-top'] = '';
} else {
var h = ((Q('column_l').clientHeight) / 2) - 220;
if (h < 0) h = 0;
QS('centralTable')['margin-top'] = h + 'px';
}
}
function messagebox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
function statusbox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t); }
function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
</script>
</body></html>

View File

@ -0,0 +1 @@
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><meta http-equiv=X-UA-Compatible content="IE=edge"><meta content="text/html;charset=utf-8"http-equiv=Content-Type><meta name=viewport content="user-scalable=1,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>MeshCentral - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>利用規約とプライバシー</a></table></div></div></div>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
<title>MeshCentral - {{{title3}}}</title>
</head>
<body>
<div id="container" style="max-height:100vh">
<div id="mastheadx"></div>
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px">
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div>
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_content" style="max-height:calc(100vh-138px)">
<div id="column_l">
<h1>{{{title3}}}</h1>
<p style="margin-left:20px">{{{message}}}</p>
<br>
</div>
<div id="footer">
<table cellpadding="0" cellspacing="10" style="width:100%">
<tbody><tr>
<td style="text-align:left"></td>
<td style="text-align:right">
<a href="terms">利用規約とプライバシー</a>
</td>
</tr>
</tbody></table>
</div>
</div>
</div>
</body></html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,642 @@
<!DOCTYPE html><html style="height:100%"><head>
<title>MeshMessenger</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<link type="text/css" href="styles/messenger.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<script type="text/javascript" src="scripts/filesaver.js"></script>
</head>
<body style="font-family:Arial,Helvetica,sans-serif">
<div id="xtop" style="position:absolute;left:0;right:0;top:0;height:38px;background-color:#036;color:#c8c8c8;box-shadow:3px 3px 10px gray">
<div style="position:absolute;background-color:#036;right:0;height:38px">
<div id="notifyButton" class="icon13 topButton" style="margin-right:4px;display:none" title="ブラウザ通知を有効にする" onclick="enableNotificationsButtonClick()"></div>
<div id="fileButton" class="icon4 topButton" title="ファイルを共有する" style="display:none" onclick="fileButtonClick()"></div>
<div id="camButton" class="icon2 topButton" title="カメラとマイクを有効にする" style="display:none" onclick="camButtonClick()"></div>
<div id="micButton" class="icon6 topButton" title="マイクを有効にする" style="display:none" onclick="micButtonClick()"></div>
<div id="hangupButton" class="icon11 topRedButton" title="電話を切る" style="display:none" onclick="hangUpButtonClick(1)"></div>
</div>
<div style="padding-top:9px;padding-left:6px;font-size:20px;display:inline-block"><b><span id="xtitle">MeshMessenger</span></b></div>
</div>
<div id="xmiddle" style="position:absolute;left:0;right:0;top:38px;bottom:30px">
<div style="position:absolute;left:0;right:0;top:0;bottom:0;overflow-y:scroll">
<div id="xmsg" style="position:absolute;left:0;right:0;bottom:0;padding:5px"></div>
</div>
</div>
<div id="xbottom" style="position:absolute;left:0;right:0;bottom:0px;height:30px;background-color:#036">
<div style="position:absolute;left:5px;right:215px;bottom:4px;top:4px;background-color:aliceblue"><input id="xouttext" type="text" style="width:calc(100% - 5px)" onfocus="onUserInputFocus(1)" onblur="onUserInputFocus(0)"></div>
<input type="button" id="sendButton" value="送る" style="position:absolute;right:110px;width:100px;top:4px;" onclick="xsend(event)">
<input type="button" id="clearButton" value="クリア" style="position:absolute;right:5px;width:100px;top:4px;" onclick="displayClear()">
</div>
<div id="remoteVideo" style="position:absolute;right:24px;top:45px;width:320px;height:calc(240px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none">
<div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">リモート</div>
<video id="remoteVideoCanvas" autoplay="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video>
</div>
<div id="localVideo" style="position:absolute;right:24px;top:320px;width:160px;height:calc(120px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none">
<div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">地元</div>
<video id="localVideoCanvas" autoplay="" muted="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video>
</div>
<input id="uploadFileInput" type="file" multiple="" style="display:none">
<script type="text/javascript" onunload="onUnLoad()">
var userInputFocus = 0;
var args = parseUriArgs();
var socket = null; // Websocket object
var state = 0; // Connection state. 0 = Disconnected, 1 = Connecting, 2 = Connected.
// WebRTC sessions and data, audio and video channels
var random = Math.random(); // Selected random, larger value initiates WebRTC.
var webrtcSessions = { }; // WebRTC objects: 0 for data, 1 for outbound audio/video, 2 for inbound audio/video
var webchannel = null; // WebRTC data channel
var localStream = null;
var remoteStream = null;
var multiWebRtc = true; // if set to true, multiple WebRTC sessions will be setup. If false, everything uses one session.
var userMediaSupport = 0;
var notification = null;
getUserMediaSupport(function (x) { userMediaSupport = x; })
var webrtcconfiguration = '{{{webrtconfig}}}';
if (webrtcconfiguration == '') { webrtcconfiguration = null; } else { try { webrtcconfiguration = JSON.parse(decodeURIComponent(webrtcconfiguration)); } catch (ex) { console.log('Invalid WebRTC config: \"' + webrtcconfiguration + '\".'); webrtcconfiguration = null; } }
// File transfer state
var fileUploads = [];
var fileDownloads = {};
var currentFileUpload = null;
var currentFileDownload = null;
// Set the title
if (args.title) { QH('xtitle', args.title.split(' ').join('&nbsp')); document.title = document.title + ' - ' + args.title; }
// Setup web notifications
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
// Listen to drag & drop events
document.addEventListener('dragover', haltEvent, false);
document.addEventListener('dragleave', haltEvent, false);
document.addEventListener('drop', fileDrop, false);
document.onclick = function (e) {
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
if (notification != null) { notification.close(); notification = null; }
}
// Trap document key up events
document.onkeyup = function ondockeypress(e) {
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
if (notification != null) { notification.close(); notification = null; }
if (state == 2) {
if ((e.keyCode == 8) && (userInputFocus == 0)) {
// Backspace
var outtext = Q('xouttext').value;
if (outtext.length > 0) { Q('xouttext').value = outtext.substring(0, outtext.length - 1); }
}
}
if (userInputFocus == 0) { haltEvent(e); return false; }
}
// Trap document key presses
document.onkeypress = function ondockeypress(e) {
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
if (notification != null) { notification.close(); notification = null; }
if (state == 2) {
if (e.keyCode == 13) {
// Return
xsend(e);
} else {
// Any other key
if ((userInputFocus == 0) && (e.key.length == 1)) { Q('xouttext').value = Q('xouttext').value + e.key; }
}
}
if (userInputFocus == 0) { haltEvent(e); return false; }
}
function onUserInputFocus(x) { userInputFocus = x; }
function displayClear() { QH('xmsg', ''); cancelAllFileTransfers(); fileUploads = [], fileDownloads = {}; }
// Polyfill FileReader if needed
if (!FileReader.prototype.readAsBinaryString) {
FileReader.prototype.readAsBinaryString = function (fileData) {
var binary = '', self = this, reader = new FileReader();
reader.onload = function (e) {
var bytes = new Uint8Array(reader.result);
for (var i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); }
self.onload({ target: { result: binary } });
}
reader.readAsArrayBuffer(fileData);
}
}
// Detect if microphone & camera are present
// 0 = nomedia, 1 = miconly, 2 = mic&cam
function getUserMediaSupport(func) {
try {
navigator.mediaDevices.enumerateDevices().then(function (devices) {
try {
var mic = 0, cam = 0;
devices.forEach(function (device) {
if (device.kind === 'audioinput') { mic = 1; }
if (device.kind === 'videoinput') { cam = 1; }
});
if (mic == 0) { func(0); }
func(mic + cam);
} catch (ex) { }
})
} catch (ex) { }
}
// Display a control message
function displayControl(msg) {
QA('xmsg', '<div style="clear:both"><div style="color:gray;float:left;margin-bottom:2px">' + msg + '</div><div></div></div>');
Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
}
function displayLocalVideo(active) { QV('localVideo', active); adjustVideoWindows(); }
function displayRemoteVideo(active) { QV('remoteVideo', active); adjustVideoWindows(); }
function adjustVideoWindows() {
//var lv = (QS('localVideo')['display'] != 'none');
var rv = (QS('remoteVideo')['display'] != 'none');
QS('localVideo')['top'] = rv ? '320px' : '45px';
}
// Display a message from the remote user
function displayRemote(msg) {
QA('xmsg', '<div style="clear:both"><div class="remoteBubble">' + msg + '</div><div></div></div>');
Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
// If web notifications are granted, use it.
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
if (Notification && (Notification.permission == 'granted')) {
if (notification != null) { notification.close(); notification = null; }
if (args.title) {
notification = new Notification("MeshMessenger" + ' - ' + args.title, { body: msg });
} else {
notification = new Notification("MeshMessenger", { body: msg });
}
}
}
// Display and send a message from the local user
function xsend(event) {
if (notification != null) { notification.close(); notification = null; }
if (Notification) { QV('notifyButton', Notification.permission != 'granted'); }
var outtext = Q('xouttext').value;
if (outtext.length > 0) {
Q('xouttext').value = '';
QA('xmsg', '<div style="clear:both"><div class="localBubble">' + outtext + '</div><div></div></div>');
Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
send({ action: 'chat', msg: outtext });
}
}
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
// Update user controls
function updateControls() {
QE('sendButton', state == 2);
QE('clearButton', state == 2);
QE('xouttext', state == 2);
QV('fileButton', state == 2);
QV('camButton', webchannel && webchannel.ok && !localStream && (userMediaSupport == 2));
QV('micButton', webchannel && webchannel.ok && !localStream && (userMediaSupport > 0));
QV('hangupButton', webchannel && webchannel.ok && localStream);
}
// This is the WebRTC setup
function startWebRTC(id, startDataChannel) {
if ((webrtcSessions[0] != null) && (multiWebRtc == false)) { return webrtcSessions[0]; };
// Setup the WebRTC object
var webrtc = null;
if (typeof RTCPeerConnection !== 'undefined') { webrtc = new RTCPeerConnection(webrtcconfiguration); }
else if (typeof webkitRTCPeerConnection !== 'undefined') { webrtc = new webkitRTCPeerConnection(webrtcconfiguration); }
if (webrtc == null) return null; // No WebRTC support.
webrtc.id = id;
webrtc.onicecandidate = function (e) { try { if (e.candidate != null) { sendws({ action: 'webRtcIce', ice: e.candidate, id: this.id }); } } catch (ex) { } }
webrtc.oniceconnectionstatechange = function () { if (webrtc && webrtc.iceConnectionState == 'failed') { webrtc.close(); if (webrtcSessions[webrtc.id]) { delete webrtcSessions[webrtc.id]; } } }
webrtc.ondatachannel = function (ev) {
//console.log('ondatachannel');
webchannel = ev.channel;
webchannel.onmessage = function (event) { processMessage(event.data, 2); };
webchannel.onopen = function () { webchannel.ok = true; updateControls(); sendws({ action: 'rtcSwitch', v: 0 }); };
webchannel.onclose = function (event) { if (webchannel && webchannel.ok) { disconnect(); } else { hangUpButtonClick(0); } }
}
webrtc.onnegotiationneeded = function (event) {
if (webrtc.holdTimer != null) return;
webrtc.holdTimer = setTimeout(function () { // This time is needed to keep Chrome from being to excited. Wait until we add all tracks before kicking this off.
//console.log('onnegotiationneeded', id);
webrtc.holdTimer = null;
webrtc.createOffer(function (offer) { /*console.log('offer', offer.sdp.length);*/ webrtc.setLocalDescription(offer, function () { sendws({ action: 'webRtcSdp', sdp: offer, id: id }); }, function () { hangUpButtonClick(id); }); }, function () { hangUpButtonClick(id); });
}, 20);
}
webrtc.ontrack = function (event) {
//console.log('ontrack', id);
var video = Q('remoteVideoCanvas');
video.srcObject = remoteStream = event.streams[0];
video.onloadedmetadata = function (e) { video.play(); };
displayRemoteVideo(true);
}
//webrtc.onremovetrack = function (event) { console.log('onremovetrack'); }
//webrtc.onicegatheringstatechange = function (event) { console.log('onicegatheringstatechange', event); }
//webrtc.onsignalingstatechange = function (event) { console.log('onsignalingstatechange', event); }
// Initiate the WebRTC offer or handle the offer from the peer.
if (startDataChannel == true) {
webchannel = webrtc.createDataChannel('DataChannel', {}); // { ordered: false, maxRetransmits: 2 }
webchannel.onmessage = function (event) { processMessage(event.data, 2); };
webchannel.onopen = function () { webchannel.ok = true; updateControls(); sendws({ action: 'rtcSwitch', v: 0 }); };
webchannel.onclose = function (event) { if (webchannel && webchannel.ok) { disconnect(); } else { hangUpButtonClick(0); } }
}
webrtcSessions[id] = webrtc;
return webrtc;
}
function webRtcHandleOffer(id, description) {
//console.log('webRtcHandleOffer', description.sdp.length);
var webrtc = webrtcSessions[id];
if (webrtc) {
webrtc.setRemoteDescription(new RTCSessionDescription(description), function () {
if (description.type == 'offer') {
webrtc.createAnswer(function (answer) {
webrtc.setLocalDescription(answer, function (a, b) {
try { sendws({ action: 'webRtcSdp', sdp: answer, id: id }); } catch (ex) { }
}, function () { hangUpButtonClick(id); });
}, function () { hangUpButtonClick(id); });
}
}, function () { hangUpButtonClick(id); });
}
}
// Indicate to peer that data traffic will no longer be sent over websocket and start holding traffic.
function performWebRtcSwitch() {
if (webchannel && webchannel.ok) { sendws({ action: 'rtcSwitch', v: 1 }); webchannel.xoutBuffer = []; }
}
// Disconnect everything
function disconnect() {
if (state > 0) { displayControl("接続が閉じられました。"); }
if (state > 1) { setTimeout(start, 500); }
cancelAllFileTransfers();
hangUpButtonClick(0, true); // Data channel
hangUpButtonClick(1, true); // Local audio/video
hangUpButtonClick(2, true); // Remote audio/video
if (socket != null) { socket.close(); socket = null; }
updateControls();
state = 0;
}
// Send data over the current transport (WebRTC first)
function send(data) {
if (state != 2) return; // If not in connected state, ignore this.
if (typeof data == 'object') { data = JSON.stringify(data); } // If this is an object, convert it to a string.
if (webchannel && webchannel.ok) { if (webchannel.xoutBuffer != null) { webchannel.xoutBuffer.push(data); } else { webchannel.send(data); } } // If WebRTC channel is possible, use it or hold until we can use it.
else { if (socket != null) { try { socket.send(data); } catch (ex) { } } } // If a websocket channel is present, use that.
}
// Send data over the websocket transport (WebSocket only)
function sendws(data) {
if (state != 2) return;
//console.log('SEND', data);
if (typeof data == 'object') { data = JSON.stringify(data); }
if (socket != null) { socket.send(data); }
}
// WebRTC id switcher (0 -> 0, 1 -> 2, 2 -> 1)
function webRtcIdSwitch(id) { if (id == 0) { return 0; } return 3 - id; }
// Process incoming messages
function processMessage(data, transport) {
if (typeof data == 'string') {
try { data = JSON.parse(data); } catch (ex) { console.log('Unable to parse', data); return; }
//console.log('RECV', data);
switch (data.action) {
case 'chat': { displayRemote(data.msg); break; } // Incoming chat message.
case 'random': { if (random > data.random) { startWebRTC(0, true); } break; } // If we have a larger random value, we start WebRTC.
case 'webRtcSdp': { if (!webrtcSessions[webRtcIdSwitch(data.id)]) { startWebRTC(webRtcIdSwitch(data.id), false); } webRtcHandleOffer(webRtcIdSwitch(data.id), data.sdp); break; } // Remote WebRTC offer or answer.
case 'webRtcIce': { var webrtc = webrtcSessions[webRtcIdSwitch(data.id)]; if (webrtc) { try { webrtc.addIceCandidate(new RTCIceCandidate(data.ice)); } catch (ex) { } } break; } // Remote ICE candidate
case 'videoStop': { hangUpButtonClick(webRtcIdSwitch(data.id), true); break; }
case 'rtcSwitch': { // WebRTC switch over commands.
switch (data.v) {
case 0: { performWebRtcSwitch(); break; } // Other side is ready for switch over to WebRTC
case 1: { sendws({ action: 'rtcSwitch', v: 2 }); break; } // Other side no longer sending data on websocket, confirm we got the end marker
case 2: { for (var i in webchannel.xoutBuffer) { webchannel.send(webchannel.xoutBuffer[i]); } delete webchannel.xoutBuffer; break; } // Send any pending data over WebRTC and start using WebRTC with all traffic
default: { console.log('Unknown rtcSwitch value: ' + data.action); break; } //
}
break;
}
case 'file': { startFileDownload(data); break; }
case 'fileUploadCancel': { cancelFileTransfer(data.id); break; }
case 'fileUploadStart': {
if (fileDownloads[data.id]) {
currentFileDownload = fileDownloads[data.id];
currentFileDownload.data = '';
changeFileInfo(data.id, 2, 0);
continueFileDownload(data);
send({ action: 'fileUploadAck', id: data.id });
} break;
}
case 'fileUploadEnd': {
if (currentFileDownload && (currentFileDownload.id == data.id)) {
changeFileInfo(data.id, 3, 200);
currentFileDownload.done = 1;
currentFileDownload = null;
send({ action: 'fileUploadAck', id: data.id });
}
currentFileDownload = null;
break;
}
case 'fileUploadAck': {
continueFileUpload();
break;
}
case 'fileData': {
if (currentFileDownload && (currentFileDownload.id == data.id)) {
currentFileDownload.data += data.data;
changeFileInfo(data.id, 2, (currentFileDownload.data.length * 200 / currentFileDownload.size));
send({ action: 'fileUploadAck', id: data.id });
}
break;
}
default: { console.log('Unhandled object data', data); break; }
}
} else {
console.log('Unhandled data', typeof data, data);
}
}
// File sharing button
function fileButtonClick() {
var chooser = Q('uploadFileInput');
if (chooser.getAttribute('eventset') != 1) {
chooser.setAttribute('eventset', '1');
chooser.addEventListener('change', fileSelect, false);
}
chooser.value = null;
chooser.click();
}
// User selected one or more files to upload to remote user.
function fileSelect() {
if (state != 2) return;
var x = Q('uploadFileInput');
if (x.files.length > 10) {
displayControl("同時にアップロードできるファイルの上限は10です。");
} else {
for (var i = 0; i < x.files.length; i++) {
if (x.files[i].size > 0) {
var reader = new FileReader();
reader.onload = function (e) { this.xfile.data = e.target.result; startFileUpload(this.xfile); };
reader.xfile = x.files[i];
reader.readAsBinaryString(x.files[i]);
}
}
}
}
// User drag & droped one or more files to upload to remote user.
function fileDrop(e) {
haltEvent(e);
if ((state != 2) || (e.dataTransfer == null)) return;
if (e.dataTransfer.files.length > 10) {
displayControl("同時にアップロードできるファイルの上限は10です。");
} else {
for (var i = 0; i < e.dataTransfer.files.length; i++) {
if (e.dataTransfer.files[i].size > 0) {
var reader = new FileReader();
reader.onload = function (e) { this.xfile.data = e.target.result; startFileUpload(this.xfile); };
reader.xfile = e.dataTransfer.files[i];
reader.readAsBinaryString(e.dataTransfer.files[i]);
}
}
}
}
function startFileUpload(file) {
if (state != 2) return;
file.id = Math.random();
fileUploads.push(file);
QA('xmsg', '<div style="clear:both"></div><div id="FILEUP-' + file.id + '" class="localBubble" style="width:240px;cursor:pointer" onclick="cancelFileTransfer(\'' + file.id + '\')"><div id="FILEUP-ICON-' + file.id + '" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-' + file.id + '" style="height:16px;overflow:hidden;white-space:nowrap;" title="' + file.name + '">' + file.name + '</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-' + file.id + '" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');
Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
send({ action: 'file', size: file.size, id: file.id, type: file.type, name: file.name });
if (currentFileUpload == null) continueFileUpload();
}
function startFileDownload(file) {
if (state != 2) return;
fileDownloads[file.id] = file;
QA('xmsg', '<div style="clear:both"></div><div id="FILEUP-' + file.id + '" class="remoteBubble" style="width:240px;cursor:pointer" onclick="saveFileTransfer(\'' + file.id + '\')"><div id="FILEUP-ICON-' + file.id + '" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-' + file.id + '" style="height:16px;overflow:hidden;white-space:nowrap;" title="' + file.name + '">' + file.name + '</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-' + file.id + '" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');
Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
}
// Change the file icon and progress
function changeFileInfo(id, icon, progress, progressColor) {
if (icon) {
Q('FILEUP-ICON-' + id).classList.remove('fileicon');
Q('FILEUP-ICON-' + id).classList.remove('fileiconx');
Q('FILEUP-ICON-' + id).classList.remove('fileicontransfer');
Q('FILEUP-ICON-' + id).classList.remove('fileicondone');
Q('FILEUP-ICON-' + id).classList.add(['fileicon', 'fileiconx', 'fileicontransfer', 'fileicondone'][icon]);
}
if (progress) { QS('FILEUP-PROGRESS-' + id)['width'] = progress + 'px'; }
if (progressColor) { QS('FILEUP-PROGRESS-' + id)['background-color'] = progressColor; }
}
// Convert a string into a blob
function data2blob(data) {
var bytes = new Array(data.length);
for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
return new Blob([new Uint8Array(bytes)]);
};
function saveFileTransfer(id) {
var f = fileDownloads[id];
if (f && f.done == 1) { saveAs(data2blob(f.data), f.name); }
}
function cancelFileTransfer(id) {
if ((currentFileUpload != null) && (currentFileUpload.id == id)) { currentFileUpload = null; }
if ((currentFileDownload != null) && (currentFileDownload.id == id)) { currentFileDownload = null; }
var found = false;
if (fileDownloads[id] && (fileDownloads[id].done != 1)) {
delete fileDownloads[id];
found = true;
} else {
for (var i in fileUploads) {
if (fileUploads[i].id == id) {
send({ action: 'fileUploadCancel', id: id });
fileUploads.splice(i, 1);
found = true;
break;
}
}
}
if (found) { changeFileInfo(id, 1, 200, 'gray'); } // Only cancel a file if it was in the file queue.
}
function cancelAllFileTransfers() {
for (var i in fileDownloads) { cancelFileTransfer(fileDownloads[i].id); }
for (var i in fileUploads) { cancelFileTransfer(fileUploads[i].id); }
}
function continueFileUpload() {
if (currentFileUpload == null) {
// Select the next file to upload
if (fileUploads.length == 0) { return; } // Nothing to do
currentFileUpload = fileUploads[0];
currentFileUpload.ptr = 0;
// Indicate that we are sending this file
send({ action: 'fileUploadStart', size: currentFileUpload.size, id: currentFileUpload.id, type: currentFileUpload.type, name: currentFileUpload.name });
} else {
if (currentFileUpload.size <= currentFileUpload.ptr) {
// If we are done, send the end marker
send({ action: 'fileUploadEnd', size: currentFileUpload.size, id: currentFileUpload.id, type: currentFileUpload.type, name: currentFileUpload.name });
changeFileInfo(currentFileUpload.id, 3, 200);
fileUploads.splice(0, 1);
currentFileUpload = null;
continueFileUpload(); // Send the next file
} else {
// Send the next block
var nextBlockLen = Math.min(4000, currentFileUpload.data.length - currentFileUpload.ptr);
var data = currentFileUpload.data.substring(currentFileUpload.ptr, currentFileUpload.ptr + nextBlockLen);
send({ action: 'fileData', id: currentFileUpload.id, data: data });
currentFileUpload.ptr += nextBlockLen;
changeFileInfo(currentFileUpload.id, 0, (currentFileUpload.ptr * 200 / currentFileUpload.size));
}
}
}
function continueFileDownload(msg) {
send({ action: 'fileUploadAck', id: msg.id });
}
// Toggle notification
function enableNotificationsButtonClick() {
if (Notification) { Notification.requestPermission().then(function (permission) { QV('notifyButton', permission != 'granted'); }); }
return false;
}
// Camera button
function camButtonClick() {
if (localStream == null) { startLocalStream({ video: true, audio: true }); }
}
// Microphone
function micButtonClick() {
if (localStream == null) { startLocalStream({ video: false, audio: true }); }
}
function hangUpButtonClick(id, fromRemote) {
//console.log('hangUpButtonClick', id);
var localVideo = Q('localVideoCanvas');
var remoteVideo = Q('remoteVideoCanvas');
var webrtc = webrtcSessions[(multiWebRtc == true)? id : 0];
if ((id == 0) && (webchannel != null)) { try { webchannel.close(); } catch (e) { } webchannel = null; }
if (webrtc) {
if ((multiWebRtc == true) || (id == 0)) {
webrtc.ontrack = null;
webrtc.onremovetrack = null;
webrtc.onremovestream = null;
webrtc.onnicecandidate = null;
webrtc.oniceconnectionstatechange = null;
webrtc.onsignalingstatechange = null;
webrtc.onicegatheringstatechange = null;
webrtc.onnotificationneeded = null;
}
if ((id == 1) && localStream) { var tracks = localStream.getTracks(); for (var i in tracks) { tracks[i].stop(); } localStream = null; }
if ((id == 2) && remoteStream) { var tracks = remoteStream.getTracks(); for (var i in tracks) { tracks[i].stop(); } remoteStream = null; }
if ((multiWebRtc == true) || (id == 0)) {
webrtc.close();
delete webrtcSessions[id];
}
}
if (id == 1) {
localVideo.removeAttribute('src');
localVideo.removeAttribute('srcObject');
if (localStream != null) { localStream = null; }
displayLocalVideo(false);
} else if (id == 2) {
remoteVideo.removeAttribute('src');
remoteVideo.removeAttribute('srcObject');
displayRemoteVideo(false);
}
if (fromRemote != true) { send({ action: 'videoStop', id: id }); }
updateControls();
}
// Setup local audio/video
function startLocalStream(constraints) {
var channel = (multiWebRtc == true) ? 1 : 0;
if (localStream != null) return;
if ((multiWebRtc == true) && (webrtcSessions[1] != null)) return;
if (navigator.mediaDevices.getUserMedia) {
localStream = 1;
updateControls();
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
localStream = stream;
var tracks = localStream.getTracks();
var webrtc = startWebRTC(channel);
if (constraints.video == true) {
var video = Q('localVideoCanvas');
video.srcObject = stream;
video.onloadedmetadata = function (e) { video.play(); };
displayLocalVideo(true);
}
for (var i in tracks) { webrtc.addTrack(tracks[i], localStream); }
}, function (err) {
displayControl(err.message + '.');
hangUpButtonClick(1);
});
}
}
// This is the main start
function start() {
// Get started
updateControls();
if ((typeof args.id == 'string') && (args.id.length > 0)) {
var url = window.location.protocol.replace('http', 'ws') + '//' + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/meshrelay.ashx?id=' + args.id;
if ((args.auth != null) && (args.auth != '')) { url += '&auth=' + args.auth; }
socket = new WebSocket(url);
socket.onopen = function () { state = 1; displayControl("他のユーザーを待っています..."); }
socket.onerror = function (e) { /*console.error(e);*/ }
socket.onclose = function () { disconnect(); }
socket.onmessage = function (msg) {
if ((state < 2) && (typeof msg.data == 'string') && ((msg.data == 'c') || (msg.data == 'cr'))) {
hangUpButtonClick(0, true);
hangUpButtonClick(1, true);
hangUpButtonClick(2, true);
displayControl("接続済み。");
state = 2;
updateControls();
sendws({ action: 'random', random: random }); // Send a random number. Higher number starts the WebRTC session.
return;
}
if (state == 2) { processMessage(msg.data, 1); }
}
} else {
displayControl("エラー:接続キーが指定されていません。");
}
}
start();
function onUnLoad() {
for (var i = 0; i < 3; i++) { if (webrtcSessions[i]) { webrtcSessions[i].close(); delete webrtcSessions[i]; } }
if (webchannel != null) { try { webchannel.close(); } catch (e) { } webchannel = null; }
if (socket != null) { try { socket.close(); } catch (e) { } socket = null; }
}
</script>
</body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,160 @@
<!DOCTYPE html><html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<title>MeshCentral - Terms of use</title>
<style type="text/css">
a {
color: #036;
text-decoration: underline;
}
#footer a {
color: #fff;
text-decoration: underline;
}
#footer a:hover {
color: #fff;
text-decoration: none;
}
</style>
</head>
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
<div id="container">
<!-- Begin Masthead -->
<div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
</div>
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:7px">
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
</div>
</div>
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px">
<div id="column_l" style="padding-left:10px;padding-right:10px">
<h1>利用規約</h1>
<p>利用規約については、サイト管理者にお問い合わせください。</p>
<hr>
<p class="MsoNormal">
以下は、このソフトウェアに組み込まれているオープンソースコンポーネントとソフトウェアの必須の開示です。
</p>
<p class="MsoNormal">
<b><span>1.AJAX Control Toolkit-新しいBSDライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyrightc2009、CodePlex Foundation。全著作権所有。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、次の条件が満たされている場合に許可されます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>1.ソースコードの再配布には、上記の著作権表示、この条件リスト、および以下の免責事項を保持する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>2.バイナリ形式での再配布では、上記の著作権表示、この条件リスト、および以下の免責事項を、配布物とともに提供されるドキュメントおよび/またはその他の資料に複製する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>3. CodePlex Foundationの名前もその貢献者の名前も、書面による事前の許可なしに、このソフトウェアから派生した製品を推奨または宣伝するために使用することはできません。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、著作権者および寄稿者によって「現状のまま」提供され、商品性および特定の目的への適合性の黙示的な保証を含むがこれに限定されない明示的または黙示的な保証は放棄されます。いかなる場合においても、著作権所有者または貢献者は、直接的、間接的、偶発的、特別、例示的、または結果的な損害代替品またはサービスの調達、代替品、データ、または利益の損失を含むが、これらに限定されないについて責任を負わないものとしますまたはビジネス中断責任の理論、または契約、厳格な責任、または不法行為過失またはその他を含むにかかわらず、このソフトウェアの使用から生じたものであっても、POSSIの可能性がある場合でも。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>2.OpenSSL OpenSSLおよびSSLeayライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="http://www.openssl.org/source/license.html">http://www.openssl.org/source/license.html</a> </span>
</p>
<p class="MsoNormal">
<span>Copyrightc1998-2011 The OpenSSL Project。全著作権所有。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、次の条件が満たされている場合に許可されます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>1.ソースコードの再配布には、上記の著作権表示、この条件リスト、および以下の免責事項を保持する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>2.バイナリ形式での再配布では、上記の著作権表示、この条件リスト、および以下の免責事項を、配布物とともに提供されるドキュメントおよび/またはその他の資料に複製する必要があります。 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>3.このソフトウェアの機能または使用について言及するすべての広告資料には、「この製品には、OpenSSL Toolkitで使用するためにOpenSSL Projectによって開発されたソフトウェアが含まれます。http://www.openssl.org/)」 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>4.「OpenSSL Toolkit」および「OpenSSL Project」という名前は、事前の書面による許可なしに、このソフトウェアから派生した製品を推奨または宣伝するために使用しないでください。書面による許可については、openssl-core @ openssl.orgにお問い合わせください。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>5.このソフトウェアから派生した製品は、OpenSSL Projectの事前の書面による許可なしに、「OpenSSL」と呼ばれたり、名前に「OpenSSL」が表示されたりすることはありません。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>6.いかなる形式の再配布でも、「この製品には、OpenSSL Toolkithttp://www.openssl.org/で使用するためにOpenSSL Projectによって開発されたソフトウェアが含まれます」という承認を保持する必要があります。 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、OpenSSLプロジェクトによって「現状のまま」提供され、商品性および特定の目的への適合性の黙示的な保証を含むがこれに限定されない、明示的または黙示的な保証は放棄されます。いかなる場合も、OpenSSLプロジェクトまたはその貢献者は、直接的、間接的、偶発的、特別、例示的、または結果的損害責任を含むが、特別損害、例示的損害、または結果的損害を含むの責任を負いませんまたはサービス、使用、データ、または利益の損失、またはビジネス中断、契約、厳格な責任、または不法行為過失またはその他を含むこのような損害の可能性について通知された場合でも、ソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>3. jQuery Foundation-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyright 2013 jQuery Foundationおよびその他の貢献者 <a href="http://jquery.com/">http://jquery.com/</a></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。</span>
</p>
<p class="MsoNormal">
<b><span>4. jQueryユーザーインターフェイス-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyright 2013 jQuery Foundationおよびその他の貢献者、 <a href="http://jqueryui.com/">http://jqueryui.com/</a></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、多くの個人による自発的な貢献で構成されていますAUTHORS.txt、http//jqueryui.com/about。正確な貢献履歴については、http//jquery-ui.googlecode.com/svn/にある改訂履歴とログをご覧ください <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>5. noVNC-Mozilla Public License 2.0</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="https://github.com/kanaka/noVNC/blob/master/LICENSE.txt">https://github.com/kanaka/noVNC/blob/master/LICENSE.txt</a></span>
</p>
<p class="MsoNormal">
<span>CopyrightC2011 Joel Martinこのソースコードフォームには、Mozilla Public License v。2.0の条件が適用されます。 MPLのコピーがこのファイルとともに配布されていない場合は、http//mozilla.org/MPL/2.0/から入手できます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>6.Rcarousel-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="https://github.com/ryrych/rcarousel/blob/master/widget/license">https://github.com/ryrych/rcarousel/blob/master/widget/license</a></span>
</p>
<p class="MsoNormal">
<span>Copyrightc2010 Wojciech 'RRH' Ryrych<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>7.Webtoolkit Javascript Base 64 Creative Commons Attribution 2.0 UKライセンス</span></b><span><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアはからのコードを使用します <a href="http://www.webtoolkit.info/javascript-base64.html">http://www.webtoolkit.info/javascript-base64.html</a> の下でライセンス <a href="http://creativecommons.org/licenses/by/2.0/uk/legalcode">http://creativecommons.org/licenses/by/2.0/uk/legalcode</a> そのソースはからダウンロードできます <a href="http://www.webtoolkit.info/javascript-base64.html">http://www.webtoolkit.info/javascript-base64.html</a>。<o:p></o:p></span>
</p>
<br>
</div>
</div>
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
<table cellpadding="0" cellspacing="6" style="width:100%">
<tbody><tr>
<td style="text-align:left;color:white">{{{footer}}}</td>
<td style="text-align:right">{{{rootCertLink}}}&nbsp;<a href="/">バック</a></td>
</tr>
</tbody></table>
</div>
</div>
</body></html>

View File

@ -0,0 +1,246 @@
<!DOCTYPE html><html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<title>MeshCentral - Terms of use</title>
</head>
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
<div id="container">
<!-- Begin Masthead -->
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:20px; padding-top:8px">
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title}}}</font></strong>
</div>
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
</div>
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;"></p>
</div>
<div id="page_leftbar">
<div style="height:16px"></div>
</div>
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
<div id="uiMenu" style="display:none">
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
</div>
</div>
</div>
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
<h1>利用規約</h1>
<p>利用規約については、サイト管理者にお問い合わせください。</p>
<hr>
<p class="MsoNormal">
以下は、このソフトウェアに組み込まれているオープンソースコンポーネントとソフトウェアの必須の開示です。
</p>
<p class="MsoNormal">
<b><span>1.AJAX Control Toolkit-新しいBSDライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyrightc2009、CodePlex Foundation。全著作権所有。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、次の条件が満たされている場合に許可されます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>1.ソースコードの再配布には、上記の著作権表示、この条件リスト、および以下の免責事項を保持する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>2.バイナリ形式での再配布では、上記の著作権表示、この条件リスト、および以下の免責事項を、配布物とともに提供されるドキュメントおよび/またはその他の資料に複製する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>3. CodePlex Foundationの名前もその貢献者の名前も、書面による事前の許可なしに、このソフトウェアから派生した製品を推奨または宣伝するために使用することはできません。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、著作権者および寄稿者によって「現状のまま」提供され、商品性および特定の目的への適合性の黙示的な保証を含むがこれに限定されない明示的または黙示的な保証は放棄されます。いかなる場合においても、著作権所有者または貢献者は、直接的、間接的、偶発的、特別、例示的、または結果的な損害代替品またはサービスの調達、代替品、データ、または利益の損失を含むが、これらに限定されないについて責任を負わないものとしますまたはビジネス中断責任の理論、または契約、厳格な責任、または不法行為過失またはその他を含むにかかわらず、このソフトウェアの使用から生じたものであっても、POSSIの可能性がある場合でも。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>2.OpenSSL OpenSSLおよびSSLeayライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="http://www.openssl.org/source/license.html">http://www.openssl.org/source/license.html</a> </span>
</p>
<p class="MsoNormal">
<span>Copyrightc1998-2011 The OpenSSL Project。全著作権所有。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>ソースおよびバイナリ形式での再配布および使用は、変更の有無にかかわらず、次の条件が満たされている場合に許可されます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>1.ソースコードの再配布には、上記の著作権表示、この条件リスト、および以下の免責事項を保持する必要があります。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>2.バイナリ形式での再配布では、上記の著作権表示、この条件リスト、および以下の免責事項を、配布物とともに提供されるドキュメントおよび/またはその他の資料に複製する必要があります。 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>3.このソフトウェアの機能または使用について言及するすべての広告資料には、「この製品には、OpenSSL Toolkitで使用するためにOpenSSL Projectによって開発されたソフトウェアが含まれます。http://www.openssl.org/)」 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>4.「OpenSSL Toolkit」および「OpenSSL Project」という名前は、事前の書面による許可なしに、このソフトウェアから派生した製品を推奨または宣伝するために使用しないでください。書面による許可については、openssl-core @ openssl.orgにお問い合わせください。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>5.このソフトウェアから派生した製品は、OpenSSL Projectの事前の書面による許可なしに、「OpenSSL」と呼ばれたり、名前に「OpenSSL」が表示されたりすることはありません。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>6.いかなる形式の再配布でも、「この製品には、OpenSSL Toolkithttp://www.openssl.org/で使用するためにOpenSSL Projectによって開発されたソフトウェアが含まれます」という承認を保持する必要があります。 <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、OpenSSLプロジェクトによって「現状のまま」提供され、商品性および特定の目的への適合性の黙示的な保証を含むがこれに限定されない、明示的または黙示的な保証は放棄されます。いかなる場合も、OpenSSLプロジェクトまたはその貢献者は、直接的、間接的、偶発的、特別、例示的、または結果的損害責任を含むが、特別損害、例示的損害、または結果的損害を含むの責任を負いませんまたはサービス、使用、データ、または利益の損失、またはビジネス中断、契約、厳格な責任、または不法行為過失またはその他を含むこのような損害の可能性について通知された場合でも、ソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>3. jQuery Foundation-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyright 2013 jQuery Foundationおよびその他の貢献者 <a href="http://jquery.com/">http://jquery.com/</a></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。</span>
</p>
<p class="MsoNormal">
<b><span>4. jQueryユーザーインターフェイス-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>Copyright 2013 jQuery Foundationおよびその他の貢献者、 <a href="http://jqueryui.com/">http://jqueryui.com/</a></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアは、多くの個人による自発的な貢献で構成されていますAUTHORS.txt、http//jqueryui.com/about。正確な貢献履歴については、http//jquery-ui.googlecode.com/svn/にある改訂履歴とログをご覧ください <o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>5. noVNC-Mozilla Public License 2.0</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="https://github.com/kanaka/noVNC/blob/master/LICENSE.txt">https://github.com/kanaka/noVNC/blob/master/LICENSE.txt</a></span>
</p>
<p class="MsoNormal">
<span>CopyrightC2011 Joel Martinこのソースコードフォームには、Mozilla Public License v。2.0の条件が適用されます。 MPLのコピーがこのファイルとともに配布されていない場合は、http//mozilla.org/MPL/2.0/から入手できます。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>6.Rcarousel-MITライセンス</span></b><span style="font-size:10.0pt;font-family:&quot;Courier New&quot;;mso-fareast-font-family:&quot;Times New Roman&quot;"><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span><a href="https://github.com/ryrych/rcarousel/blob/master/widget/license">https://github.com/ryrych/rcarousel/blob/master/widget/license</a></span>
</p>
<p class="MsoNormal">
<span>Copyrightc2010 Wojciech 'RRH' Ryrych<o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>本ソフトウェアは、商品性、特定の目的への適合性、および非侵害の保証を含むが、これに限らず、明示または黙示を問わず、いかなる保証もなしに「現状のまま」提供されます。いかなる場合でも、作者または著作権者は、契約、不法行為、またはその他の行為、ソフトウェアまたは使用またはその他の取引に起因する、または関連するいかなる請求、損害またはその他の責任についても責任を負わないものとしますソフトウェア。<o:p></o:p></span>
</p>
<p class="MsoNormal">
<b><span>7.Webtoolkit Javascript Base 64 Creative Commons Attribution 2.0 UKライセンス</span></b><span><o:p></o:p></span>
</p>
<p class="MsoNormal">
<span>このソフトウェアはからのコードを使用します <a href="http://www.webtoolkit.info/javascript-base64.html">http://www.webtoolkit.info/javascript-base64.html</a> の下でライセンス <a href="http://creativecommons.org/licenses/by/2.0/uk/legalcode">http://creativecommons.org/licenses/by/2.0/uk/legalcode</a> そのソースはからダウンロードできます <a href="http://www.webtoolkit.info/javascript-base64.html">http://www.webtoolkit.info/javascript-base64.html</a>。<o:p></o:p></span>
</p>
<br>
</div>
<div id="footer">
<table cellpadding="0" cellspacing="10" style="width: 100%">
<tbody><tr>
<td style="text-align:left"></td>
<td style="text-align:right"><a href="/">バック</a></td>
</tr>
</tbody></table>
</div>
</div>
<script>
'use strict';
var uiMode = parseInt(getstore('uiMode', 1));
var webPageStackMenu = false;
var webPageFullScreen = true;
var nightMode = (getstore('_nightMode', '0') == '1');
var logoutControls = {{{logoutControls}}};
var terms = '{{{terms}}}';
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
QV('column_l', true);
userInterfaceSelectMenu();
// Setup logout control
var logoutControl = '';
if (logoutControls.name != null) { logoutControl = format("{0}へようこそ。", logoutControls.name); }
if (logoutControls.logoutUrl != null) { logoutControl += format(' <a href=\"' + logoutControls.logoutUrl + '\" style="color:white">' + "ログアウト" + '</a>'); }
QH('logoutControl', logoutControl);
// Toggle user interface menu
function showUserInterfaceSelectMenu() {
Q('uiViewButton1').classList.remove('uiSelectorSel');
Q('uiViewButton2').classList.remove('uiSelectorSel');
Q('uiViewButton3').classList.remove('uiSelectorSel');
Q('uiViewButton4').classList.remove('uiSelectorSel');
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
QV('uiMenu', (QS('uiMenu').display == 'none'));
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
}
function userInterfaceSelectMenu(s) {
if (s) { uiMode = s; putstore('uiMode', uiMode); }
webPageFullScreen = (uiMode < 3);
webPageStackMenu = true;//(uiMode > 1);
toggleFullScreen(0);
toggleStackMenu(0);
QC('column_l').add('room4submenu');
}
function toggleNightMode() {
nightMode = !nightMode;
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
putstore('_nightMode', nightMode ? '1' : '0');
}
// Toggle the web page to full screen
function toggleFullScreen(toggle) {
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
var hide = 0;
//if (args.hide) { hide = parseInt(args.hide); }
if (webPageFullScreen == false) {
QC('body').remove('menu_stack');
QC('body').remove('fullscreen');
QC('body').remove('arg_hide');
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
//QV('UserDummyMenuSpan', false);
//QV('page_leftbar', false);
} else {
QC('body').add('fullscreen');
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
//QV('page_leftbar', true);
}
QV('body', true);
}
// If FullScreen, toggle menu to be horisontal or vertical
function toggleStackMenu(toggle) {
if (webPageFullScreen == true) {
if (toggle === 1) {
webPageStackMenu = !webPageStackMenu;
putstore('webPageStackMenu', webPageStackMenu);
}
if (webPageStackMenu == false) {
QC('body').remove('menu_stack');
} else {
QC('body').add('menu_stack');
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
}
}
}
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
</script>
</body></html>