数学建模社区-数学中国

标题: 使用html画一个键盘 [打印本页]

作者: 2744557306    时间: 2024-4-27 10:42
标题: 使用html画一个键盘
  1. <!DOCTYPE html>1 }0 z# a& T% a  k# d5 M2 e$ k6 }, `
  2. <html lang="en">
    8 N! B* @$ n- b, C; F9 u) F4 C
  3. <head>, _3 b2 \* c+ Y7 A7 v3 V
  4.   <meta charset="UTF-8">
    " J) R  C6 F5 f, y" Q+ l  N  S
  5.   <meta http-equiv="X-UA-Compatible" content="IE=edge">
    $ y  Z6 D% z$ ]0 S0 k& J
  6.   <meta name="viewport" content="width=device-width, initial-scale=1.0">8 [5 [9 a, A0 Y+ ]
  7.   <link rel="stylesheet" >
    : c9 \6 n; ^4 b$ I: L: R
  8.   <title>vector examples Keyboard</title>/ y+ T' T* q/ Y) _+ R/ r4 q( E
  9. </head>
    4 F: N: \# C3 f; @' c. |1 B0 }
  10. <body>
    7 `3 i2 ^: O+ p! W) E
  11.   <div id="keyboard"></div>9 h1 B( I7 k% ]' b
  12.   <!-- <script type="module" src="./Keyboard.js"></script> -->: S; m. W, V! I1 u4 h" w2 a
  13.   <script type="module" src="./temp.js"></script>0 Q/ Q5 O: q; s$ ]
  14. </body>* U! C  w; v, I. L
  15. </html>; s/ L# h# ]" E2 h. C' F- U* x
复制代码
  1. import Interactive from "https://vectorjs.org/interactive.js";$ {* Q+ m& g; B) t
  2. console.log("Interactive", Interactive);/ J" k6 X* Q% F$ t6 A
复制代码
  1. /**
    ( ~! \. _- n: H( O5 K
  2. * [url=home.php?mod=space&uid=634908]@title[/url] Keyboard
    ' t' v; T# [" c! u; y
  3. * @description This interactive demonstrates how key board input can be used to add interactivity.
    / p! E, T. T1 @. |* H* ^* y# X
  4. * @tags [input]" p' F6 I  K9 o6 b9 P: B( i/ O2 t
  5. */
    6 O7 w6 c4 d+ [, h3 F" s
  6. // import { Interactive, getScriptName } from "../../index.js";
    & U; T, E5 j- X5 U+ P4 N+ M
  7. // let interactive = new Interactive(getScriptName());! H8 `! G* [, D4 b! S" ?
  8. import Interactive from "https://vectorjs.org/interactive.js";
    2 L7 J2 F: Y9 [' Z0 P
  9. let interactive = new Interactive("keyboard");
    1 Q, e* q$ ?" e" e/ H7 G$ J5 G
  10. interactive.width = 768;0 L" y' M7 P9 Z/ [( P, }8 i, N
  11. interactive.height = 300;
    - S# ]* A& h; J& v0 ~1 L: [' H% w* p
  12. interactive.border = true;
    : Q% f" ^+ x+ K
  13. let buffer = "";' x' K: J4 O% `
  14. let keys = [
    8 ?- |+ m& u$ }* H
  15.   [
    * _" B* G$ S" o2 ]9 M$ a5 a
  16.     "`",
    $ n/ Q; t7 s' W' m
  17.     "1",
    ' m) m1 P2 Y3 P3 t( }1 q: \* G
  18.     "2",5 l: b/ O! b3 A4 g; ?% g
  19.     "3",
    , r1 B5 T# t! |1 C- g: c$ v( b; \
  20.     "4",- s5 m" r1 Q' p* |2 g. f
  21.     "5",6 D+ C* W, O# E: ^0 Y/ O
  22.     "6",
    4 N# `% V; _4 }2 E6 C) H
  23.     "7",* C$ j; P5 |+ o2 p
  24.     "8",; J4 d+ H! Q6 C; c6 t' Y9 A0 x+ G& T
  25.     "9",
    ) W6 E% P0 R, j( j& ?( w3 W. V
  26.     "0",
    $ S2 i5 Q' S! g0 k" d
  27.     "-",4 r$ i6 n0 `. L" y3 V
  28.     "=",3 \0 ]. ^! V9 U2 Y! A( N7 c+ ^) X
  29.     "Backspace",3 w) e% |& }- I3 `
  30.   ],
    / j0 `5 M) t7 W) q5 _
  31.   ["tab", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"],
    * G6 _, B3 y+ v& g6 |( i% v! J4 p
  32.   ["CapsLock", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Enter"],8 ]" |5 V: ?+ _  ?% N1 s$ J( K
  33.   ["Shift", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "Shift"],
    9 a" H) f$ T9 y/ V2 O/ c) W
  34.   [
    , R$ t3 O6 y8 \/ J
  35.     "fn",
    ; a: f$ w5 ]$ q. }
  36.     "Control",  C: g3 Y4 I% T5 ^; b, w4 m
  37.     "Alt",
    & J. [$ q5 S+ N$ h2 J
  38.     "Meta",
    $ {2 |6 `: P# Y
  39.     " ",1 N* f5 U4 E( e  I; R
  40.     "Meta",/ E/ E" |1 n! A
  41.     "Alt",% @( c/ P* H$ ^2 L- n; k
  42.     "ArrowLeft",9 S6 l0 w& Y( {  {) G/ R
  43.     "ArrowUp",1 n& z7 p0 b$ q6 f: x$ U
  44.     "ArrowDown",
    $ W, j0 J* Y( W5 k. d; i4 O. t  c
  45.     "ArrowRight",& T) e  K' z7 G6 z* K; H; t5 r
  46.   ],( W- m( E. G, V5 o3 }
  47. ];5 E4 r1 G. ?; C$ V$ S- o+ M0 {
  48. let buttons = [];* g* q) l7 V1 _: u0 d' K
  49. let keycodes = {6 e9 Q* _! l$ K' ~8 h
  50.   0: { Symbol: 0, Shift: ")" },
    : ]7 Y) n$ J: @
  51.   1: { Symbol: 1, Shift: "!" },
    . V) [3 F: r& x+ S- t% T+ ^& b
  52.   2: { Symbol: 2, Shift: "@" },
    ( Z5 \. W# |: v( z6 F% i* {
  53.   3: { Symbol: 3, Shift: "#" },
    & \; X) v( Y! e. t$ z$ Q
  54.   4: { Symbol: 4, Shift: "$" },9 s1 M! Y  i8 ~& f& B" p8 d
  55.   5: { Symbol: 5, Shift: "%" },% ~0 n: _3 Y! W/ k% c2 r3 R$ E8 I
  56.   6: { Symbol: 6, Shift: "^" },0 o" m  a$ R5 I6 I  I" ~% v
  57.   7: { Symbol: 7, Shift: "&" },' f7 o0 K1 ]4 W7 K0 k
  58.   8: { Symbol: 8, Shift: "*" },* q4 c/ c$ ^5 b) {: |# J
  59.   9: { Symbol: 9, Shift: "(" },6 q5 Y/ Q$ Q: c; L. @' k0 N
  60.   a: { Symbol: "a", Shift: "A" },
    + q3 J1 L8 J1 m# J' r3 x
  61.   b: { Symbol: "b", Shift: "B" },: d! y2 t/ N4 W+ [
  62.   c: { Symbol: "c", Shift: "C" },! _/ Y7 v  \7 w1 `( ~* c
  63.   d: { Symbol: "d", Shift: "D" },0 C$ }" p! p# Z! H4 A
  64.   e: { Symbol: "e", Shift: "E" },
    : l6 z3 `# V1 [" b6 q
  65.   f: { Symbol: "f", Shift: "F" },+ e5 I( u: f/ U( Q
  66.   g: { Symbol: "g", Shift: "G" },
    ) Z4 h& S# r% x7 L  i$ N. q
  67.   h: { Symbol: "h", Shift: "H" },; [$ y3 ]1 H& Y2 j
  68.   i: { Symbol: "i", Shift: "I" },
    8 q3 s2 l" @  f+ a
  69.   j: { Symbol: "j", Shift: "J" },
    ) g5 p# V; Q, ^7 `2 W, t5 q
  70.   k: { Symbol: "k", Shift: "K" },; D: o; }- f5 u/ Z+ s0 E- T! z
  71.   l: { Symbol: "l", Shift: "L" },4 d9 Y0 c1 h9 i, v& A9 V
  72.   m: { Symbol: "m", Shift: "M" },
    3 E. z5 ]4 N. P
  73.   n: { Symbol: "n", Shift: "N" },
    # D( _+ F0 F: `8 O0 _5 z
  74.   o: { Symbol: "o", Shift: "O" },
    6 B- j5 S+ z% u$ Y5 Q. \6 {
  75.   p: { Symbol: "p", Shift: "P" },. W4 F5 p, ^2 y* ~* w
  76.   q: { Symbol: "q", Shift: "Q" },: D( o) N7 @3 u: C! \4 s4 u* [
  77.   r: { Symbol: "r", Shift: "R" },$ N6 }$ h9 `2 Y4 ]& n
  78.   s: { Symbol: "s", Shift: "S" },, E8 j6 d& ^/ {9 N) q! q
  79.   t: { Symbol: "t", Shift: "T" },
    5 q& }% j* m- `( ~; a7 t. u+ H) y" E
  80.   u: { Symbol: "u", Shift: "U" },0 p* v8 y( X1 s- N$ m4 |, |* |
  81.   v: { Symbol: "v", Shift: "V" },
    ( T4 j" R- q( ?- Y& V( `) h! Y
  82.   w: { Symbol: "w", Shift: "W" },
      o* o+ D; \3 ]& d. F+ d
  83.   x: { Symbol: "x", Shift: "X" },0 H. Y' l" o. u5 b9 L% a
  84.   y: { Symbol: "y", Shift: "Y" },
    & ^) s% O' u6 C! k. O
  85.   z: { Symbol: "z", Shift: "Z" },# E# [6 B) ^' c. J/ y' D( l! @0 k" y
  86.   "`": { Symbol: "`", Shift: "~" },( f, x9 z0 X6 s% [
  87.   "-": { Symbol: "-", Shift: "_" },
    # @0 a( r1 R' g* {
  88.   "=": { Symbol: "=", Shift: "+" },
    ) G) O2 V$ |7 R  j2 M2 A, ]$ m2 k
  89.   ";": { Symbol: ";", Shift: ":" },. ~  r( E9 _( W& t+ S/ u( d, C
  90.   "'": { Symbol: "'", Shift: '"' },/ S5 `- }* e# |- u# K" l
  91.   "[": { Symbol: "[", Shift: "{" },9 Q* ^: U+ l& H6 I* M
  92.   "]": { Symbol: "]", Shift: "}" },
    - t, t  p1 T3 g: P# t. T
  93.   "\\": { Symbol: "\\", Shift: "|" },
    3 ^$ U) C+ m% i) Q
  94.   ",": { Symbol: ",", Shift: "<" },+ b' |% A: E  k' a
  95.   ".": { Symbol: ".", Shift: ">" },
    5 a: T9 p7 B! C
  96.   "/": { Symbol: "/", Shift: "?" }," @; k6 S( g, q" r
  97.   Backspace: { Symbol: "⌫", Shift: "" },
    2 T. A4 P& T& k5 `- p, N
  98.   tab: { Symbol: "  ", Shift: "" },
    - P9 J" p8 {# D4 g
  99.   CapsLock: { Symbol: "⇪", Shift: "" },, B0 f+ G$ D9 [! v
  100.   Shift: { Symbol: "⇧", Shift: "" },
    8 d' U% G% u8 R8 @5 A6 G- H9 Q1 H7 Z
  101.   Enter: { Symbol: "⏎", Shift: "" },- r0 j5 l2 ?: I5 @
  102.   Control: { Symbol: "⌃", Shift: "" },2 ^5 w  o, H( h- ]/ A6 t( b) G5 L
  103.   Alt: { Symbol: "Alt", Shift: "" },# Y7 ^- J6 b/ M' r+ b" z) p
  104.   Meta: { Symbol: "⌘", Shift: "" },
    1 h+ x% }. A1 V2 q3 F2 R; {/ F
  105.   ArrowLeft: { Symbol: "←", Shift: "" },
    7 p/ j0 B9 D5 Q( F
  106.   ArrowUp: { Symbol: "↑", Shift: "" },( K3 ], L6 ^' J* x9 z+ I  C. F  w
  107.   ArrowDown: { Symbol: "↓", Shift: "" }," W  o. q+ G0 i$ r
  108.   ArrowRight: { Symbol: "→", Shift: "" },2 }& P; E7 [. a+ y1 ]
  109.   " ": { Symbol: " ", Shift: "" },' K1 S) I8 G8 T: A; K
  110. };
    5 g/ `8 a& V6 B) s
  111. let buttonMap = new Map();- ~- [6 C# V7 w6 m" e5 Z
  112. let height = 32;/ P2 S% M1 C  t* o" h6 A
  113. let margin = 8;) f+ ^+ m7 `* _- k- S+ ^
  114. let capslock = interactive.button(0, 0, keycodes["CapsLock"].Symbol);1 f& L8 ?! K- F( L
  115. let shift = interactive.button(0, 0, keycodes["Shift"].Symbol);
    ) o: I; z( U2 S
  116. for (let row = 0; row < keys.length; row++) {. p$ E: s) K% \9 b6 z/ H
  117.   let x = 32;$ F6 }( }/ x- K2 @2 A
  118.   let prev;; Q% W" Y& E9 ^' `; a* t
  119.   for (let i = 0; i < keys[row].length; i++) {
    0 I0 U# t) w; F% {/ v2 y
  120.     let key = keys[row][i];
    / _& n% Q- Q& A! A
  121.     let width = 32;( ^1 e3 T# }9 [: `2 @
  122.     let button;0 |7 N/ Q8 `! b2 u
  123.     switch (key) {1 n, P6 j% y; O; {  m# d
  124.       case "CapsLock":
    6 y8 B+ z: ~7 M) o% t
  125.         button = capslock;
    6 }; U& a# g2 k
  126.         width = 64;
    - B% c6 O4 S4 p0 c) L3 o0 F& X" n1 U
  127.         break;/ X& U5 K- x/ V# C9 d3 g
  128.       case "Shift":
    ( V/ A0 Z) w: w8 C5 k
  129.         if (shift.x === 0) {! n' d! A5 @4 y9 y: P( N1 @+ L
  130.           button = shift;- l7 O6 q: G9 a  e  W
  131.         } else {/ K, d4 U2 m9 l8 N" M! s! o
  132.           button = interactive.button(+ U6 n9 V0 V% T7 u5 W+ e
  133.             0,8 o: D; e* [3 J0 w; V$ J
  134.             0,* Y: s$ g1 x7 o6 ?1 k: @* Q! K
  135.             keycodes[key] != undefined ? keycodes[key].Symbol : key
    : f" e$ s2 `/ a6 a) U8 |
  136.           );% _5 K, f6 m# \9 n
  137.         }( }- P; w' D% u# {( b
  138.         width = 90;
    ( P# g; R$ X' j$ d6 j
  139.         break;
    " E' S& M4 ?" c) v/ U& d- n  Y* q* d
  140.       case "tab":
    1 }# ]0 z. j; i
  141.         width = 50;% ~3 U3 Y, H: b4 W3 O% U/ E
  142.         button = interactive.button(
    ' q- M* p3 p) V
  143.           0,
    + K9 F/ D; a* u8 s/ e
  144.           0,
    + e6 K- V7 M" R* J
  145.           keycodes[key] != undefined ? keycodes[key].Symbol : key. q" c7 b! l) Z4 a0 n
  146.         );6 N) V/ g  R: K$ G$ Y/ U
  147.         break;
    0 O; l) A; z3 @: x
  148.       case " ":
    6 ^. [6 K; b, h( X
  149.         width = 176;
    4 ^- v0 c. I9 g0 p! a# a+ e3 J
  150.         button = interactive.button(; w: V; X2 k7 {+ g4 a& j' P
  151.           0,% P2 n6 H5 k5 E& [* t, `$ I
  152.           0,
    & d, r4 L1 c! B1 t  ?5 n: B
  153.           keycodes[key] != undefined ? keycodes[key].Symbol : key* J8 \' R2 w2 M( j
  154.         );
    ) E5 `. `+ U; n$ V  |; u9 B
  155.         break;
    # ^; s: P5 t3 t; v+ e
  156.       case "Meta":
    & X7 U# ]4 H$ B" a
  157.         width = 50;
      j7 [: m. V. d9 j0 h1 K1 s
  158.         button = interactive.button(
    ' V4 [. ]5 \5 @$ q0 z
  159.           0,3 W+ \+ W' c, T0 [5 i/ q
  160.           0,
    / s& u. G, t7 f0 q) `" K' t! d
  161.           keycodes[key] != undefined ? keycodes[key].Symbol : key+ F0 v6 D3 G& P& e. R: W
  162.         );
    # s; O* H' F$ U* I! _/ j
  163.         break;. n$ S- U4 U) J( ]* }3 j
  164.       default:
    $ }. }4 K) u, ?# e
  165.         button = interactive.button(
    . x, }5 A2 m2 r% M' e( B: ^
  166.           0,, `: `% Q6 v0 C" ~5 }. G
  167.           0,
    ' I3 g& U  c6 K" I$ a+ e1 m! x7 t
  168.           keycodes[key] != undefined ? keycodes[key].Symbol : key
    1 h- P) }8 m% c/ h2 C
  169.         );
    & L' l/ i: n# O5 Z# h. _: o# C
  170.         if (keycodes[key] != undefined) {5 C  y2 u: _8 t# T( G
  171.           if (keycodes[key].Shift != "") {
    . a" a/ U' M2 B2 @- E0 e5 F
  172.             button.addDependency(shift, capslock);
    1 f) `' n2 q, |2 K8 V6 w
  173.             button.update = () => {" b* O$ G, Z* F7 Z* ?( @) ?
  174.               if (shift.active || capslock.active) {3 b1 X+ v4 P2 H5 I- j2 e  ?% D
  175.                 button.label.contents = keycodes[key].Shift;; D- f1 E$ ^" F" {- Q- E
  176.               } else {5 q2 F5 v* g2 t' x: e5 w, E% {4 r
  177.                 button.label.contents = keycodes[key].Symbol;1 b9 i- N- p- t
  178.               }, D( u9 g- R- S2 x& o: K
  179.             };
    , t; Q3 D& W" B/ \
  180.           }& V; o7 a; R7 _/ V- h) ~# y( o
  181.         }
    ; y' a' f! x/ j' \$ h
  182.     }" J, ]; }7 X8 U+ v( E0 ]
  183.     button.x = x;
    / `1 X- B! G3 |9 C: ^, V9 _
  184.     button.y = 64 + row * (height + margin);
    & K8 _9 W$ v7 b0 P. A
  185.     if (button.box.width < width) {& s3 J. I* [) o2 r' C
  186.       button.box.width = width;
    " m) V8 V: g' P; h% w& G
  187.     }1 X% r  ?1 }8 f  Y
  188.     let bbox = button.root.getBBox();: V, ~1 t2 n8 R0 [, C' E
  189.     x += bbox.width + margin;9 z5 @) R1 v1 g% L0 h; @6 m1 j
  190.     buttons.push(button);
      I8 Q7 C" z/ W! C
  191.     prev = button;
    : i7 [+ h$ K! b! u( @% D+ Q
  192.     buttonMap.set(key, button);
    ; Q" T$ w  i0 U2 A1 T) ~
  193.     if (key === "ArrowUp") {& h% A! R! H+ j+ t9 a
  194.       button.box.height = 16;& c# c) T5 z( G& k% K
  195.       button.label.root.style.display = "none";( q( X4 a" O# ?6 _* y' I3 m
  196.     } else if (key === "ArrowDown") {6 F7 N5 ]! |  a) e5 o
  197.       button.box.height = 16;. k2 g- ^+ p6 J- |
  198.       button.x -= 32 + margin;
    ! \, [9 \3 q( w  R2 N& `# F
  199.       button.y += 16;
    / j+ G8 v0 a9 t
  200.       button.label.root.style.display = "none";
    % p* b; i( u! D  H& D: ?8 w$ G
  201.       x -= bbox.width + margin;* R- p& v4 p# k4 ~5 l5 v& [. ]) w6 R
  202.     }
    8 n* w1 I6 J% l, w/ {
  203.   }9 A. l8 v' q0 {4 Q1 \
  204.   let right = prev.x;3 d1 w  I- ^( ]+ X* i6 r
  205.   if (right < 630) {
    ; i' I' E: x6 H1 u1 [7 I2 K. x2 t+ p
  206.     prev.box.width = 630 - right;
    # l9 r$ T" H, o/ i8 R
  207.   }
    * M# E: a: }! K! d4 |* g( _
  208. }
    4 w* A0 t5 e( j  l. G# B. R5 a% U& u
  209. // console.log(keycodes["0"], shift, capslock);
    : ]) i( [6 v$ z7 G7 Q/ p0 A6 b
  210. let active = [];, L3 ?: y/ g0 w
  211. window.onkeydown = function (event) {
      a" |: ^  b1 L7 a5 D
  212.   for (let i = 0; i < buttons.length; i++) {
    % _5 z4 Q$ N. n+ f
  213.     let button = buttons[i];
    ; m, O' y, y* N. P2 W3 d; ^, b
  214.     if (
    / a- j9 |2 e( s5 N( t
  215.       button.label.contents === event.key ||
    $ M9 N( P+ O# V4 v& I9 r
  216.       (keycodes[event.key] != undefined &&0 d1 U4 E7 A4 z( W' D: \
  217.         button.label.contents === keycodes[event.key].Symbol)( g9 j; c% q1 j% R+ L6 u) a
  218.     ) {
    3 c) ~* i4 Z3 a( O& q, S
  219.       button.box.style.fill = "#f8f8f8";
    7 u4 h" y' R. b, ]- `; S
  220.       button.label.style.fill = "#404040";
    : m( ]+ }& s; i7 l
  221.       button.active = true;
    : ]7 k8 k" g5 t# E" H9 V
  222.       active.push(button);* p/ u/ B9 c0 [7 q; {
  223.     }
    9 D: Z$ H0 X0 d  d
  224.   }- O6 F; G' w# S  t- b
  225.   buffer += `'${event.key}',`;
    & V) m5 a% v& h  [; x/ I
  226. };. c4 y. S1 M9 {. f. x
  227. window.onkeyup = function (event) {2 [% {  i/ A2 o8 d
  228.   let newActive = [];
    + Q7 e8 |5 N7 {* ]* Z% [; {
  229.   for (let button of active) {* B4 C  _6 ^) t5 O# `5 D6 D
  230.     if (
    4 K7 _5 J' I8 u- s8 V5 _2 F
  231.       button.label.contents === event.key ||
    # @: L' l, B2 U5 J
  232.       (keycodes[event.key] != undefined &&
    0 N* O$ Y1 P) w0 C3 c
  233.         button.label.contents === keycodes[event.key].Symbol)0 h5 `- c3 @& v; w: H5 }
  234.     ) {
    / y+ g, N# \7 b" @$ X3 s
  235.       button.box.style.fill = "";
    / I) r/ @% e. v" V
  236.       button.label.style.fill = "";- J9 @- Y5 @: d
  237.       button.active = false;0 e2 K+ g2 ^6 ?' l& j; L; X) N2 @4 U
  238.     } else {$ k( l& i; A8 b8 G
  239.       newActive.push(button);
    ! J2 X! d5 R# {. w
  240.     }" j/ Q0 `4 ?8 c8 t
  241.   }
    ' f9 b+ A9 O# B7 ^# ?2 e
  242.   active = newActive;
    # a1 T4 B: U5 E; F- z9 H- W
  243. };) q9 M+ g/ \2 U
  244. let bbox = interactive.input.root.getBBox();
    ( L7 O& i. Z$ o6 @
  245. interactive.setViewBox(
    9 L' N9 @" R) I1 l/ Y% W8 l9 {
  246.   bbox.x - margin,6 @0 _! F! R( |6 ~. O
  247.   bbox.y,
    / M' x6 @- a& X$ K6 o5 X
  248.   bbox.width + 2 * margin,
    0 Z0 E' g/ ?5 ?/ }2 Q
  249.   bbox.height
    0 Q! ^# K, x# H/ W/ h7 W
  250. );
    ) ~  z  j( J9 J0 a
  251. //# sourceMappingURL=keyboard.js.map8 \! o0 b# [0 ]! N

  252. / S: k6 x% a( J7 y
复制代码

9 g8 X% }' @* N  E




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5