|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于单片机+lcd12864的英文记事本程序设计
( w* {1 L2 e/ w) K8 P! ~& W% `
$ @4 E. D- U% a- q! w, ~7 c B, w+ C+ M4 ~- g- Y" Z/ W3 M- Z
系统通电后,要输入6位的密码才能进入系统。进入系统后,可以输入英文文章。即系统按键具有数字、标点符号、大小写字母、空格,回车等字符输入功能。附加功能为进入系统后,密码可以用按键更改;输入的文章,液晶界面显示满之后,能够分页切换,并且具有保存、清楚功能。
. j6 k1 ^: i H4 G, Z# v/ I- A9 y: Z
单片机源程序如下:2 d. o) D6 i% W6 H
/**% f" |- Z9 Z! C' H: g2 G
* note.c, j9 G: y( S! p S
*
- F, r- S7 V0 P * Created At: 2018-12-17
8 {+ w1 [ i2 V: Q0 e * Author: yowfung
2 D/ d; s6 n0 t/ [ * Description: 英文记事本程序$ G2 H$ S6 j5 O
*/+ B1 f0 i" F r
~/ D! c- o7 P #include <reg52.h>& E* j1 F2 G( f( N& D j: E5 x
#include "../inc/public.h"
4 Z$ x7 ^' o$ S* \7 E- ` #include "../inc/lcd12864.h"
3 t* e( I! Q3 T+ `) ^ #include "../inc/keys.h"; K9 N0 ], @9 |6 _" s2 [* |3 a/ i' W1 \
) Q4 l9 H4 \8 z7 q; g2 w+ ]
6 A( z( v* i! S$ t0 t0 F
/**
4 R: g& i/ w; X+ S8 ~2 n- q3 o% o' I * 定义常量
; O n6 ] G1 m& b" T% ] */5 U! A" J% g* ^" [' S1 s& @# a
const unsigned char PASSWORD_CONTENT[7] = "yowfung"; // 登录密码8 c! h, `( l3 N9 m7 O% F
const unsigned char PASSWORD_LENGTH = 7; // 密码长度
4 I3 i: r% |! D6 Z" k+ H& H! e+ {9 m# q) G/ t4 t( S
/**: T( I: U3 W) f* e# Y# E3 a7 m( ~& p
* 声明函数 g* _4 ^ ~( g! e$ K* K+ n0 `
*/, e; w7 M5 z8 a/ z4 l
bit ValidatePassword();
+ y+ F+ M" m2 B1 G) svoid Editor(void);
8 a$ o! N$ W4 c3 vvoid insCharToStr(unsigned char *str, unsigned char ch, unsigned int index);
' l( y- e4 X8 W; i6 i) P2 ?void delChaRFromStr(unsigned char *str, unsigned int index);% P! h+ Z3 I/ D) }8 _. a, k
void WriteContent(unsigned char *content, unsigned char length);8 _2 k. ?$ s; y4 J/ A
void setLcdPos(unsigned char pos);( I" ^6 L- l' d3 m& I, S
. h6 D+ G/ C U3 u% w$ ?& \) l0 U+ u+ a; N/ [5 u* \, x
/**
$ k; J$ F# Z" ]3 {4 V! F6 I) e * 英文记事本程序运行. |" X9 @" p0 p
*
* i9 L; G2 M$ v7 N' }. e * 需要连接的线路:( N' ]9 P5 L" _! [. t
* 1. LCD12864电路: RS -> P0.0
* P! [1 V! }7 P3 l6 d6 t$ D8 f * RW -> P0.1
$ N$ b# Q) b3 u! S9 Z* p, c0 E * E -> P0.2) S* i1 q" }- n2 H. L( ]# K4 _
* D0~D7 -> P1.0~1.7
- C9 {9 N) G/ z0 \5 [& r6 Z T7 w * 2. 矩阵按键电路: Row1~9 -> P2.0~2.7,P0.7! |$ m6 N/ A, a ~! c& u; S
* Col1~6 -> P3.2~3.7
`: d0 |8 S& E5 S. }: U * 3. Shift状态灯电路:LED -> P0.3
: a. y4 e$ U8 g! _* c *
9 W {5 G; C! k6 J$ w * 功能及流程描述:
- l% x3 x- C6 w! R3 Z * 1. 运行后LCD上第一行显示“Hello YowFung”,第二行显示“NoteBook”;
: _, }% T" Y* f- Y, [6 S) D * 2. 5秒后出现密码输入界面,通过按键输入六位数密码,然后按Enter键,密码
7 L3 W$ B) m; X4 p! b( s, U3 Z) W# J * 正确则进入编辑状态,否则显示“Password Error!”3秒并回到密码输入 ~; u+ V& w' Y/ l/ ~# J! z2 q; t2 g
* 界面;% _. Y; x; V" V: x+ P+ Y: O
* 3. 在编辑状态中,通过按键输入字符,每输入一个字符光标向右移动一位,当8 A4 c2 {. S8 S& E
* 一行显示满了后,则在下一行显示,当一个屏幕都显示满了后,则可以通过) N0 y# @, ]( j# ~9 ] ~5 @% }" y
* 按 Up 或 Down 键来滚动屏幕;
C* ^7 U6 l' U c' v' {/ w * 4. 按 ← 或 → 键可以左右移动光标;6 L l9 U* z0 i5 j. m2 |# w) L4 Y( }
* 5. 按 Clear 键可以清屏; k& o6 v4 e+ C
* 6. 按 Del 键可以删除当前光标左边的一个字符;) q3 y9 L0 z; v+ s" d3 X. P
* 7. 按下 Shift 键时,Shift 状态 LED 灯被点亮,此时输入的字符为第二字. c5 E1 `. P2 E6 p1 z' T
* 符,再按一次 Shift 键,LED 灭,回到第一字符输入状态。* Z+ K9 D( D2 Q' z* r
*/
$ |1 B [5 W! I2 I& kvoid note_run(void) ]; V7 V' S+ J
{, Q; @ V' L3 n6 m7 @, C
bit vali_res = 0;( d' }- {, W( q
3 [6 T7 f8 Z' Z5 m // 初始化 LCD128648 w& n: t& B, a; u Z* B& D) i: x
Lcd12864_init();% m5 ]9 J" d$ h/ Y# U) w' K8 ]; |
# |$ I# O# f v# ?, F& s; N' G // 显示欢迎界面3 R7 p: l# ]2 v8 O3 V
Lcd12864_wrLine(2, " Hello YowFung");7 V2 l) x% x* J, {# Q6 e$ W
Lcd12864_wrLine(3, " NoteBook");8 ^ |) t, K, V" j; I, \% M) w
delay(3000);
* x7 y9 d1 ~; M( a" F) T- ~7 E1 o* ` o
8 t5 ?3 w: Y) b( H // 输入登录密码,直到密码正确, m8 M2 ~; ]9 D& ^/ U8 J# U
do {
) [% Y/ c4 k+ d. k9 ^ // 清屏3 r" Y8 E; C$ Q
Lcd12864_cls();3 u& F' D6 S2 u$ r/ V( R: R2 A; t
delay(500);2 _) A: T5 t* H3 c9 h2 A; O
' \2 j2 D# E' T' [! C
// 输入密码并验证
/ e! t( S0 u: v vali_res = ValidatePassword();
7 T/ p6 L- q* m6 e) [8 o: S& Q- q/ t& q: r
// 如果密码错误则显示错误信息# r5 ^8 c) ~" c9 c+ L/ ~
if (vali_res == 0) {8 ~* t# W% _0 C8 x( A5 t, g
Lcd12864_cls();
- y2 n |& {$ U6 ` Lcd12864_showCursor(0);; u* b+ }' `3 K- p; X/ E! N% H
Lcd12864_wrLine(2, "Password Error,");
i" V9 f- I+ ?- }. v8 l Lcd12864_wrLine(3, "Input Again!");
- H" n6 q4 n! b delay(2000);' y- Z) p5 X ~: t$ z {3 |
}
% s* a+ H) e7 e* ^! B } while (vali_res == 0);1 O1 @, x8 l+ w3 a3 t
$ t7 f/ P/ y* K% B6 W
// 密码输入正确,显示欢迎信息
. J1 Q! W7 P+ A6 I& ?# |$ z Lcd12864_cls();
! A* ^: s7 H7 N* \ Lcd12864_showCursor(0);" E; O& @! M* i& {9 ]1 _, o7 i' c1 i' q7 d
Lcd12864_wrLine(2, " Welcome Back!");# ?( r! ?0 J4 L
delay(2000);) ^. z) ]8 Z, y. y8 X) ~1 z8 |. Z
. G) A' J( H/ b5 \: p8 p1 ] // 进入编辑界面
. _. I; @; x5 p0 g( t3 }* ` Editor();
4 v# \/ q4 b6 k3 Y3 d: o( A while(1);' J3 m/ s7 w0 I, h2 K
}) {0 [ }2 k" S( i" P0 l
4 c9 |* D1 |# i. a, N/**
% T. L- x* ]( Z2 O! K- v * 检测登录密码输入并验证+ l# w' O8 Y! w) p( G
*
) d+ w9 b( h1 D) p# F8 u) D! x( B; \ */
a: Z0 U8 T* {bit ValidatePassword()3 \: ^4 ], q- `2 i" p5 \
{
6 g. C2 A) U: s6 d0 l9 {0 l9 Z) r& h unsigned char input, length = 0, ch, ct, i;
" L0 h4 h4 `7 j, x unsigned char pass_in[7] = {0x00}; // 全部显示空格5 A7 {9 o- B5 e6 O& M0 q
unsigned char pass_show[7] = {0x20}; // 密码默认为空" S7 L2 Z* g' E3 V% i9 w b! k& `
bit result = 1;* U5 _# s% q G+ c+ e( [
: W9 J4 Z" l' ^% C: ? // 提示输入登录密码的界面5 \% ]* ~% a0 h! o
Lcd12864_wrLine(1, " Login Password");- `+ a5 I6 z" x& e0 K J8 F4 I
Lcd12864_wrLine(2, " ^^^^^^^^^^^^^^ ");* M3 {) p S' `
Lcd12864_wrLine(3, "> <");
) O8 ?" m: [. a& d( ~3 S Lcd12864_wrLine(4, " -------------- ");! }. j" m6 A. X. {* A
Lcd12864_setPos(3, 2);( l% T0 G, k7 V) s! {; a3 s
Lcd12864_showCursor(1);4 ]0 t$ }$ J5 {( L' V
delay(500);) m7 ~% L% Q/ H0 h: }3 @% V. L
) k+ {* E5 C9 Q; J. O# U% y // 监测按键输入(同时监测字符按键和控制按键)
# c% ^, `1 U9 V* d! u while (1) {0 y" {) m, v- {; m8 `
input = Keys_get9x6Num();
( a' W) L7 T" U. j/ Y delay(20);
5 \* f* @, o8 V! N9 F9 z4 b' j) x
if (input == 0)
8 W4 i% k0 D$ f9 K // 如果没有按下任何键& V; |7 d# f% _$ _7 ] G
continue;
0 @/ \1 F$ ^0 X: ] else {) F- n6 P' G. a) B% O
// 取出按下的控制键码4 l p( H# A4 J2 ?) \- w1 h
ct = Keys_get9x6Ctrl(input);4 A$ _! J4 r d; H! t
if (ct != NULL_CHAR) {: o& K8 d3 W$ b/ l2 k r J# X
switch (ct) {+ ]- z8 M9 `6 R! ?: l
case CTRL_SHIFT : { // 切换 Shift 输入状态" L/ ?" i6 T: O: M+ p8 a2 z4 ?
Keys_setShift(!Keys_getShift());
7 f, c+ P( n: P% W$ b0 D9 x5 F; } }; break;* F+ c$ W3 X S3 W: H
case CTRL_DEL : { // 栅格
/ o; c O, e/ F- V5 V if (length) {
6 F, m# {6 C( {- z% Z# G7 p length--;7 f& K* Y: |8 a, j
pass_show[length] = 0x20;
* r- @! r+ n: }8 t6 X; d+ v3 w pass_in[length] = 0x00;8 o0 D' j: f$ Z5 C5 Y
}9 h3 ]" \7 d) [# S" b
}; break;
$ B2 [/ p0 D$ ~) f' Y$ E case CTRL_CLS : { // 清屏+ G, a; X Y# O4 T! X; u! N
length = 0;( B9 k3 {5 X* O% }, i! H
for (i = 0; i < 7; i++) {
) v4 c5 X9 U+ x0 L( R- u: ?* U# n pass_show = 0x20;
8 @2 `" R' r( F) { pass_in = 0x00;1 \3 [6 O" T5 h" {; C+ w- y
}
T$ [' L+ ?. m4 {5 F* u+ l }; break;
4 n$ p' G5 B/ D$ G1 }, v6 G/ g case CTRL_ENT : { // 回车
5 b& N. I3 }* H5 f2 B0 _ for (i = 0; i < 7; i++) {) C9 g6 K9 b9 j: \+ b( {, y+ r
if (pass_in != PASSWORD_CONTENT) {' y& z, }$ a" `
result = 0;
9 t/ y# g: v4 L. l break;
- B# T- o. V/ r1 O1 C- U! a }
$ L9 [ M/ L: H }
. _, |+ @' [; u6 m return result;8 i# G9 |; u C0 C6 C
}; break;8 A% r, Y, Y" e- D. p+ }3 E
}! _8 t2 K% ~5 B3 K( v I% d. F8 r; y
}
6 g8 Z3 S5 v4 T H/ T* _) Y$ l c! S# U8 x/ z- a! s$ N1 y6 @
// 如果已经输满了,则不再监测字符输入! K& l: ` h7 b6 u1 ]
if (length != PASSWORD_LENGTH) {
* \* D( R6 H% M$ n; i // 取出按下的字符
7 N i' X8 O2 \8 `' e ch = Keys_get9x6Char(input);
" w* O& w' d- R) ]3 O if (ch != NULL_CHAR) {
- Y! j- L6 Z+ f4 |+ H8 @ pass_in[length] = ch;
+ e4 N: ^' W/ o9 {( \ pass_show[length] = '*';' y" R" F8 x5 \. o
length++;
, n6 k! V( f* ?0 o) a1 h h! x4 L }
$ c+ r- ^" g6 n4 \1 w5 Y* }+ ?, L7 A) ? }
$ q- { z: i0 R7 l& j8 X% C' ~ }; _) g9 m6 \% o
7 i1 k0 s' P, D2 v3 i% \" e1 Z // 显示输入情况
) H% n- _; c& ^6 K1 H3 H8 N Lcd12864_wrLine(3, "| |");
0 P% K# ?0 H1 |% j* h& O; K Lcd12864_setPos(3, 2);" |: ~+ B' x/ [2 l. c+ t+ o5 l
Lcd12864_wrStr(pass_show, 7);4 P- C' U* K) Q" [: j
Lcd12864_setPos(3, 2 + length/2);, f% A+ w! r$ N5 d( ?( z; _- S
}* U% P% v3 o) D, M* J ~
}! r; A& w. } Q, X
! i( G& L& q: m3 m/**
. b/ [" D; C& m$ Q* R% F% n* @# o * 记事本编辑器
, p6 x9 d, U5 U& S1 ^: Y */
! `# f& J2 V$ F" O# Nvoid Editor(void)
1 Q' t/ r, i% s9 y, X0 T{
6 Q4 V5 `+ r( B( A unsigned char input, ch, ct, i, j;' j' W$ V1 i$ {4 F8 Q7 K7 i
unsigned char length = 0; // 字符长度) b: o. u6 B( K& ^8 F3 K& a
unsigned char content[64] = {0x20}; // 字符串内容# m- {, z+ N* a; ^+ G1 T# _
unsigned char pos = 0; // 光标位置1 X3 C9 A' o7 a. ]
, F2 i5 x4 c% M1 @3 a& D" a
// 清屏,显示光标
4 y6 s6 [. [2 a% z l3 X6 H! M Lcd12864_cls();
6 Z" v8 g& _) s/ z, L" _( { Lcd12864_showCursor(1);
$ x6 D5 W/ z5 q2 J, F delay(500);$ j% ^! s0 \: C% `% T/ S
3 M7 O& k9 a+ i! [4 x1 _9 X4 J6 N while(1) {
) A3 Y1 k* B7 b! a7 ]+ V- q // 监测按键输入
) R" D5 K. J# y" i! O4 r input = Keys_get9x6Num();% O# k4 E, t1 s) }( V
delay(20);
7 `# E6 l* \; C# E& }* J9 e+ g, R# r/ y$ r5 i. a% Y
if (input == 0)
: A1 V# [3 ^+ C9 I$ ~5 s0 o // 如果没有按键输入则跳过
: g( |# M* k2 g" [, u: e. S continue;# n- Z1 J3 u1 y y) Y+ w
else {% v0 j* @- u0 s K
// 监测是否为控制键码1 c3 w6 h9 |0 d' X/ a- ?1 F9 c
ct = Keys_get9x6Ctrl(input);
9 P' \1 S$ P! v if (ct != NULL_CHAR) {9 |$ G3 L! C5 {" c
switch (ct) {
/ ]7 O2 l! s- Q6 g6 u case CTRL_CLS : { // 清屏
4 e* H, w! ~( u+ y( j, R' k Lcd12864_cls();2 A2 B! h l+ z; z( r" c
length = 0;7 p; q6 J/ N9 O$ s
pos = 0;
$ @. f! n6 b) r. _' R2 @+ N$ K" r for (i = 0; i < 64; i++)4 v- } E' n/ u
content = 0x20;8 v) z8 O' s. s5 ]0 w4 f& v
}; continue;, m1 o" K) }, Z# R' Y
case CTRL_DEL : { // 栅格! ^% D% ], [/ p" C( O& E
if (pos != 0) {
$ i$ Y$ W- o/ o. A- v s/ i( s pos--;
3 L7 ]8 h6 ~" T* S9 K8 |' L delCharFromStr(content, pos);
; N! }- D( c# h4 U$ K1 U length--;0 G j6 o5 s" \8 q2 s
}
6 w& k" \ A/ r8 |8 {6 ?; d }; break;
3 b! B+ `4 C! g" I& b1 l: c$ t+ d case CTRL_SHIFT : { // 切换 Shift 输入状态
7 j4 q+ |( R# }( ^$ ]+ P Keys_setShift(!Keys_getShift());( D* D6 z5 O3 E1 [. R4 Y! g
}; continue;' I( m2 l, b1 @& T8 `
case CTRL_UP : { // 向上移动光标6 a6 g$ d, i: P% x: q# a
if (pos >= 16) {, ]6 B0 w, A9 R* M' L& z
pos -= 16;0 q, M( R- ]/ P9 E6 k$ z4 G: v% p
setLcdPos(pos);
! q" ^! c" u8 p3 e7 K' V }* t( A0 ?$ u0 A; @9 P, L
- w+ l: Q- P- u6 e& {& \2 `4 m }; continue;2 S V1 P% y! B( [
case CTRL_DOWN : { // 向下移动光标; G' S. Y, l: C4 b- z; |% \
if (pos + 16 < length) {
+ I) m- N" R) y8 ^ q, m pos += 16;1 M2 G% w k" P( `' j
setLcdPos(pos);
U0 f3 ^5 U! U' T }
w! Y8 `+ a- ~! W4 D: x3 h2 i: B2 q% j
}; continue; v' j8 l B# D" {) c: }! I
case CTRL_LEFT : { // 向左移动光标
8 H k* {0 ?7 t4 B; k. l( D. u z z if (pos != 0) {
. T" n7 X" |& m4 K pos--;+ _9 e" p( ?- l( c; K
setLcdPos(pos);
) W4 @* v- c" _$ ?% v }
: A6 k3 y( v+ u/ N/ j
2 `+ s p4 s: G8 S- |. X6 v }; continue;
* V' N6 x5 X$ k3 \ case CTRL_RIGHT : { // 向右移动光标
6 [, L1 k# ~) s- S% p1 L8 | if (pos < length - 1) {* K& x5 Z0 W* Z
pos++;) ? K2 I: @2 P% X9 ?4 Q( J# l& A
setLcdPos(pos);
" S- B9 b. l% w3 T: C3 U }, P2 w0 ~1 ?6 H7 ?9 B3 S
, ]9 `3 R! B7 |& r }; continue;
) t( s9 k- _+ C( x* s$ a0 {9 X Q }( p: N h: G9 d! P6 v
}
" ^% R5 M6 A4 Y+ _3 i8 D
3 Y4 S8 a2 e. A& }7 s // 监测是否为字符按键" d5 j, F* H: x+ f' n9 P$ i
ch = Keys_get9x6Char(input);
* Y6 l: L1 v M; j if (ch != NULL_CHAR) {9 R, i; `/ D$ z8 N0 O
insCharToStr(content, ch, pos);9 F. X. {! K1 y; b8 B, q, C
pos++;: }& X! L; ]; e/ l- L- }* u
length++;
9 K4 s- o) ^: r6 F if (pos > 63)% `/ W( |0 r9 M& L; Y: s. T
pos = 63;
$ [2 @0 I/ A7 i% a( h' P if (length > 64)- Q1 E1 C# [3 F/ h3 N9 _
length = 64;. w6 T& e# {2 W- H7 e" \- p
}) N) @4 r7 i: P" b
) e! F1 B3 p- Q% f
// 显示记事本文本内容
. y, W) [8 r% q! W3 s& g WriteContent(content, length);
0 E0 P3 J# [5 u4 V8 [
2 Z2 x( i! u) h) i // 设置光标位置
; k1 J; J, T; W9 _. |& u setLcdPos(pos);) J2 p' o9 ]3 z$ I2 W# C
} M( ]. c( f, p6 {( `8 h
G. m4 e& v6 Q. b! _ }* s: a5 l9 b1 M5 ]( C- D
% }# W. `" u: N" {8 i/ ]}( D" y# }# w* `! J- K: \2 h
$ b7 m+ g3 J) r) S+ K" c1 s/**% K G$ ^% A8 W2 {
* 插入字符到字符串中
4 ~; x& S5 c$ b* y- B+ v * @param str 字符串
/ [( l7 H0 p+ _, H/ i7 w7 w+ Y * @param ch 欲插入的字符# y+ V3 [) l1 N3 Z! @
* @param index 插入位置
9 |8 @) @- Z# i' L( J */& y/ Z5 A2 n }2 R, _8 \+ D* o( |
void insCharToStr(unsigned char str[], unsigned char ch, unsigned int index)
* w3 H, J1 ~& s- b9 ?{& o2 _( I1 i9 O5 O, d
unsigned int i = 0;3 |+ n8 |) Y( T1 A# k" r, k+ n: I
unsigned char tmp1, tmp2;: `2 q: j% a6 I4 u8 n
4 T* p7 k! X& _5 F
while(i < 64) {
5 @, p2 v) }9 S' B; R5 b, Y if (i == index) {
, I. A2 F n, G tmp1 = str;
4 W! A, K. S$ [9 f' z/ J str = ch;
0 r+ S# |: ^% R- e! ] } else if (i > index) {
% [8 B& L5 _- N) t k tmp2 = str;+ P) w) Q, Z, n
str = tmp1;- p0 c" U5 D4 [' b# K8 v2 s
tmp1 = tmp2;7 {+ i- ^ O" m
}
* R6 u ?1 h& z" ?1 ?0 C
0 f" o+ h3 t9 V3 u; u. W" x+ C i++;
2 {9 U) h* \- s8 x0 u }
, E9 X* A/ a+ |# z/ G9 {2 n}- D; {6 k a: B3 U/ p" [5 _) H
3 ~) B( E f; j- D, ^/**( t% h8 S8 j8 a! w* P
* 从字符串中删除指定位置处的字符9 C& n: A e9 l
* @param str 字符串
6 O& n* R* _1 s) N. l * @param index 欲删除字符的位置9 ]# |& {- n0 P1 D- x4 I
*/
5 I/ `" _* I: x2 I' Q( I7 H; rvoid delCharFromStr(unsigned char str[], unsigned int index)
* v( y. S0 ^# ^+ H4 D) |5 x{" f1 M' a% D3 U" K# c
unsigned int i = 0;' I4 Y! g; E4 V/ W; i- y# j
8 n% m1 V Q) y$ S8 W. g
while(i < 64) {
" V3 `9 {8 H+ @, \# D' {' F if (i >= index) {/ b$ u S. i# B, ~* c
if (i == 63)) m# @ V$ L, g* V* ]. G" E1 C: w4 ^
str = 0x20;
5 I$ w5 l( F/ r' w8 e1 U else {
8 E, _ s! n; l$ i8 e8 r str = str[i+1];
# j5 _ b$ J8 N……………………5 g* C+ w9 p& j$ ^" ~
2 `2 w3 _1 |( [5 @
…………限于本文篇幅 余下代码请从论坛下载附件………… d6 X4 }. s4 B6 d; {* R8 U
( k$ m" O S d下载:" t3 U j6 e" ~# g) j3 K6 G
5 x7 j2 V4 m r6 t+ G z9 |% W# f# G2 l: r2 @ v! M# {( D# y
|
|