本示例使用的设备:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Serial串口读写器示例 </title>
<script>
window.onload = function() {
document.getElementById('butt_openserial').hidden=true;
document.getElementById('butt_closeserial').hidden=true;
}
if ('serial' in navigator){
}else{
alert('您的浏览器不支持 Web Serial API,暂无法使用以下功能!');
}
navigator.serial.onconnect =function event(){
console.log("Serial port connected: ", event.target);
}
navigator.serial.ondisconnect =function event(){
console.log("Serial port disconnected: ", event.target);
}
var BLOCK0_EN = 0x01;//读第一块的(16个字节)
var BLOCK1_EN = 0x02;//读第二块的(16个字节)
var BLOCK2_EN = 0x04;//读第三块的(16个字节)
var NEEDSERIAL = 0x08;//仅读指定序列号的卡
var EXTERNKEY = 0x10;//用明码认证密码,产品开发完成后,建议把密码放到设备的只写区,然后用该区的密码后台认证,这样谁都不知道密码是多少,需要这方面支持请联系
var NEEDHALT = 0x20; //读/写完卡后立即休眠该卡,相当于这张卡不在感应区。要相重新操作该卡必要拿开卡再放上去
var port = null;
var reader = null;
var reading = false;
const getdata=new Uint8Array(1000); //接收串口返回的数据
var DataPoint=0; //接收数据指针
var SendCode=0; //已发送的指令代码
function isUIntNum(val) {
var testval = /^\d+$/; // 非负整数
return (testval.test(val));
}
function isHex(val) {
var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断
return (testval.test(val));
}
async function SelectSerial(){
try{
port =await navigator.serial.requestPort(); // 弹出系统串口列表对话框,选择一个串口进行连接
ports =await navigator.serial.getPorts(); // 获取已连接的授权过的设备列表
document.getElementById('butt_openserial').hidden=false;
}
catch (e)
{
console.log(e);
}
}
function updateInputData(data) {
let array = new Uint8Array(data); // event.data.buffer就是接收到的inputreport包数据了
//let hexstr = "";
for (const data of array) {
//hexstr += (Array(2).join(0) + data.toString(16).toUpperCase()).slice(-2) + " "; // 将字节数据转换成(XX )形式字符串
getdata[DataPoint]=data;
DataPoint=DataPoint+1;
}
var crc=0;
for(i=1;i<DataPoint;i++){ //校验接收数据,同时也解决数据分包上传的问题
crc=crc^getdata[i];
}
if (crc==0 && DataPoint>1){
let hexstr = "";
for (i=0;i<DataPoint;i++){
hexstr=hexstr+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
ReceiveData.value += hexstr;
var dispstr="";
var cardnohex="";
var datahex="";
switch (SendCode) {
case 1:
break;
case 2: //读取M1卡序列号的回应
case 3: //读取M1卡扇区数据的回应
case 4: //写M1卡扇区数据的回应
case 5: //修改M1卡扇区数密钥的回应
switch (getdata[0]){
case 1: //返回有效数据长度为1
switch (getdata[1]){
case 8:
dispstr = "未寻到卡!" ;
break;
case 9:
dispstr = "两张以上卡片同时在感应区,发生冲突!" ;
break;
case 10:
dispstr = "无法选择激活卡片!" ;
break;
case 11:
dispstr = "密码装载失败,卡片序列号已知!" ;
break;
default:
dispstr = "操作卡失败,返回代码:" + getdata[1].ToString() ;
break;
}
var label_disp = document.getElementById('label_disp');
label_disp.innerText = dispstr;
break;
case 5: //返回有效数据长度为5
for(i=2;i<6;i++){
cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();
}
if(SendCode==2){
dispstr ="读卡序列号";
}else if(SendCode==3){
dispstr ="读扇区数据";
}else if(SendCode==4){
dispstr ="写扇区数据";
}else if(SendCode==5){
dispstr ="修改扇区密码";
}
switch (getdata[1]){
case 0:
dispstr=dispstr+"成功!卡号:"+cardnohex
break;
case 1:
dispstr = dispstr+",密码认证成功,但读写扇区内容失败!卡号:" + cardnohex;
break;
case 2:
dispstr = dispstr+",第0块操作成功,但第1、2块操作失败,仅扇区内容前16个字节的数据有效!!卡号:" + cardnohex;
break;
case 3:
dispstr = dispstr+",第0、1块操作成功,但第2块操作失败,仅扇区内容前32个字节的数据有效!!卡号:" + cardnohex;
break;
case 12:
dispstr = dispstr+",密码认证失败,卡号:" + cardnohex;
break;
default:
dispstr = dispstr+",操作卡失败,返回代码:" + getdata[1].ToString() ;
break;
}
var label_disp = document.getElementById('label_disp');
label_disp.innerText = dispstr;
break;
case 53: //返回有效数据长度为53
for(i=2;i<6;i++){
cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();
}
dispstr = "读M1卡扇区数据成功,卡号:" + cardnohex;
for(i=6;i<DataPoint-1;i++){
datahex=datahex+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
var label_disp = document.getElementById('label_disp');
label_disp.innerText = dispstr;
RWM1Data.value=datahex;
break;
case 54: //旧版本设备返回有效数据长度为54
for(i=2;i<6;i++){
cardnohex=cardnohex+getdata[i].toString(16).padStart(2, '0').toUpperCase();
}
dispstr = "读M1卡扇区数据成功,卡号:" + cardnohex;
for(i=7;i<DataPoint-1;i++){
datahex=datahex+getdata[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
var label_disp = document.getElementById('label_disp');
label_disp.innerText = dispstr;
RWM1Data.value=datahex;
break;
}
break;
}
DataPoint=0;
}
}
async function listenReceived(){
if (reading){
console.log("On reading.");
return;
}
reading=true;
await port.close(); // 关闭串口
port = null;
alert("串口已关闭!");
}
async function OpenSerial(){
if (port==null){
alert('请先选择要操作的串口号!');
return;
}else{
document.getElementById('butt_closeserial').hidden=false;
var baudSelected = parseInt(document.getElementById("select_btn").value);
await port.open({
baudRate: baudSelected,
});
listenReceived();
alert('串口打开成功!');
}
}
async function CloseSerial(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
if (reading) {
reading = false;
reader?.cancel();
}
}
async function beep(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
var beepdelay=parseInt(document.getElementById("beepdelay").value);
const outputData = new Uint8Array(5);
outputData[0]=0x03;
outputData[1]=0x0f;
outputData[2]=beepdelay % 256;
outputData[3]=beepdelay / 256;
outputData[4]=outputData[1] ^ outputData[2] ^outputData[3];
var sendhex="";
for(i=0;i<5;i++){
sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
SendCode=1;
DataPoint=0;
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function Request(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
const outputData = new Uint8Array(3);
outputData[0]=0x01; //指令长度
outputData[1]=0xf0; //功能码
outputData[2]=0xf0; //校验码
var sendhex="";
for(i=0;i<3;i++){
sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
SendCode=2;
DataPoint=0;
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "";
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function ReadM1Card(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
if (selinoutkey.selectedIndex==1){
myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY; //外部密钥认证
}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;} //已装载到发卡器内部密钥认证
myareano = selareano.selectedIndex; //指定为本次读取第8区,十进制
authmode = selauthmode.selectedIndex; //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证
mypiccserial = "00000000"; //指定本次操作的卡序列号,十六进制,未知时可指定为8个0
mypicckey = authkey0.value.trim(); //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码
if (!isHex(mypicckey) || mypicckey.length!=12) {
textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";
authkey0.focus();
authkey0.select();
return;
}
const outputData = new Uint8Array(16);
outputData[0]=0x0e; //指令长度
outputData[1]=0x78; //功能码
outputData[2]=myctrlword; //控制位
outputData[3]=0x00; //四字节本次操作卡卡号,全部取0表示可操作任意卡
outputData[4]=0x00;
outputData[5]=0x00;
outputData[6]=0x00;
outputData[7]=myareano; //扇区号
outputData[8]=authmode; //密钥认证方式
for(i=0;i<6;i++){ //6字节密钥
outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);
}
var crc=0;
for (i=1;i<15;i++){
crc=crc^outputData[i];
}
outputData[15]=crc;
var sendhex="";
for(i=0;i<16;i++){
sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
RWM1Data.value="";
SendCode=3;
DataPoint=0;
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "";
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function WriteM1Card(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
if (selinoutkey.selectedIndex==1){
myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY; //外部密钥认证
}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;} //已装载到发卡器内部密钥认证
myareano = selareano.selectedIndex; //指定为本次读取第8区,十进制
authmode = selauthmode.selectedIndex; //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证
mypiccserial = "00000000"; //指定本次操作的卡序列号,十六进制,未知时可指定为8个0
mypicckey = authkey0.value.trim(); //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码
if (!isHex(mypicckey) || mypicckey.length!=12) {
textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";
authkey0.focus();
authkey0.select();
return;
}
mypiccdata=RWM1Data.value.trim();
mypiccdata=mypiccdata.replace(/\s/g, "");
if (isHex(mypiccdata)){
if(mypiccdata.length<96){
if (confirm("写卡数据不足一扇区48个字节,是否要后面补0写入?")) {
while (mypiccdata.length<96){
mypiccdata=mypiccdata+"0";
}
}else{
return;
}
}
}else{
alert("请输入96位16进制写卡数据!");
return;
}
const outputData = new Uint8Array(64);
outputData[0]=0x3e; //指令长度
outputData[1]=0x69; //功能码
outputData[2]=myctrlword; //控制位
outputData[3]=0x00; //四字节本次操作卡卡号,全部取0表示可操作任意卡
outputData[4]=0x00;
outputData[5]=0x00;
outputData[6]=0x00;
outputData[7]=myareano; //扇区号
outputData[8]=authmode; //密钥认证方式
for(i=0;i<6;i++){ //6字节密钥
outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);
}
for(i=0;i<48;i++){ //48字节写卡数据
outputData[15+i]=parseInt(mypiccdata.substr(i*2,2),16);
}
var crc=0;
for (i=1;i<63;i++){
crc=crc^outputData[i];
}
outputData[63]=crc;
var sendhex="";
for(i=0;i<64;i++){
sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
SendCode=4;
DataPoint=0;
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "";
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
async function changecardkeyex(){
if ((port == null) || (!port.writable)) {
alert("请选择并打开与发卡器相连的串口!");
return;
}
if (selinoutkey.selectedIndex==1){
myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY; //外部密钥认证
}else {myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;} //已装载到发卡器内部密钥认证
myareano = selareano.selectedIndex; //指定为本次读取第8区,十进制
authmode = selauthmode.selectedIndex; //指定密码模式,十进制,大于0表示用A密码认证,推荐用A密码认证
mypiccserial = "00000000"; //指定本次操作的卡序列号,十六进制,未知时可指定为8个0
mypicckey = authkey0.value.trim(); //指定卡片密码,十六进制,FFFFFFFFFFFF为卡片厂家出厂密码
if (!isHex(mypicckey) || mypicckey.length!=12) {
textarea.value = "认证密钥输入错误,请输入正确的12位16进制认证密钥!";
authkey0.focus();
authkey0.select();
return;
}
mypicckeyA = newkeya.value.trim(); //新A密钥
if (!isHex(mypicckeyA) || mypicckeyA.length!=12) {
textarea.value = "新A密钥输入错误,请输入正确的12位16进制新A密钥!";
newkeya.focus();
newkeya.select();
return;
}
mypiccctr = cardctr.value.trim(); //新控制位,出厂为FF078069,
if (!isHex(mypiccctr) || mypiccctr.length!=8) {
textarea.value = "新控制位输入错误,请输入正确的8位16进制控制位!";
cardctr.focus();
cardctr.select();
return;
}
mypicckeyB = newkeyb.value.trim(); //新B密钥
if (!isHex(mypicckeyB) || mypicckeyB.length!=12) {
textarea.value = "新B密钥输入错误,请输入正确的12位16进制新B密钥!";
newkeyb.focus();
newkeyb.select();
return;
}
mypicckey_new=mypicckeyA+mypiccctr+mypicckeyB;
switch (selchangekey.selectedIndex){
case 0:
mypicckey_new=mypicckey_new+"00";
break;
case 1:
mypicckey_new=mypicckey_new+"02";
break;
default:
mypicckey_new=mypicckey_new+"03";
break;
}
const outputData = new Uint8Array(33);
outputData[0]=0x1f; //指令长度
outputData[1]=0xf1; //功能码
outputData[2]=myctrlword; //控制位
outputData[3]=0x00; //四字节本次操作卡卡号,全部取0表示可操作任意卡
outputData[4]=0x00;
outputData[5]=0x00;
outputData[6]=0x00;
outputData[7]=myareano; //扇区号
outputData[8]=authmode; //密钥认证方式
for(i=0;i<6;i++){ //6字节密钥
outputData[9+i]=parseInt(mypicckey.substr(i*2,2),16);
}
for(i=0;i<17;i++){ //6字节新A钥+4字节控制位+6字节新B钥+1字节密钥修改类型
outputData[15+i]=parseInt(mypicckey_new.substr(i*2,2),16);
}
var crc=0;
for (i=1;i<32;i++){
crc=crc^outputData[i];
}
outputData[32]=crc;
var sendhex="";
for(i=0;i<33;i++){
sendhex=sendhex+outputData[i].toString(16).padStart(2, '0').toUpperCase()+" ";
}
SendData.value=sendhex;
ReceiveData.value="";
SendCode=5;
DataPoint=0;
var label_disp = document.getElementById('label_disp');
label_disp.innerText = "";
const writer = port.writable.getWriter();
await writer.write(outputData); // 发送数据
writer.releaseLock();
}
</script>
<style>
th {
font-family:楷体;
background-color:#F6FAFF;
color:blue;
}
td {
font-family:楷体;
background-color:#F6FAFF;
}
</style>
</head>
<body>
<table width="950" height="423" align="center">
<tr>
<td width="120" height="50">
<input name="btnSelect" type="submit" id="btnSelect" style="width:100%" onclick="SelectSerial()" value="选择串口" />
</td>
<td width="800">波特率:<label for="select_btn"></label>
<select name="select_btn" id="select_btn">
<option>1200</option>
<option>4800</option>
<option>9600</option>
<option>14400</option>
<option selected="selected">19200</option>
<option>38400</option>
<option>43000</option>
<option>57600</option>
<option>115200</option>
<option>128000</option>
<option>230400</option>
<option>256000</option>
<option>460800</option>
<option>921600</option>
<option>1382400</option>
</select>
数据位:
<select name="select_btn2" id="select_data">
<option>8</option>
<option>7</option>
<option>6</option>
<option>5</option>
</select>
停止位:
<select name="select_btn3" id="select_stop">
<option>1</option>
<option>1.5</option>
<option>2</option>
</select>
校验位:
<select name="select_btn4" id="select_mark">
<option>None 无</option>
<option>Odd 奇</option>
<option>Even 偶</option>
<option>Mask 常1</option>
<option>Space 常0</option>
</select>
<input name="butt_openserial" type="submit" id="butt_openserial" style="width:80px" onclick="OpenSerial()" value="打开串口" />
<input name="butt_closeserial" type="submit" id="butt_closeserial" style="width:80px" onclick="CloseSerial()" value="关闭串口" />
</td>
</tr>
<tr>
<td height="36" >
<input name="butt_beep" type="submit" id="butt_beep" style="width:100%" onclick="beep()" value="驱动发卡器响声" />
</td>
<td>响声延时:
<input style="color:blue;text-align:center;" name="beepdelay" type="text" id="beepdelay" value="30" size="5" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
毫秒</td>
</tr>
<tr>
<td height="36"><input name="butt_request" type="submit" id="butt_request" style="width:100%" onclick="Request()" value="仅读取M1卡序列号" /></td>
<td><label style="color:blue;" name="label_disp" id="label_disp"></label></td>
</tr>
<tr>
<td height="36"><input name="butt_readm1" type="submit" id="butt_readm1" style="width:100%" onclick="ReadM1Card()" value="读取M1卡扇区数据" /></td>
<td><p>扇区号:
<select style="color:blue;" name="selareano" id="selareano">
<option selected="selected">第0扇区</option>
<option>第1扇区</option>
<option>第2扇区</option>
<option>第3扇区</option>
<option>第4扇区</option>
<option>第5扇区</option>
<option>第6扇区</option>
<option>第7扇区</option>
<option>第8扇区</option>
<option>第9扇区</option>
<option>第10扇区</option>
<option>第11扇区</option>
<option>第12扇区</option>
<option>第13扇区</option>
<option>第14扇区</option>
<option>第15扇区</option>
</select>
<label for="changeauthkey"></label>
<select style="color:blue;" name="selinoutkey" id="selinoutkey">
<option>内部密钥认证</option>
<option selected="selected">外部密钥认证</option>
</select>
<label for="newkey"></label>
<select style="color:blue;" name="selauthmode" id="selauthmode">
<option>B密钥认证</option>
<option selected="selected">A密钥认证</option>
</select>
,认证密钥:
<label for="authkey0"></label>
<input style="color:blue;text-align:center;" name="authkey0" type="text" id="authkey0" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>
</p>
</td>
</tr>
<tr>
<td height="69"><input name="butt_writem1" type="submit" id="butt_writem1" style="width:100%" onclick="WriteM1Card()" value="写数据到M1卡扇区" /></td>
<td><textarea style="width:800px;color:red;" name="RWM1Data" id="RWM1Data" cols="100" rows="4" ></textarea></td>
</tr>
<tr>
<td height="36"><input style="width:100%" name="butt_changecardkeyex" type="submit" id="butt_changecardkeyex" onclick="changecardkeyex()" value="修改M1卡扇区密钥" /></td>
<td><select style="color:blue;" name="selchangekey" id="selchangekey">
<option>只修改A密钥</option>
<option>只修改AB密钥</option>
<option selected="selected">修改AB密钥及控制位</option>
</select>
,新A密钥
<input style="color:red;text-align:center;" name="newkeya" type="text" id="newkeya" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>
,控制位
<input style="color:red;text-align:center;" name="cardctr" type="text" id="cardctr" value="FF078069" size="8" maxlength="8" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>
,B密钥
<input style="color:red;text-align:center;" name="newkeyb" type="text" id="newkeyb" value="FFFFFFFFFFFF" size="12" maxlength="12" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></td>
</tr>
<tr>
<td height="70" scope="row"><p align="center">发送的数据</p></td>
<td><textarea style="width:800px;color:blue;" name="SendData" id="SendData" cols="100" rows="4" ></textarea></td>
</tr>
<tr>
<td height="70" scope="row"><p align="center">接收的数据</p></td>
<td><textarea style="width:800px" name="ReceiveData" id="ReceiveData" cols="100" rows="4" ></textarea></td>
</tr>
</table>
</body>
</html>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
- 376.
- 377.
- 378.
- 379.
- 380.
- 381.
- 382.
- 383.
- 384.
- 385.
- 386.
- 387.
- 388.
- 389.
- 390.
- 391.
- 392.
- 393.
- 394.
- 395.
- 396.
- 397.
- 398.
- 399.
- 400.
- 401.
- 402.
- 403.
- 404.
- 405.
- 406.
- 407.
- 408.
- 409.
- 410.
- 411.
- 412.
- 413.
- 414.
- 415.
- 416.
- 417.
- 418.
- 419.
- 420.
- 421.
- 422.
- 423.
- 424.
- 425.
- 426.
- 427.
- 428.
- 429.
- 430.
- 431.
- 432.
- 433.
- 434.
- 435.
- 436.
- 437.
- 438.
- 439.
- 440.
- 441.
- 442.
- 443.
- 444.
- 445.
- 446.
- 447.
- 448.
- 449.
- 450.
- 451.
- 452.
- 453.
- 454.
- 455.
- 456.
- 457.
- 458.
- 459.
- 460.
- 461.
- 462.
- 463.
- 464.
- 465.
- 466.
- 467.
- 468.
- 469.
- 470.
- 471.
- 472.
- 473.
- 474.
- 475.
- 476.
- 477.
- 478.
- 479.
- 480.
- 481.
- 482.
- 483.
- 484.
- 485.
- 486.
- 487.
- 488.
- 489.
- 490.
- 491.
- 492.
- 493.
- 494.
- 495.
- 496.
- 497.
- 498.
- 499.
- 500.
- 501.
- 502.
- 503.
- 504.
- 505.
- 506.
- 507.
- 508.
- 509.
- 510.
- 511.
- 512.
- 513.
- 514.
- 515.
- 516.
- 517.
- 518.
- 519.
- 520.
- 521.
- 522.
- 523.
- 524.
- 525.
- 526.
- 527.
- 528.
- 529.
- 530.
- 531.
- 532.
- 533.
- 534.
- 535.
- 536.
- 537.
- 538.
- 539.
- 540.
- 541.
- 542.
- 543.
- 544.
- 545.
- 546.
- 547.
- 548.
- 549.
- 550.
- 551.
- 552.
- 553.
- 554.
- 555.
- 556.
- 557.
- 558.
- 559.
- 560.
- 561.
- 562.
- 563.
- 564.
- 565.
- 566.
- 567.
- 568.
- 569.
- 570.
- 571.
- 572.
- 573.
- 574.
- 575.
- 576.
- 577.
- 578.
- 579.
- 580.
- 581.
- 582.
- 583.
- 584.
- 585.
- 586.
- 587.
- 588.
- 589.
- 590.
- 591.
- 592.
- 593.
- 594.
- 595.
- 596.
- 597.
- 598.
- 599.
- 600.
- 601.
- 602.
- 603.
- 604.
- 605.
- 606.
- 607.
- 608.
- 609.
- 610.
- 611.
- 612.
- 613.
- 614.
- 615.
- 616.
- 617.
- 618.
- 619.
- 620.
- 621.
- 622.
- 623.
- 624.
- 625.
- 626.
- 627.
- 628.
- 629.
- 630.
- 631.
- 632.
- 633.
- 634.
- 635.
- 636.
- 637.
- 638.
- 639.
- 640.
- 641.
- 642.
- 643.
- 644.
- 645.
- 646.
- 647.
- 648.
- 649.
- 650.
- 651.
- 652.
- 653.
- 654.
- 655.
- 656.
- 657.
- 658.