]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - keyboard/ergodox/keymap_micro.c
Merge remote-tracking branch 'tmk/master'
[max/tmk_keyboard.git] / keyboard / ergodox / keymap_micro.c
1 //
2 // Inspired by MicroDox:
3 // http://geekhack.org/index.php?topic=42231.msg1062851#msg1062851
4 // https://www.massdrop.com/ext/ergodox/?referer=CTL63V&hash=9ff8ddbb75e03e517aaa39acabc81669
5 //
6 #include <util/delay.h>
7 #include "bootloader.h"
8 #include "keymap_common.h"
9
10
11 const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
12     /*
13      * Keymap: Default Layer in QWERTY
14      *
15      * ,--------------------------------------------------.           ,--------------------------------------------------.
16      * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
17      * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
18      * | Tab    |   Q  |   W  |   E  |   R  |   T  |      |           |      |   Y  |   U  |   I  |   O  |   P  |   [    |
19      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
20      * | Tab/Shf|   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |   ;  |   '    |
21      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
22      * | LCtrl/~|   Z  |   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ,  |   .  |   /  |   ]    |
23      * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
24      *   |      |      | Caps | LAlt | LGui |                                       | RGui |      |      |      |      |
25      *   |      |      |      | Spc  | Esc  |                                       |      |      |      |      |      |
26      *   `----------------------------------'                                       `----------------------------------'
27      *                                        ,-------------.       ,-------------.
28      *                                        |      |      |       |      |      |
29      *                                 ,------|------|------|       |------+------+------.
30      *                                 |      |      |      |       |      |      |      |
31      *                                 | BkSp |  Del |------|       |------| Enter| Space|
32      *                                 |      |      |  Esc |       | Ins  |      |      |
33      *                                 | LCtl | LSft | LAlt |       | RAlt | RSft | RCtl |
34      *                                 `--------------------'       `--------------------'
35      *
36      *
37      *
38      ****************************************************************************************************
39      *
40      * Under XOrg, I use my own mapping from QWERTY to "Workman for Programmers"
41      * See XOrg files in ./addons/ subdirectory.
42      *
43      * I have to do so, because of two things:
44      * 1) my native language is Russian, and XOrg keymap for it is based on QWERTY layout
45      * 2) I want to have non-standart shifted keys, like $ (as normal) and @ (as shifted), or _ and -
46      *
47      * And even if (2) could be solved using FN* keys (but there is limit in firmware for only 32 such
48      * keys), then (1) can't be solved at firmware level at all.
49      *
50      * So, I have to stick with QWERTY as my main layout + my own XOrg keyboard layout for English.
51      * But sometimes I have to input something when XOrg is not active - for example, in Linux console,
52      * or in firmware console (while debugging firmware), or when keyboard is connected to not my computer.
53      *
54      * For such cases I have Layer1 :)
55      * // hint: switch to Layer1 is only at Layer6
56      *
57      ****************************************************************************************************
58      *
59      *
60      *
61      * Keymap: Default Layer in Workman
62      *
63      * ,--------------------------------------------------.           ,--------------------------------------------------.
64      * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
65      * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
66      * | Tab    |   Q  |   D  |   R  |   W  |   B  |      |           |      |   J  |   F  |   U  |   P  |   $  |   :    |
67      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
68      * | Tab/Shf|   A  |   S  |   H  |   T  |   G  |------|           |------|   Y  |   N  |   E  |   O  |   I  |   -    |
69      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
70      * | LCtrl  |   Z  |   X  |   M  |   C  |   V  |      |           |      |   K  |   L  |   ,  |   .  |   /  |   |    |
71      * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
72      *   |      |      | Caps | LAlt | LGui |                                       | RGui |      |      |      |      |
73      *   |      |      |      | Spc  | Esc  |                                       |      |      |      |      |      |
74      *   `----------------------------------'                                       `----------------------------------'
75      *                                        ,-------------.       ,-------------.
76      *                                        |      |      |       |      |      |
77      *                                 ,------|------|------|       |------+------+------.
78      *                                 |      |      |      |       |      |      |      |
79      *                                 | BkSp |  Del |------|       |------| Enter| Space|
80      *                                 |      |      |  Esc |       | Ins  |      |      |
81      *                                 | LCtl | LSft | LAlt |       | RAlt | RSft | RCtl |
82      *                                 `--------------------'       `--------------------'
83      *
84      * Keymap: Default Layer in Workman / with Shift
85      *
86      * ,--------------------------------------------------.           ,--------------------------------------------------.
87      * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
88      * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
89      * | Tab    |   Q  |   D  |   R  |   W  |   B  |      |           |      |   J  |   F  |   U  |   P  |   @  |   %    |
90      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
91      * | Tab/Shf|   A  |   S  |   H  |   T  |   G  |------|           |------|   Y  |   N  |   E  |   O  |   I  |   _    |
92      * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
93      * | LCtrl  |   Z  |   X  |   M  |   C  |   V  |      |           |      |   K  |   L  |   ,  |   .  |   /  |   &    |
94      * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
95      *   |      |      | Caps | LAlt | LGui |                                       | RGui |      |      |      |      |
96      *   |      |      |      | Spc  | Esc  |                                       |      |      |      |      |      |
97      *   `----------------------------------'                                       `----------------------------------'
98      *                                        ,-------------.       ,-------------.
99      *                                        |      |      |       |      |      |
100      *                                 ,------|------|------|       |------+------+------.
101      *                                 |      |      |      |       |      |      |      |
102      *                                 | BkSp |  Del |------|       |------| Enter| Space|
103      *                                 |      |      |  Esc |       | Ins  |      |      |
104      *                                 | LCtl | LSft | LAlt |       | RAlt | RSft | RCtl |
105      *                                 `--------------------'       `--------------------'
106      *
107      * |  ~     |   ;  |   !  |   #  |   {  |   }  |   '  |           |   ^  |   [  |   ]  |   *  |   (  |   )  |   =    |
108      * |  `     |   1  |   2  |   3  |   4  |   5  |   "  |           |   \  |   6  |   7  |   8  |   9  |   0  |   +    |
109      */
110
111     KEYMAP(  // Layer0: default, leftled:none
112         // left hand
113         NO,  NO,  NO,  NO,  NO,  NO,  NO,
114         TAB, Q,   W,   E,   R,   T,   NO,
115         FN11,FN28,FN29,FN30,FN21,G,
116         FN12,FN24,FN25,FN26,FN27,B,   NO,
117         NO,  NO,  CAPS,FN13,FN14,
118                                       NO,  NO,
119                                            NO,
120                                  FN5, FN6, FN7,
121         // right hand
122              NO,  NO,  NO,  NO,  NO,  NO,  NO,
123              NO,  Y,   U,   I,   O,   P,   LBRC,
124                   H,   J,   K,   L,   FN22,FN15,
125              NO,  N,   M,   COMM,DOT, SLSH,FN16,
126                        RGUI,FN17,NO,  NO,  NO,
127         NO,  NO,
128         NO,
129         FN8, FN9, FN10
130     ),
131
132     KEYMAP(  // Layer1: Workman layout, leftled:all
133         // left hand
134         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
135         TRNS,Q,   D,   R,   W,   B,   TRNS,
136         TRNS,A,   S,   H,   T,   G,
137         TRNS,Z,   X,   M,   C,   V,   TRNS,
138         TRNS,TRNS,TRNS,TRNS,TRNS,
139                                       TRNS,TRNS,
140                                            TRNS,
141                                  TRNS,TRNS,TRNS,
142         // right hand
143              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
144              TRNS,J,   F,   U,   P,   4,   TRNS,
145                   Y,   N,   E,   O,   I,   TRNS,
146              TRNS,K,   L,   TRNS,TRNS,TRNS,TRNS,
147                        TRNS,TRNS,TRNS,TRNS,TRNS,
148         TRNS,TRNS,
149         TRNS,
150         TRNS,TRNS,TRNS
151     ),
152
153     KEYMAP(  // Layer2: numpad, leftled:blue
154         // left hand
155         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
156         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
157         TRNS,NO,  NO,  NO,  TRNS,NO,
158         TRNS,NO,  NO,  NO,  TRNS,NO,  TRNS,
159         TRNS,TRNS,TRNS,TRNS,TRNS,
160                                       TRNS,TRNS,
161                                            TRNS,
162                                  TRNS,TRNS,TRNS,
163         // right hand
164              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
165              TRNS,NLCK,P7,  P8,  P9,  PMNS,PGUP,
166                   PAST,P4,  P5,  P6,  PPLS,PGDN,
167              TRNS,FN17,P1,  P2,  P3,  PSLS,PENT,
168                        P0,  PDOT,SLSH,NO,  NO,
169         TRNS,TRNS,
170         TRNS,
171         TRNS,TRNS,TRNS
172     ),
173
174     KEYMAP(  // Layer3: F-keys + PgUp/PgDn on right hand, leftled:green
175         // left hand
176         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
177         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
178         TRNS,NO,  TRNS,NO,  NO,  NO,
179         TRNS,NO,  TRNS,NO,  NO,  NO,  TRNS,
180         TRNS,TRNS,TRNS,LALT,LGUI,
181                                       TRNS,TRNS,
182                                            TRNS,
183                                  LCTL,LSFT,LALT,
184         // right hand
185              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
186              TRNS,PSCR,F1,  F2,  F3,  F4,  PGUP,
187                   SLCK,F5,  F6,  F7,  F8,  PGDN,
188              TRNS,PAUS,F9,  F10, F11, F12, APP,
189                        RGUI,RALT,TRNS,TRNS,TRNS,
190         TRNS,TRNS,
191         TRNS,
192         RALT,RSFT,RCTL
193     ),
194
195     KEYMAP(  // Layer4: unconvenient keys on right hand, leftled:red
196         // left hand
197         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
198         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
199         TRNS,TRNS,NO,  NO,  NO,  NO,
200         TRNS,TRNS,NO,  NO,  NO,  NO,  TRNS,
201         TRNS,TRNS,TRNS,TRNS,TRNS,
202                                       TRNS,TRNS,
203                                            TRNS,
204                                  TRNS,TRNS,TRNS,
205
206         /* in Workman right hand will be:
207          *
208          *    ^ { } ( ) +
209          *    ' ! $ " ; =
210          *    # [ < > ] \
211          */
212
213         // right hand
214              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
215              TRNS,MINS,4,   5,   9,   0,   PPLS,
216                   BSLS,2,   P,   FN1, 1,   EQL,
217              TRNS,3,   6,   FN3, FN4, 7,   FN2,
218                        TRNS,TRNS,TRNS,TRNS,TRNS,
219         TRNS,TRNS,
220         TRNS,
221         TRNS,TRNS,TRNS
222     ),
223
224     KEYMAP(  // Layer5: cursor, leftled:red
225         // left hand
226         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
227         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
228         TRNS,NO,  NO,  NO,  TRNS,NO,
229         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
230         TRNS,TRNS,TRNS,TRNS,TRNS,
231                                       TRNS,TRNS,
232                                            TRNS,
233                                  TRNS,TRNS,TRNS,
234         // right hand
235              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
236              TRNS,PGUP,HOME,END, DEL, INS, PGUP,
237                   PGDN,LEFT,UP,  DOWN,RGHT,PGDN,
238              TRNS,NO,  HOME,END, DEL, INS, TRNS,
239                        TRNS,TRNS,TRNS,TRNS,TRNS,
240         TRNS,TRNS,
241         TRNS,
242         TRNS,TRNS,TRNS
243     ),
244
245     KEYMAP(  // Layer6: F1-F10, Workman-layer switch, Teensy, layer switches, leftled:red+onboard
246         // left hand
247         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
248         FN0, F1,  F2,  F3,  F4,  F5,  TRNS,
249         TRNS,FN18,NO,  NO,  FN19,NO,
250         TRNS,NO,  NO,  NO,  FN19,NO,  TRNS,
251         TRNS,TRNS,TRNS,TRNS,TRNS,
252                                       TRNS,TRNS,
253                                            TRNS,
254                                  TRNS,TRNS,TRNS,
255         // right hand
256              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
257              TRNS,F6,  F7,  F8,  F9,  F10, FN0,
258                   FN0, NO,  NO,  NO,  TRNS,TRNS,
259              TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
260                        TRNS,TRNS,TRNS,TRNS,TRNS,
261         TRNS,TRNS,
262         TRNS,
263         TRNS,TRNS,TRNS
264     ),
265
266     //
267     // rarely used
268     //
269
270     KEYMAP(  // Layer7: F-keys only, leftled:red
271         // left hand
272         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
273         TRNS,F13, F14, F15, F16, NO,  TRNS,
274         TRNS,F17, F18, F19, F20, NO,
275         TRNS,F21, F22, F23, F24, NO,  TRNS,
276         TRNS,TRNS,TRNS,TRNS,TRNS,
277                                       TRNS,TRNS,
278                                            TRNS,
279                                  TRNS,TRNS,TRNS,
280         // right hand
281              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
282              TRNS,NO,  F1,  F2,  F3,  F4,  TRNS,
283                   NO,  F5,  F6,  F7,  F8,  TRNS,
284              TRNS,NO,  F9,  F10, F11, F12, TRNS,
285                        TRNS,TRNS,TRNS,TRNS,TRNS,
286         TRNS,TRNS,
287         TRNS,
288         TRNS,TRNS,TRNS
289     ),
290
291     KEYMAP(  // Layer8: mouse and navigation, leftled:blue and green
292         // left hand
293         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
294         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
295         TRNS,NO,  NO,  TRNS,NO,  NO,
296         TRNS,NO,  NO,  TRNS,NO,  NO,  TRNS,
297         TRNS,TRNS,TRNS,TRNS,TRNS,
298                                       TRNS,TRNS,
299                                            TRNS,
300                                  TRNS,TRNS,TRNS,
301
302         // right hand
303              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
304              TRNS,BTN2,WH_L,WH_U,WH_D,WH_R,PGUP,
305                   BTN1,MS_L,MS_U,MS_D,MS_R,PGDN,
306              TRNS,BTN3,HOME,END, DEL, INS, NO,
307                        TRNS,TRNS,TRNS,TRNS,TRNS,
308         TRNS,TRNS,
309         TRNS,
310         TRNS,TRNS,TRNS
311     ),
312
313 /*
314     // templates to copy from
315
316     KEYMAP(  // LayerN: transparent on edges + hard-defined thumb keys, all others are empty
317         // left hand
318         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
319         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
320         TRNS,NO,  NO,  NO,  NO,  NO,
321         TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
322         TRNS,TRNS,TRNS,LALT,LGUI,
323                                       TRNS,TRNS,
324                                            TRNS,
325                                  LCTL,LSFT,TRNS,
326         // right hand
327              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
328              TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
329                   NO,  NO,  NO,  NO,  NO,  TRNS,
330              TRNS,NO,  NO,  NO,  NO,  NO,  TRNS,
331                        RGUI,RALT,TRNS,TRNS,TRNS,
332         TRNS,TRNS,
333         TRNS,
334         TRNS,RSFT,RCTL
335     ),
336     KEYMAP(  // LayerN: fully transparent
337         // left hand
338         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
339         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
340         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
341         TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
342         TRNS,TRNS,TRNS,TRNS,TRNS,
343                                       TRNS,TRNS,
344                                            TRNS,
345                                  TRNS,TRNS,TRNS,
346         // right hand
347              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
348              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
349                   TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
350              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
351                        TRNS,TRNS,TRNS,TRNS,TRNS,
352         TRNS,TRNS,
353         TRNS,
354         TRNS,TRNS,TRNS
355     ),
356 */
357
358 };
359
360 /* id for user defined functions */
361 enum function_id {
362     TEENSY_KEY,
363 };
364
365 /*
366  * Fn action definition
367  */
368 const uint16_t PROGMEM fn_actions[] = {
369     ACTION_FUNCTION(TEENSY_KEY),                    // FN0  - Teensy key
370
371     // Layer4: unconvenient keys on right hand
372     ACTION_MODS_KEY(MOD_LSFT, KC_BSLS),             // FN1  = Shifted BackSlash // " in Workman
373     ACTION_MODS_KEY(MOD_LSFT, KC_MINS),             // FN2  = Shifted Minus     // \ in Workman
374     ACTION_MODS_KEY(MOD_LSFT, KC_COMM),             // FN3  = Shifted comma     // < in Workman
375     ACTION_MODS_KEY(MOD_LSFT, KC_DOT),              // FN4  = Shifted dot       // > in Workman
376
377     // Dual-role keys on thumbs
378     ACTION_MODS_TAP_KEY(MOD_LCTL, KC_BSPC),         // FN5  = LShift with tap BackSpace
379     ACTION_MODS_TAP_KEY(MOD_LSFT, KC_DEL),          // FN6  = LCtrl  with tap Delete
380     ACTION_MODS_TAP_KEY(MOD_LALT, KC_ESC),          // FN7  = LAlt   with tap Escape
381     ACTION_MODS_TAP_KEY(MOD_RALT, KC_INS),          // FN8  = RAlt   with tap Ins
382     ACTION_MODS_TAP_KEY(MOD_RSFT, KC_ENT),          // FN9  = RShift with tap Enter
383     ACTION_MODS_TAP_KEY(MOD_RCTL, KC_SPC),          // FN10 = RCtrl  with tap Space
384
385     // Dual-role keys on pinkies
386     ACTION_MODS_TAP_KEY(MOD_LSFT, KC_TAB),          // FN11 = LShift with tap Tab
387     ACTION_MODS_TAP_KEY(MOD_LCTL, KC_GRV),          // FN12 = LCtrl  with tap Tilda
388     ACTION_MODS_TAP_KEY(MOD_LALT, KC_SPC),          // FN13 = LAlt   with tap Space
389     ACTION_MODS_TAP_KEY(MOD_LGUI, KC_ESC),          // FN14 = LGui   with tap Escape
390     ACTION_MODS_TAP_KEY(MOD_RSFT, KC_QUOT),         // FN15 = RShift with tap quotes
391     ACTION_MODS_TAP_KEY(MOD_RCTL, KC_RBRC),         // FN16 = RCtrl  with tap ]
392
393     // Layers switching
394     ACTION_LAYER_SET(0, ON_BOTH),                   // FN17 - set Layer0
395     ACTION_LAYER_SET(1, ON_BOTH),                   // FN18 - set Layer1, to use Workman layout at firmware level
396     ACTION_LAYER_SET(2, ON_BOTH),                   // FN19 - set Layer2, to use with Numpad keys
397
398     ACTION_LAYER_MOMENTARY(2),                      // UNUSED: FN20 - momentary Layer2, to use with Numpad keys
399     ACTION_LAYER_TAP_KEY(5, KC_F),                  // FN21 - momentary Layer5, to use with cursor
400     ACTION_LAYER_TAP_KEY(6, KC_SCLN),               // FN22 - tapping ; Layer6, to use with F1-F10, Workman-layer switch, Teensy, layer switches
401     ACTION_LAYER_MOMENTARY(7),                      // UNUSED: FN23 - momentary Layer7, to use with F* keys (F1-F24)
402
403     ACTION_LAYER_TAP_KEY(4, KC_Z),                  // FN24 = momentary Layer4 on Z key, to use with unconvenient keys
404     ACTION_LAYER_TAP_KEY(3, KC_X),                  // FN25 = momentary Layer3 on X key, to use with F* keys
405     ACTION_LAYER_TAP_KEY(8, KC_C),                  // FN26 = momentary Layer8 on C key, to use with mouse and navigation keys
406     ACTION_LAYER_TAP_KEY(2, KC_V),                  // FN27 = momentary Layer2 on V key, to use with Numpad keys
407
408     // i'd like to remove this - will try to get used to live without this and convert them to usual keys
409     ACTION_LAYER_TAP_KEY(4, KC_A),                  // FN28 = momentary Layer4 on A key, to use with unconvenient keys
410     ACTION_LAYER_TAP_KEY(3, KC_S),                  // FN29 = momentary Layer3 on S key, to use with F* keys
411     ACTION_LAYER_TAP_KEY(8, KC_D),                  // FN30 = momentary Layer8 on D key, to use with mouse and navigation keys
412     ACTION_LAYER_TAP_KEY(2, KC_F),                  // UNUSED: FN31 = momentary Layer2 on F key, to use with Numpad keys
413 };
414
415 void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
416 {
417     print("action_function called\n");
418     print("id  = "); phex(id); print("\n");
419     print("opt = "); phex(opt); print("\n");
420     if (id == TEENSY_KEY) {
421         clear_keyboard();
422         print("\n\nJump to bootloader... ");
423         _delay_ms(250);
424         bootloader_jump(); // should not return
425         print("not supported.\n");
426     }
427 }
428